我有两个问题
我的书中说明了“如果没有鞋面就指定了通配符 绑定,然后只能调用Object类型的方法 通配符类型“
的值
我不知道这可能是什么意思。这是什么意思?
对于外卡类型(无界和有界)有什么限制?例如,如果我有MyClass<?>
或MyClass<? extends SomeOtherClass>
的引用,我不允许通过该引用调用哪些方法。我不明白外卡允许或禁止我做什么,这可能是我不理解本书引用的原因。
我有第二部分的例子:
class SomeOtherClass
{
[...]
}
class MyClass<T>
{
[...]
}
class Test
{
public static void main(String[] arg)
{
MyClass<? extends SomeOtherClass> myClass = new MyClass<String>() // for instance what does the wild card reference limit me to in any way. In a general sence.
}
}
答案 0 :(得分:10)
对于返回参数化类型对象的集合和类,通配符边界(上部和下部)通常是必需的。
您经常会听到PECS
,这意味着“Producer extends,Consumer super”。我建议你阅读the answer to this question,以避免重复答案。
更准确地说,当您使用<? extends TheClass>
定义通配符时,您告诉编译器通配对象至少是TheClass
类型。因此,您可以像TheClass
的实例一样使用此对象,并调用此类型建议的任何方法。
现在,当您将通配符定义为<? super TheClass>
时,您告诉编译器您的通配对象类型是由TheClass
类型实现或扩展的。这意味着对象类型可能不是TheClass
,而是TheClass
对象可以用作通配引用的实例。因此,您无法在该对象上调用任何内容,因为其类型仅在运行时已知,但您可以将该对象传递给等待通配对象的方法。
示例:
private void foo(List<?> list) {
Object o = list.get(0); // ok
list.add(new Object()); // won't compile!
// you cannot add anything, and only extract Object instances
}
private void foo(List<? extends TheClass> list) {
Object o1 = list.get(0); // ok
TheClass o2 = list.get(0); // ok
list.add(new Object()); // won't compile!
list.add(new TheClass()); // won't compile!
// You are sure that the objects are of a subtype of TheClass,
// so you can extract TheClass instances safely. However, you cannot
// add anything to this list since its type is not known (may be
// different from TheClass, so the compiler does not allow anything).
}
private void foo(List<? super TheClass> list) {
Object o1 = list.get(0); // ok
TheClass o2 = list.get(0); // won't compile!
list.add(new Object()); // won't compile!
list.add(new TheClass()); // ok
// You are sure that the objects are of a type implemented by TheClass,
// so you can add any TheClass instances to the list. However, you cannot
// extract TheClass objects since the objects type may be just implemented
// by TheClass, but different.
}
答案 1 :(得分:0)
普通通用;
ArrayList<Man> list= new ArrayList<Man>();
list.put(man);
Man m = list.get(0);
使用带上限的通配符:
ArrayList<? extends Person> list= new ArrayList<? extends Person>();
list.put(man); //Man is a person..
Person p = list.get(0);
使用通配符:
ArrayList<?> list= new ArrayList<?>();
list.put(man);
Object o = list.get(0);
如果使用通配符,则无法知道ArrayList的泛型类型,因此只能从列表中获取Object,这意味着您将返回使用没有泛型的旧方式的ArrayLists ..
答案 2 :(得分:0)
例如你有&lt;?扩展MyClass&gt;通配符。这意味着匹配此通配符的任何类都可以是MyClass类型或其任何后代。但由于我们唯一知道它是MyClass的后代,我们只能保证MyClass类可用的方法可以调用。
对于具有bo上限的通配符&lt;?&gt;上限将是Object类。这意味着我们所知道的是该类扩展了Object,所以只有保证在这个类中存在的方法才是在Object类中定义的方法。