考虑这些经典的人多态层次...静态泛型方法,类型推断导致java.lang.VerifyError的:验证拒绝类
超接口
public interface Person {
String getName();
interface Builder<P, B extends Builder<P, B>> {
B name(String name);
P build();
}
}
Student.java
public class Student implements Person {
@Override
public String getName() {
...
}
public static class Builder implements Person.Builder<Student, Builder> {
@Override
public Builder name(String name) {
...
}
@Override
public Student build() {
...
}
}
}
Employee.java 我这里省略了员工类型,它只是同与学生
PersonBuilderFactory.java
public class PersonBuilderFactory {
public static <T extends Person.Builder> T getBuilder(T...args) {
if (args.getClass().getComponentType().isAssignableFrom(Student.Builder.class)) {
return (T) new Student.Builder();
} else if (args.getClass().getComponentType().isAssignableFrom(Employee.Builder.class)) {
return (T) new Employee.Builder();
}
throw new RuntimeException("No such builder for other person types");
}
TestInference.java
public class TestInference {
public static void testInference() {
Compile Test 1
// java wants me to infer the type argument
// which will build perfectly fine
Student.Builder studentBuilder1 = PersonBuilderFactory.<Student.Builder>getBuilder();
Employee.Builder employeeBuilder1 = PersonBuilderFactory.<Employee.Builder>getBuilder();
Compile Test 2
// so if i remove those explicit type arguments
// everything still works fine
Student.Builder studentBuilder2 = PersonBuilderFactory.getBuilder(); // this will implicitly get a student builder
Employee.Builder employeeBuilder2 = PersonBuilderFactory.getBuilder(); // this will have an employee builder
Compile Test 3
// Now...
// leaving the argument type NOT inferred and changing the data type
// gives me a compile error which is Im expecting and I want
String someString = PersonBuilderFactory.<Student.Builder>getBuilder();
Compile Test 4
// but when i remove the explicit type argument
// it compiles but this will cause me a specific Verify Error
String someAnotherString = PersonBuilderFactory.getBuilder();
}
}
Co mpile测试具有显式类型参数的Java要求我删除(告诉我,它是某种redudant)导致编译测试,工作正常
编译测试是林预计,如果
- 我宣布一个明确的类型参数是不声明类型变量
编译的范围内测试让我感到困惑,为什么没有编译器说什么它没有Person.Builder的界限返回东西(T扩展Person.Builder),当我运行代码时,它会抛出一个验证错误,告诉我我有一个不好的方法,我的问题是为什么编译器没有?但是当我明确指定了一个类型实参时,当Im声明一个正确的变量数据类型时,它返回一个正确的类型。
林完全有一个很难理解这里的类型推断,有问题,说有事情做与Java编译器版本,以及另一篇文章中说:“你只是有一个非常复杂的方法”
任何帮助不胜感激。
是的!非常感谢在基础知识上提醒我,我忘记了接口和类(absctract或具体)之间的关系,任何类都可以实现MANY接口,但一个类只能扩展一个父类! – Robert
我只是不明白交叉口类型:p – Robert
现在我即将获得所需的编译时错误! :),“类型参数T具有不兼容的上限” – Robert