Java 当我们在泛型类中还需要一个参数时,菱形操作符会做什么? 类GenericBase{ 私有T基变量; 公共部门得不到{ 返回基变量; } 公共无效集(T){ baseVariable=t; } } 类GenericSubTwo扩展了GenericBase{ 私有V子变量2; 公共V get2(){ 返回子变量2; } } 公共测试类{ 公共静态void main(字符串[]args){ GenericBase sub2=新的GenericSubTwo(); } }
在这种情况下,菱形操作符是否真的生成了新的GenericSubTwo();Java 当我们在泛型类中还需要一个参数时,菱形操作符会做什么? 类GenericBase{ 私有T基变量; 公共部门得不到{ 返回基变量; } 公共无效集(T){ baseVariable=t; } } 类GenericSubTwo扩展了GenericBase{ 私有V子变量2; 公共V get2(){ 返回子变量2; } } 公共测试类{ 公共静态void main(字符串[]args){ GenericBase sub2=新的GenericSubTwo(); } },java,generics,Java,Generics,在这种情况下,菱形操作符是否真的生成了新的GenericSubTwo(); 或者别的什么。。我不明白发生了什么,因为在GenericSubTwo中,我需要两个参数。这真的没关系,因为您无论如何都看不到V是什么 V推断为对象,因为这是V上的边界 更新 实际上,似乎V被推断为?,因为它可以被转换为任何对象 GenericBase sub2=新的GenericSubTwo(); //有效强制转换:T必须是整数,但V可以是任何值 GenericSubTwo x=(GenericSubTwo)sub2;
或者别的什么。。我不明白发生了什么,因为在GenericSubTwo中,我需要两个参数。这真的没关系,因为您无论如何都看不到
V
是什么
V
推断为对象,因为这是V
上的边界
更新
实际上,似乎V
被推断为?
,因为它可以被转换为任何对象
GenericBase sub2=新的GenericSubTwo();
//有效强制转换:T必须是整数,但V可以是任何值
GenericSubTwo x=(GenericSubTwo)sub2;
“钻石操作员在这种情况下真的会做出新的GenericSubTwo()吗?”;"
不,那不是真的
“或者其他什么”
是的。其他的东西。而“其他的东西”是对象
。这是因为
因此,实际的参数化类型应该是GenericSubTwo()
,就像你做的那样GenericBase sub2=new-GenericSubTwo()
这是一个哲学问题,因为在编译的字节码中,new-GenericSubTwo()
,new-GenericSubTwo()
和新的GenericSubTwo()
。因此,如果您说它使用了特定的类型参数,但不影响结果,那么它真的存在吗
请记住,对象在运行时不知道其泛型类型参数,因此在运行时创建对象时,您不需要知道泛型类型参数。new
中提供的泛型类型参数仅在编译时用于类型检查(例如,检查与参数类型(如果有)的一致性,并检查该返回类型是否有效)。在类型检查之后,这些类型参数不再重要,因为它们不会被发送到编译的字节码中。在这种特殊情况下,由于构造函数没有参数,并且返回值被分配给GenericBase
,其中GenericSubTwo
的V
未使用,因此对w没有限制帽子V
可以是
因此,我们可以考虑编译器使用菱形来考虑对象创建表达式的不同方式:
- 编译器可以尝试为每个类型参数“推断”某些确切的类型参数,并检查该选择是否与参数和返回上下文一起工作;或者
- 编译器可以尝试证明存在至少一个类型参数选项,使其能够编译并进行类型检查,并且只要它能够证明至少存在一个类型参数选项,它就不需要选择它是哪一个类型参数,因为在发出字节码时不使用实际的类型参数
我很确定它是
,尽管我找不到任何关于这方面的文档。这很重要,因为你可以使用(GenericSubTwo)sub2
@昆仑是一个原始类型的转换,所以它仍然不重要,因为没有V
。实际上,似乎V
被推断为?
,因为它可以转换为任何东西…-引用变量sub2
可以“转换为任何东西”。但当我刚刚做x.set(“666”)时
在一个测试您的示例的实验中,我得到:“不兼容的类型:java.lang.String不能转换为java.lang.Integer”
?您认为这是为什么?TIA。@dedupler 1)sub2
不能强制转换为任何对象,例如,is不能强制转换为GenericSubTwo
,因为T
必须是Integer
——2)它失败,因为T
是Integer
并且方法是set(T)
,所以它与这个问题没有任何关系,这个问题是关于V
@dedupler你在讨论列表
和列表
之间的区别,所以你基本上是在问:泛型的好处是什么。对于这个问题,这完全是离题的。
class GenericBase<T> {
private T baseVariable;
public T get() {
return baseVariable;
}
public void set(T t){
baseVariable = t;
}
}
class GenericSubTwo<T, V> extends GenericBase<T>{
private V subVariable2;
public V get2(){
return subVariable2;
}
}
public TestClass{
public static void main(String[] args){
GenericBase<Integer> sub2 = new GenericSubTwo<>();
}
}