简体   繁体   English

为什么编译器会这样表现?

[英]Why does compiler behave like this?

Look, we've got come code: 看,我们有代码:

public class Test2 {
    public static void main(String... args) {
        ArrayList<Exception> a = new ArrayListFactory().create(new RuntimeException());
        ArrayList<Exception> b = new ArrayListFactory().create("Z");
        }
}

class ArrayListFactory {
    public <T> ArrayList<T> create(T example) {
        return new ArrayList<T>(10);
    }
}

and an compilation error on second statement: 以及第二条语句的编译错误:

Error:(15, 63) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.lang.Exception
    lower bounds: java.lang.String
  1. In fact, the first statement assigns to ArrayList<Exception> another ArrayList<RuntimeException> , doesnt it clash with java rules? 实际上,第一条语句将另一个ArrayList<RuntimeException>分配给ArrayList<Exception> ArrayList<RuntimeException> ,它是否与Java规则冲突?
  2. The second statement infers Exception type argument for create . 第二条语句推断create Exception类型参数。 Does it check that method's return type matches it's argument type as it's defined in ArrayListFactory class? 它是否检查方法的返回类型是否与ArrayListFactory类中定义的参数类型相匹配? It seems that this method call shall be resolved dynamically, why is compiler sure that it's processing the correct method? 看来应该动态地解决此方法调用,为什么编译器确定它正在处理正确的方法?

All Generic type will assign at compile time so compiler will infer type from your assignment and its expected both to be same, but in your case its different, so it will give type mismatch error, change code like this to fix the errors. 所有泛型类型都将在编译时进行分配,因此编译器将从您的分配及其预期的类型中推断出类型,但在您的情况下,它们是不同的,因此它将产生类型不匹配错误,请更改此类代码以修复错误。

public class Test2 {

    public static void main(String... args) {
        ArrayList<RuntimeException> a = new ArrayListFactory().create(new RuntimeException());
        ArrayList<String> b = new ArrayListFactory().create("Z");  
        }
}

In this statement: 在此语句中:

ArrayList<Exception> b = new ArrayListFactory().create("Z");

The compiler uses type inference (from the declaration ArrayList<Exception> ) to add a constraint on the generic return type of create() . 编译器使用类型推断(来自声明ArrayList<Exception> )对create()的通用返回类型添加约束。 It's called a Target Type . 这称为目标类型 The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. 表达式的目标类型是Java编译器期望的数据类型,具体取决于表达式出现的位置。

In this case, T should be a subclass of Exception. 在这种情况下,T应该是Exception的子类。 RuntimeException is thus fine; 因此, RuntimeException很好。 but String is not. String不是。

This feature appeared with Java 8. More information on it : http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html 此功能随Java 8一起出现。有关更多信息,请参见: http : //docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html

1) First call 1)首次通话

    ArrayList<Exception> a = new ArrayList<RuntimeException>();

is not a legal use of Generics in Java. 不是Java中泛型的合法使用。 You can go to Explanation of the get-put principle to understand. 您可以转到“获取原理”的说明进行理解。

2) Second call 2)二次通话

The inference of the T Type depends on the returned type declared from the caller. T类型的推论取决于从调用方声明的返回类型。

Here the caller declares the returned type as Exception : 在这里,调用者将返回的类型声明为Exception

 ArrayList<Exception> b = new ArrayListFactory().create("Z");

Whereas the compilation error : 而编译错误:

Error:(15, 63) java: incompatible types: inference variable T has incompatible 错误:(15,63)java:不兼容类型:推断变量T具有不兼容

bounds equality constraints: java.lang.Exception 边界相等约束:java.lang.Exception

To pass a String : 传递字符串:

 ArrayList<String> b = new ArrayListFactory().create("Z");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM