简体   繁体   English

为什么这个赋值在 Java 泛型中是非法的?

[英]Why is this assignment illegal in Java generics?

I'm sure I'm probably missing something fairly obvious here, but is there a reason why:我敢肯定,我可能在这里遗漏了一些相当明显的内容,但是否有原因:

ArrayList<? extends Number> list = new ArrayList<Number>();

is allowed, but:是允许的,但是:

ArrayList<T extends Number> list = new ArrayList<Number>();

is not?不是?

Because, with:因为,与:

ArrayList<? extends Number> list = new ArrayList<Number>(); //OK

you are defining the concrete object of type ArrayList generalized with upper bounded wildcard <? extends Number>正在定义类型的具体对象ArrayList具有上界通配符广义<? extends Number> <? extends Number> . <? extends Number>

Type of your wildcard will match any sub-type of Number , which means that you can assign to your list variable, any ArrayList specialized with any type which extends Number :您的通配符类型将匹配Number任何子类型,这意味着您可以分配给您的list变量,任何专门用于扩展Number任何类型的ArrayList

list = new ArrayList<Float>(); //will work fine
list = new ArrayList<Double>(); //will work fine
list = new ArrayList<String>(); //will NOT work as String does not extend Number

The only caveat is the Capture Problem .唯一需要注意的是捕获问题 You won't be able to add Number extender instances in your list.您将无法在列表中添加 Number 扩展器实例。


In here, however:然而,在这里:

ArrayList<T extends Number> list = new ArrayList<Number>(); //Syntax error

you have a syntax error in your object declaration.您的对象声明中有语法错误。 You are using bounded type parameter to declare your variable;您正在使用有界类型参数来声明您的变量; however, bounded type parameter is used to define a generic class/type or generic method.但是,有界类型参数用于定义泛型类/类型或泛型方法。

Type parameter T , or any (preferably capital) letter, is used to declare a generic type parameter when you define your class (or method).类型参数T或任何(最好是大写)字母用于在定义类(或方法)时声明泛型类型参数

For example, your upper-bounded generic type in this definition:例如,您在此定义中的上限泛型类型:

public class YourClass<T extends Number> {
....
}

will become a real type, at run-time, when you will declare your YourClass type by providing some real type, as a generic type argument, like this:将在运行时成为真实类型,当您通过提供一些真实类型作为泛型类型参数来声明YourClass类型时,如下所示:

YourClass<Integer> ints; //will work fine
YourClass<Double> doubles; //will work fine
YourClass<Float> floats; //will work fine
YourClass<String> strings; //will NOT work, as String does not extend Number

Pay attention, that here as well, T extends Number matches any type that extends Number .请注意,这里也是, T extends Number匹配任何扩展Number类型。

If you want to use a generic type class like T you need to explicitly declare it in your class.如果你想使用像 T 这样的泛型类,你需要在你的类中显式声明它。 Here you can find official documentation. 在这里你可以找到官方文档。

If you want to use an unknownk wildcard class instead, you can use if freely in you code as mentiond here如果你想使用一个 unknownk 通配符类,你可以在你的代码中自由使用 if 在这里提到

Anyway, you can find a similar question here无论如何,你可以在这里找到类似的问题

generic class in java should look like this java中的泛型类应该是这样的

/**
 * Generic version of the Box class.
 * @param <T> the type of the value being boxed
 */
public class Box<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

so you can use something like ArrayList<T> arr = new ArrayList<T>()所以你可以使用类似ArrayList<T> arr = new ArrayList<T>()

source: https://docs.oracle.com/javase/tutorial/java/generics/types.html来源: https : //docs.oracle.com/javase/tutorial/java/generics/types.html

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

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