J S*_*J S 2 java generics types
如果将参数化类型对象分配给原始类型对象,据我所知,原始类型对象采用参数化类型.这对我来说很有意义.但为什么它不能相反呢?我认为在将Raw Type分配给Paramterized Type之后,编译器将简单地假设参数化类型.
谢谢你的帮助!
好吧,据我所知,以下内容没有问题,将Raw Type视为传递了String类型:
SomeClass<String> instance1 = new SomeClass<>();
SomeClass instance2 = instance1;
Run Code Online (Sandbox Code Playgroud)
但是以下内容将抛出警告,并且任何类的方法都不会隐含一种String类型:
SomeClass instance1 = new SomeClass();
SomeClass<String> instance2 = instance1;
Run Code Online (Sandbox Code Playgroud)
我想我只是想出来了,所以如果是这样我很遗憾浪费每个人的时间.这是否有效,因为instance2正在创建一个指针而不是一个新对象,并且指针不能改变它指向的对象的行为?
泛型只是编译时间.基本上,当编译代码时,参数化类型将被删除并替换为强制转换.
考虑以下内容:
class SomeClass<T> {
T value;
T get() {
return value;
}
void set(T val) {
value = val;
}
}
Run Code Online (Sandbox Code Playgroud)
当你声明一个新的SomeClass时,它看起来像是这样的:
class SomeClass {
String value; // "value is now a String"
String get() {
return value;
}
void set(String val) {
value = val;
}
}
Run Code Online (Sandbox Code Playgroud)
但这不是实际发生的事情.实际发生的是SomeClass总是这样:
class SomeClass {
Object value; // erasure of T is Object
Object get() {
return value;
}
void set(Object val) {
value = val;
}
}
Run Code Online (Sandbox Code Playgroud)
当你有一个SomeClass<String>,无论何时你说SomeClass<String>,编译器都会从Object转换为String.在运行时,原始时间和参数化类型之间没有行为差异,只有是否存在强制转换.这就是原始类型"糟糕"的原因,因为原始类型与不使用泛型之间基本没有区别.
试试这个:
SomeClass<String> pam = new SomeClass<String>();
((SomeClass)pam).set(new Integer(0));
System.out.println(((SomeClass)pam).get()); // prints 0
System.out.println(pam.get()); // ClassCastException
Run Code Online (Sandbox Code Playgroud)
所以要清楚,当你这样做时:
SomeClass<String> instance1 = new SomeClass<>();
SomeClass instance2 = instance1;
Run Code Online (Sandbox Code Playgroud)
没有类型被"通过".String someString = someClass.get();不是instance2.
当你这样做:
SomeClass instance1 = new SomeClass();
SomeClass<String> instance2 = instance1;
Run Code Online (Sandbox Code Playgroud)
你得到一个警告,因为它不安全.不能保证SomeClass<String>值是一个字符串,但如果你打电话,它将被转换成一个字符串instance1.
给出以下代码段:
SomeClass<String> instance1 = new SomeClass<String>();
SomeClass instance2 = instance1;
System.out.println(instance1.get());
System.out.println(instance2.get());
Run Code Online (Sandbox Code Playgroud)
print语句编译为以下字节码:
getstatic PrintStream System.out
aload_1 instance1
invokevirtual Object SomeClass.get() // instance1.get() returns Object
checkcast String // which is casted to String
invokevirtual void PrintStream.println(String) // call println for String
getstatic PrintStream System.out
aload_2 instance2
invokevirtual Object SomeClass.get() // instance2.get() returns Object
invokevirtual void PrintStream.println(Object) // call println for Object
Run Code Online (Sandbox Code Playgroud)
如你所见,除了演员之外没有区别.