我已经阅读了一些主题,其中涵盖了关于泛型的某些问题,例如它们与原始类型的关系.但是我想对Java SE教程中关于未绑定泛型的某一行进行补充说明.
根据一句话:
printList的目标是打印任何类型的列表,但它无法实现该目标 - 它只打印一个Object实例列表; 它不能打印List <Integer>,List <String>,List <Double>等,因为它们不是List <Object>的子类型.
如果我理解这句话; 之间的区别List<?>和List<Object>,就是我们可以使用的类型参数List<String>或List<Integer>通过实施前.如果我们实现后者,我们只能使用type参数List<Object>.好像List<?>是一个上界Object即List<? Object>.
但是后面的句子让我感到困惑,因为根据我之前的理解,它List<Object>应该只包含类的实例Object而不包含其他内容.
重要的是要注意
List<Object>并且List<?>不一样.您可以将Object或Object的任何子类型插入到List<Object>.但是你只能插入null一个List<?>.
我知道我们不能调用,instanceof List<E>因为List<E>它不是一个可再生的类型.兼顾instanceof List和instanceof List<?>工作; 然而eclipse IDE建议使用instanceof List<?>.
我想知道为什么它建议使用未绑定的通配符instanceof List<?>而不是原始调用instanceof List.未绑定的通配符是否instanceof List<?>比原始调用有任何优势instanceof List?
预先感谢.
编辑1:实际上,instanceof List与instanceof List<?>编译器在编译时将擦除类型相同.但是化妆品的原因旁边,梅纳指出的,它有其他任何理由使用instanceof List<?>赞成instanceof List?
编辑2:根据Oracle的这个条目:
- instanceof/cast表达式的类型是raw
这种情况经常发生,因为javac禁止其目标类型为泛型类型的instanceof表达式; 对于强制类型转换,编译器稍微宽松一些,因为允许转换为泛型类型,但会发出警告(参见上文).无论如何,原始类型应该由无界通配符替换,因为它们具有类似的属性和子类型.
Object o = new ArrayList<String>();List<?> list_string = (List)o;//same as (List<?>)o boolean b = o instanceof List; //same as o instanceof List<?>
因此,我们可以推断,除了Mena所说的美容理由和使用genenics的限制,instanceof List并且instanceof …
我有一个关于Java中泛型的问题,即使用通配符.我有一个像这样的示例类GenClass:
public class GenClass<E> {
private E var;
public void setVar(E x) {
var = x;
}
public E getVar() {
return var;
}
}
Run Code Online (Sandbox Code Playgroud)
我有另一个简单的类:
public class ExampleClass {
}
Run Code Online (Sandbox Code Playgroud)
我写了以下测试类:
public class TestGenClass {
public static void main(String[] str) {
ExampleClass ec = new ExampleClass();
GenClass<ExampleClass> c = new GenClass<ExampleClass>();
c.setVar(ec);
System.out.println(c.getVar()); // OUTPUT: ExampleClass@addbf1
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用通配符并在测试类中写入:
GenClass<?> c = new GenClass<ExampleClass>();
Run Code Online (Sandbox Code Playgroud)
在以下的地方:
GenClass<ExampleClass> c = new GenClass<ExampleClass>();
Run Code Online (Sandbox Code Playgroud)
编译器对这个新语句没有任何问题,但它抱怨
c.setVar(ec);
Run Code Online (Sandbox Code Playgroud)
它说"方法(setVar())不适用于参数(ExampleClass)".为什么我收到此消息?
我认为我使用通配符的方式使得引用变量c的类型为GenClass,它将接受任何类作为参数 - 在EI的位置上将具有任何类.这只是变量的声明.然后我用它初始化它
new GenClass<ExampleClass>()
Run Code Online (Sandbox Code Playgroud)
这意味着我创建了一个GenClass类型的对象,它具有一个类型为ExampleClass的参数.所以,我认为现在GenClass中的E将是ExampleClass,我将能够使用方法setVar(),将其作为类型为ExampleClass的参数.这是我的假设和理解,但似乎Java不喜欢它,我不对.任何评论表示赞赏,谢谢.