据我了解,Java 泛型将泛型方法(或泛型类)中有关参数类型 T 的所有信息都删除了。这就是为什么我们不能使用
新的表达,比如
new T()
instanceof表达式,如
if(obj instanceof T)
在泛型方法中。
我的问题是,当涉及到转换时,参数类型 T 如何在泛型方法中工作。例如,我这里有 3 个简单的类:
public class People {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public People(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "People [name=" + name + "]";
}
}
public class GenericClass<T> {
public T getCast(People p) {
return (T)p;
}
}
public class App
{
public static void main( String[] args )
{
People p = new People("Kewei");
GenericClass<Integer> genericClass = new GenericClass<Integer>();
Object p_object = genericClass.getCast(p);
System.out.println(p_object);
}
}
当它在通用方法 getCast(People p)
中执行 (T)p
时。它只是将类型 T 作为对象吗?或者它只是在编译时删除了整个 (T)
转换?我读过 Bruce Eckel 的《Thinking in Java》,大致理解为:
Java compiler checks at method's entry/leave points at compile time to make sure the internal consistency of generic method, and inserts casting code (at compile time).
这样理解对吗?
谢谢。
最佳答案
您可以在脑海中想象编译器将带有泛型的代码“重写”为没有泛型的代码。
在通用类中,T 被删除到其上限,在本例中为 Object,但也可以是其他东西。转换为 T 变成转换为 T 的上界(在本例中为 Object,因此它是多余的,编译器可能会跳过它)。该方法类似地返回 T 的上限(即 Object)。因此,没有运行时检查方法内部的转换是否有效。
public class GenericClass {
public Object getCast(People p) {
// In this case the cast to T is removed because T's upper bound is Object.
// But if T's upper bound was, say, Number, then there would still be a cast
// to the upper bound. e.g. "(Number)p", and the return type would also be Number
return p;
}
}
在调用返回 T 的方法的地方,编译器会将强制转换插入到 T 的实际类型中。在这种情况下,在 main 方法中,您有一个 GenericClass<Integer>
。 ,所以当getCast
返回 T,它被转换为 Integer。所以在这种情况下,运行时检查现在被“移动”到调用方法,而不是带有转换的方法。
// somewhere else
GenericClass genericClass = new GenericClass();
p_object = (Integer)genericClass.getCast(p);
也有可能调用者保留了一个 GenericClass<S>
引用(对于其范围内的某些类型参数 S),以便将结果强制转换为 S,而不是特定类型。然后我们将再次重复整个重写过程(即,对 S 的转换被重写为对其上限的转换,调用该方法的地方会将结果转换为它们的实际类型参数)。这意味着运行时检查可能会推迟到另一个地方,依此类推。
关于java - 在 Java 运行时使用泛型 - (T)object - 进行强制转换会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11353555/