在不同版本的Android中,跨包的受保护内部类可见性的差异

时间:2014-12-11 00:05:57

标签: java android

我今天在Android代码库中遇到了这个问题,令我感到困惑。我的同事们有一段时间了。我们以前有类似的类结构:

Foo.java

package test.a;

public abstract class Foo extends View {
    protected abstract class InnerFoo {
        public InnerFoo() {}
    }
    protected class Cog {
        public Cog() {}
    }
}

Bar.java

package test.a;

public class Bar extends Foo {
    private abstract class AbstractInnerBar extends InnerFoo {
        protected abstract void someMethod();
    }
    private class InnerBar extends AbstractInnerBar {
        Cog myCog;
        public InnerBar() {
            myCog = new Cog();
        }
        protected void someMethod() {}
    }        
}

我理解这个类结构不一定简单,但它没有问题。但是,我们最近做了一些包重组,并意识到Bar属于其他地方。因此,我们将它移动到一个不同的包,并具有几乎相同的结构,有两个不同的包。

Foo.java

package test.a;

public abstract class Foo extends View {
    protected abstract class InnerFoo {
        public InnerFoo() {}
    }
    protected class Cog {
        public Cog() {}
    }
}

Bar.java

package test.b; //This is the only change

public class Bar extends Foo {
    private abstract class AbstractInnerBar extends InnerFoo {
        protected abstract void someMethod();
    }
    private class InnerBar extends AbstractInnerBar {
        Cog myCog;
        public InnerBar() {
            myCog = new Cog();
        }
        protected void someMethod() {}
    }        
}

奇怪的是,在某些版本的Android上发生更改后,我们会收到如下错误:java.lang.IllegalAccessError: tried to access class test.a.Foo$Cog[] from class test.b.Bar$InnerBar。我不认为这会是一个问题,因为Cog被赋予protected可见性,Bar extends FooInnerBar扩展InnerFoo。奇怪的是,其他版本的Android工作得很好(没有错误,没有可见性问题)。我们可以通过将Cog声明为public来解决此问题,但这似乎是一种不必要的解决方法。

我们在运行Android 4.4.4的摩托罗拉Moto X(第一代开发人员版)上看到了这个问题。我们在运行Lollipop的Nexus 5或运行Android 4.1.2的Nexus S上没有问题

有人能说清楚这个吗?

1 个答案:

答案 0 :(得分:0)

包a中的抽象类Foo是默认的包私有,您应该将其访问说明符更改为public以避免任何错误。 否则你的Cog类应该没有问题,即使它受到保护。只要让Foo公开,你就可以去了。

 public abstract class Foo{}