Java代码可以编译,但是会产生IllegalAccessError

在下面的代码中,我给出了两个主要的类-TestWorks和TestCompilesButFails.我不确定我是否理解失败-看来Arrays.asList()表达式的类型为“ AbstractBaseClass的列表”,但为什么在此处提供引用本地包类的类型却是正确的在另一个包裹里?

// failing test class
import somepackage.*;
import java.util.Arrays;

public class TestCompilesButFails {
    public static void main(String [] args){
        // fails here with java.lang.IllegalAccessError: 
        // tried to access class somepackage.AbstractBaseClass 
        // from class TestCompilesButFails
        for (Object o : Arrays.asList(new ConcreteA(), new ConcreteB())) { 
            System.out.println(o);
        }
    }
}


// package-local abstract base class
package somepackage;

abstract class AbstractBaseClass {
    public abstract void doSomething();
}

// next two classes - public extenders of abstract base class
package somepackage;

public class ConcreteA extends AbstractBaseClass {
    public void doSomething(){
        System.out.print("Look, ma!\n");
    }
}

package somepackage;

public class ConcreteB extends AbstractBaseClass {
    public void doSomething(){
        System.out.print("No types!\n");
    }
}

// working test 
import somepackage.*;

public class TestWorks {
    public static void main(String [] args){
        new ConcreteA().doSomething();
        new ConcreteB().doSomething();
    }
}

解决方法:

因为Java语言规范中的类型推断算法specified没有考虑类型可见性:

A supertype constraint T :> X implies that the solution is one of supertypes of X. Given several such constraints on T, we can intersect the sets of supertypes implied by each of the constraints, since the type parameter must be a member of all of them. We can then choose the most specific type that is in the intersection.

至于他们为什么这样定义的原因,我怀疑这是为了避免使本来就很复杂的算法变得更复杂,其唯一目的只是为了处理罕见的极端情况.毕竟,他们还写道:

Note also that type inference does not affect soundness in any way. If the types inferred are nonsensical, the invocation will yield a type error. The type inference algorithm should be viewed as a heuristic, designed to perfdorm well in practice. If it fails to infer the desired result, explicit type paramneters may be used instead.

您的情况是:

    for (Object o : Arrays.<Object>asList(new ConcreteA(), new ConcreteB())) { 
        System.out.println(o);
    }
上一篇:c#-在方法返回上使用隐式类型语法


下一篇:C是否有一些类似于C#Type的东西来存储列表/数组中的类的Type?