Java Casting方法,不知道要转换为什么

今天我正在玩Java,我注意到一些奇怪的东西。 考虑以下代码:

String foo = cast("hi"); int bar = cast("1"); 

cast()方法在这里:

 public static  T cast(Object value) { return (T) value; } 

Java似乎将"hi"转换为String,即使我没有传递任何提示它将是一个String ,除了类型。 它确实很好,但是在bar失败了,因为你不能将一个String放到一个Integer中。 这里发生了什么?

我有两个猜测:

  1. cast方法返回一个Object ,并在初始化时自动转换为该类型。

    这没有意义,因为它会给我:

     Type mismatch: cannot convert from Object to int 
  2. Java似乎知道它需要转换为String,或者变量的类型。 但这是如何工作的?

您的强制转换方法执行未经检查的转换 ,该转换在JVM中专门处理,以保持与非generics代码的向后兼容性。

在使用generics的类型系统下,这样的调用不能显示为静态安全。 拒绝此类调用将使大量现有代码无效,并阻止它们使用较新版本的库。 JLS 5.1.9

调用没有显式类型参数的方法将导致编译器推断调用的类型参数,在这种情况下基于它们的预期返回类型。 类型推断 , JLS 15.12.2.7。 。 这意味着代码与此等价:

 String foo = Caster.cast("hi"); // no exception int bar = Caster.cast("1"); // runtime ClassCastException 

原始类型将推断为其盒装版本:

如果A是基本类型,则通过装箱转换将A转换为引用类型U,并且该算法递归地应用于约束U << F. JLS 15.12.2.7。

JVM通过对包含未经检查的强制转换的函数的返回值进行运行时类型检查来确保类型安全,在第一个未删除类型信息的位置(我没有在规范中明确说明它,但事情看起来像这样工作,虽然在Java教程中提到过。 在这种情况下,尝试将值分配给类型化局部变量时,将检查返回值的类型,从而导致ClassCastException

为了更好地了解强制执行运行时类型检查强制转换的时间,下面是一些示例:

 Object a3 = Caster.cast(3); // no exception, a3 is now Integer Object a4 = (String)Caster.cast(3); // an explicit cast causes runtime ClassCastException 

编辑:

这是一个关于何时强制执行运行时类型检查的StackOverflow问题: 何时是在类型擦除后执行的函数的generics返回值?

 public static  T cast(Object value) { return (T) value; } 

重要的部分是方法上的 ,这意味着该方法将根据方法调用所期望的内容返回一个类型。

 String foo = cast("hi"); // left side is a String,  will be typed as String 

第二个是有点棘手,因为generics类型不能是原始类型。 我猜它会返回最常见的Object类型。

 int bar = cast("1"); // left side is primitive //  will be typed by with the corresponding non-primitive type. // But it fails because "1" cannot be casted to java.lang.Integer 

我没有看到任何奇怪的行为。

在:

 String foo = cast("hi"); 

"hi"是一个Object (作为Java中的所有东西),因此它将被编译器接受为Object参数。 调用之后, cast()函数返回“hi”,这是一个字符串,并将其分配给String foo 。 这里没有奇怪的行为。

在:

 int bar = cast("1"); 

“1”是一个对象,它被编译器接受。 cast函数返回“1”,这是一个字符串。 与其他语言(例如Javascript)不同,字符串不能直接转换为整数。 这里没有奇怪的行为。

如果将cast()函数更改为:

 public static  T cast(T value) { return value; } 

您将在编译时获得错误,而不是执行时间。