英文:
Why is this assignment illegal in Java generics?
问题
我确信我可能在这里漏掉了一些相当明显的东西,但是否有一个原因:
ArrayList<? extends Number> list = new ArrayList<Number>();
被允许,但是:
ArrayList<T extends Number> list = new ArrayList<Number>();
却不被允许?
英文:
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?
答案1
得分: 4
因为,在这里:
ArrayList<? extends Number> list = new ArrayList<Number>(); //OK
你正在使用 上界通配符 <? extends Number>
来定义类型为 ArrayList
的具体对象。
通配符的类型将匹配任何 Number
的子类型,这意味着你可以将任何用 任何 扩展了 Number
的类型来专门化的 ArrayList
分配给你的 list
变量:
list = new ArrayList<Float>(); //将正常工作
list = new ArrayList<Double>(); //将正常工作
list = new ArrayList<String>(); //不会工作,因为 String 不扩展 Number
唯一的注意点是捕获问题。你将无法在列表中添加继承自 Number 的实例。
然而,在这个例子中:
ArrayList<T extends Number> list = new ArrayList<Number>(); //语法错误
你的对象声明中存在语法错误。你正在使用有界类型参数来声明变量;然而,有界类型参数用于定义泛型类/类型或泛型方法。
类型参数 T
,或者任何(最好是大写)字母,用于在定义类(或方法)时声明泛型类型参数。
例如,在此定义中,你的上界泛型类型:
public class YourClass<T extends Number> {
// ...
}
将在运行时成为一个真正的类型,当你通过提供一些真正的类型作为泛型类型参数来声明你的 YourClass
类型时,就像这样:
YourClass<Integer> ints; //将正常工作
YourClass<Double> doubles; //将正常工作
YourClass<Float> floats; //将正常工作
YourClass<String> strings; //不会工作,因为 String 不扩展 Number
注意,这里同样,T extends Number
匹配任何扩展了 Number
的类型。
英文:
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>
.
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
:
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.
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).
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<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
.
答案2
得分: 0
如果您想要使用像 T 这样的通用类型类,您需要在您的类中明确声明它。您可以在这里找到官方文档。
如果您想要使用未知通配符类,您可以根据这里的说明在您的代码中自由使用它。
无论如何,您可以在这里找到一个类似的问题。
英文:
If you want to use a generic type class like T you need to explicitly declare it in your class. 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
Anyway, you can find a similar question here
答案3
得分: -2
以下是翻译好的部分:
/**
* 泛型版本的Box类。
* @param <T> 被封装的值的类型
*/
public class Box<T> {
// T代表“类型”
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
因此,你可以使用类似这样的语法来创建一个ArrayList:ArrayList<T> arr = new ArrayList<T>()
。
来源:https://docs.oracle.com/javase/tutorial/java/generics/types.html
英文:
generic class in java should look like this
/**
* 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>()
source: https://docs.oracle.com/javase/tutorial/java/generics/types.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论