考慮這些經典的人多態層次...靜態泛型方法,類型推斷導致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