java - 编译器从不检查强制转换为泛型类型 (T)?

标签 java generics casting

static <T> void f1(Base arg1, T arg2) {
    T loc = (T) arg1; // why Derived is "kind of cast" to String?
    System.out.println(loc.getClass().getName()); // would print: Derived
}

f1(new Derived(), "sdf");  // T is String - inferred from arg2

class Base { }

class Derived extends Base { }

我的想法是否正确:写 cast (T) 意味着“编译器不能也不会检查这个 cast”在编译时,编译器不知道 arg2 是什么(它可以是任何东西),因此编译器不能排除转换可以工作并且必须信任程序员。因此,这个转换在编译时从未被检查过。 在运行时本地 var 声明看起来像 Object loc = arg1;(在类型删除之后)。所以一切正常只是因为编译器从不关心这个 (T) 转换? p>

P.S:我的研究:this , 和 this . This is also very interesting ("casting primitive to generic": (T) true) 我的问题更明确地指出了问题所在,问题还在于编译器是否检查了 cast (T) 并且相关代码示例中没有干扰。

最佳答案

这包含在 JLS Sec 5.5.1 中:

Given a compile-time reference type S(source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules.

...

If T is a class type, then either |S| <: |T|, or |T| <: |S|. Otherwise, a compile-time error occurs.

...

If T is a type variable, then this algorithm is applied recursively, using the upper bound of T in place of T.

因此编译器使用 Object 代替 T,因此它认为转换是合法的。

关于java - 编译器从不检查强制转换为泛型类型 (T)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47004935/

相关文章:

postgresql - 如何在 Postgres/Postgis 中转换类型(并使用 sequelizejs)

c# - If Else 在 linq 中使用匿名对象

java - 使用 Comparator 排序时,Content 已经有一个现有的父级

Java 多线程跳过循环并给出错误的结果

c# - 创建多个类型的通用方法

c# - 如何有效地从 List<T> 中删除 (C#)?

c# - 从基类强制转换为继承类时,InvalidCastException?

java - 如何将 if else 语句中的每个系统输出存储到一个解决方案字符串中

java - 如何深度复制具有初始容量的 map ?

c# - 如何在 C# 中对具有抽象内部类型的泛型进行模式匹配?