【问题标题】:Is not accessible in current context在当前上下文中不可访问
【发布时间】:2014-10-05 06:44:47
【问题描述】:

我有以下代码

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 在当前上下文中不可访问

我真的不明白这个错误,也不知道我做错了什么。有人可以向我解释这个问题或可以澄清这种情况的链接吗?

【问题讨论】:

  • 你能发布完整的编译器信息吗?
  • 这是完整的编译器消息

标签: java android generics scope android-context


【解决方案1】:

创建死锁

你使用ModelAdapter.ModelViewHolder作为BaseAdapter的模板参数,让ModelAdapter扩展BaseAdapter,然后编译器尝试先创建ModelViewHolder,但是ModelAdapter.ModelViewHolder的类(类型为Class) 尚未创建。它必须等待ModelAdapter 被创建,因为ModelViewHolderModelAdapter 的范围内。

解决方法是将ModelViewHolder类放到一个新的*.java文件中。

【讨论】:

  • 好答案!我完全被这个弄糊涂了。
  • 我有同样的任务。可能,将 ViewHolder 类移动到单独的 *.java 文件中会更方便。
  • 我还是不明白……难道不应该让 ModelViewHolder 静态解决这个问题吗?静态修饰符应该使该类可以在不初始化父类的情况下进行初始化...
【解决方案2】:

这就是我的解决方法。通常不应该存在循环依赖问题,因为嵌套的视图类是静态的。例如。看看臭名昭著的LayoutParams层次结构,它的构建方式完全一样:一个类继承另一个类,然后它们的静态嵌套类有对应的继承关系。
看起来循环性来自可见性范围问题。 ModelViewHolder 只能在外部ModelAdapter 继承BaseAdapter 的可见性范围之后才知道ViewHolder。同时ModelAdapter 不能继承BaseAdapter,直到ModelViewHolder 类被初始化,因为它需要泛型参数。另一方面,ModelViewHolder 是一个静态嵌套类,在技术上不依赖于它的外部类。

因此,解决方案是在声明ModelViewHolder 时完全限定ViewHolder 的名称。请注意下面 sn-p 中的 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 的“复制类”功能(使用 AS 3.0)遇到了它。在复制时,它为我“简化”了代码,删除了完全限定的名称。所以,小心 AS 的聪明!

【讨论】:

    【解决方案3】:

    在扩展 Base 类时,我也遇到了同样的情况。但是这次我是这样的(按照问题中给出的示例)

    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 中的 import 中。

    我认为斐良的回答部分不正确,因为 ModelViewHolder 静态应该可以在不初始化其父类 ModelAdapter 的情况下初始化 ModelViewHolder

    【讨论】:

    • 我使用的是 Android Studio 1.5.2,这对我不起作用。 Android Studio 说导入未使用,但仍然报错。
    【解决方案4】:

    我之前遇到过这个问题,我不知道为什么会这样,但是我通过将 not-accessible inner 类设置为 独立类 解决了这个问题(不是内部手段在单独的文件中)。

    【讨论】:

      猜你喜欢
      • 2021-02-25
      • 2011-04-20
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多