Недоступен в текущем контексте
У меня есть следующий код
public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> {
public BaseAdapter(Context context, int resource, Collection<T> collection) {
// typical constructor logic
}
// some other custom defined methods
public static class ViewHolder {
// custom defined logic
}
}
public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
public ModelAdapter(Context context, int resource, Collection<Model> collection) {
super(context, resource, collection);
// typical constructor logic
}
public static class ModelViewHolder extends ViewHolder {
// custom defined logic
}
}
BaseAdapter и ModelAdapter находятся в разделенных файлах. Проблема в том, что у меня есть ошибка компиляции при попытке определить ModelAdapter:
ModelViewHolder недоступен в текущем контексте
Я действительно не понимаю эту ошибку и не могу понять, что я делаю неправильно. Может ли кто-нибудь объяснить мне эту проблему или ссылку, которая может прояснить эту ситуацию?
Ответы
Ответ 1
Создание мертвой блокировки
Вы используете ModelAdapter.ModelViewHolder
как параметр шаблона BaseAdapter
, и пусть ModelAdapter
extends BaseAdapter
, тогда компилятор попытался создать ModelViewHolder
сначала, но класс ModelAdapter.ModelViewHolder
(тип Класс) еще не создан. Он должен ждать создания ModelAdapter
, потому что ModelViewHolder
находится в области ModelAdapter
.
Способ его решения помещает класс ModelViewHolder
в новый *.java файл.
Ответ 2
Вот как это разрешилось для меня. Как правило, не должно быть проблемы с циклической зависимостью, поскольку классы вложенных зрителей являются статическими. Например. посмотрите на пресловутую иерархию LayoutParams
, которая построена точно так же: класс наследует другой класс, а затем их статические вложенные классы имеют соответствующие отношения наследования.
Похоже, округлость возникает скорее из области видимости. ModelViewHolder
может расширить ViewHolder
только после того, как внешний ModelAdapter
наследует область видимости BaseAdapter
. Между тем ModelAdapter
не может наследовать BaseAdapter
до тех пор, пока класс ModelViewHolder
не инициализируется, как это требуется для общего параметра. С другой стороны, ModelViewHolder
является статическим вложенным классом и технически не зависит от его внешнего класса.
Таким образом, решение должно полностью квалифицировать имя ViewHolder
при объявлении ModelViewHolder
. Обратите внимание на часть extends BaseAdapter.ViewHolder
в нижеприведенном фрагменте. Таким образом, ModelViewHolder
не нужно использовать область ModelAdapter
, чтобы знать о ViewHolder
.
ModelAdapter.java
public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
public ModelAdapter(Context context, int resource, Collection<Model> collection) {
super(context, resource, collection);
// typical constructor logic
}
public static class ModelViewHolder extends BaseAdapter.ViewHolder {
// custom defined logic
}
}
Заметка об Android Studio: несмотря на то, что сама проблема не связана с Android Studio, я столкнулся с ней с помощью функции AS "Copy class" (с использованием AS 3.0). При копировании он "упростил" код для меня, удалив полное имя. Итак, следите за умностью AS!
Ответ 3
Случилось то же самое при расширении базового класса. Но на этот раз я сделал это так (следуя приведенному примеру в вопросе)
BaseAdapter.java
public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> {
public BaseAdapter(Context context, int resource, Collection<T> collection) {
// typical constructor logic
}
// some other custom defined methods
public static class ViewHolder {
// custom defined logic
}
}
ModelAdapter.java
import com.mypackage.ModelAdapter.ModelViewHolder; ***//NOTE THIS IMPORT!!!***
public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
public ModelAdapter(Context context, int resource, Collection<Model> collection) {
super(context, resource, collection);
// typical constructor logic
}
public static class ModelViewHolder extends ViewHolder {
// custom defined logic
}
}
Таким образом, предупреждение не прошло и не нужно было отделять ModelViewHolder в другом файле .java. Обратите внимание, что они находятся в двух разных файлах и импортировать в ModelAdapter.java.
Я думаю, что ответ Фэй Ляна частично неверен, потому что, поскольку статический ModelViewHolder должен сделать возможным инициализацию ModelViewHolder без инициализации родительского класса ModelAdapter
Ответ 4
Я столкнулся с этой проблемой раньше, я не уверен, почему это произошло,
но я разрешил его
создание класса the not-accessible inner
class stand-alone
(не внутреннего, что означает в отдельном файле)