java - 类型转换中的模棱两可的行为

标签 java generics casting

我在教学生老式泛型时遇到了一个看不见的东西!我在演讲时的行为! :(

我有一个简单的类

public class ObjectUtility {

  public static void main(String[] args) {
    System.out.println(castToType(10,new HashMap<Integer,Integer>()));
  }

  private static <V,T> T castToType(V value, T type){
    return (T) value;
  }

}

这给出输出 10,没有任何错误!!!我期待这会给我一个 ClassCastException,并出现一些错误,例如 Integer cannot be cast to HashMap。

好奇和愤怒,我在返回值上尝试了 getClass(),如下所示

System.out.println(castToType(10,new HashMap<Integer,Integer>()).getClass());

如我所料抛出 ClassCastException。

此外,当我将同一个语句分成两部分时,比如

Object o = castToType(10,new HashMap<Integer,Integer>());
System.out.println(o.getClass());

它没有抛出任何错误并打印 class java.lang.Integer

全部用

执行
openjdk version "1.7.0_181"
OpenJDK Runtime Environment (Zulu 7.23.0.1-macosx) (build 1.7.0_181-b01)
OpenJDK 64-Bit Server VM (Zulu 7.23.0.1-macosx) (build 24.181-b01, mixed mode)

有人能为我指出正确的方向吗?为什么会发生这种行为?

最佳答案

T 在运行时不存在。它解析为约束的下限。在本例中,没有对象,因此它解析为 Object。一切都可以转换为 Object,因此没有类转换异常。

如果你要改变约束条件

private static <V,T extends Map<?,?>> T castToType(V value, T type){
    return (T) value;
}

然后对 T 的转换成为对下界 Map 的转换,显然 Integer 不是,你得到类转换您期望的异常。


Also, when I break the same statement into two, something like

Object o = castToType(10,new HashMap<Integer,Integer>());
System.out.println(o.getClass());

It is not throwing any error

castToType(10,new HashMap<Integer,Integer>()).getClass() 

这会抛出类转换异常,因为它静态链接到方法 HashMap::getClass(不是 Object::getClass),因为签名表示期望 HashMap 作为返回值。这需要对 HashMap 进行隐式转换,但会失败,因为 castToType 在运行时返回一个 Integer

当你第一次使用它时

Object o = castToType(10,new HashMap<Integer,Integer>());

您现在静态链接到 Object::getClass,这很好,不管实际返回的是什么。

“未拆分”版本等同于此

final HashMap<Integer, Integer> map = castToType(10, new HashMap<>());
System.out.println(map.getClass());

这有望证明差异

关于java - 类型转换中的模棱两可的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57853055/

相关文章:

c - 为什么我可以在 C 中将整数隐式转换为 char

java - 如何设置来自 Stream 的 imageView

java - 通过构造函数传递实例或使用静态访问它?

java - 匹配不在嵌套括号中的字符

swift - swift 中类型约束泛型函数的调用优先级?

Java泛型。对我来说有什么好处?

scala - 在 Scala 中调用泛型类型的 "static function"

c++ - 类型转换泛型类型 C++

java - JPA 和 Hibernate 有什么区别?

c# - null 和 (type)null 有什么区别?