Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 未经检查的强制转换行为(有或无变量赋值)_Java_Generics_Unchecked Exception - Fatal编程技术网

Java 未经检查的强制转换行为(有或无变量赋值)

Java 未经检查的强制转换行为(有或无变量赋值),java,generics,unchecked-exception,Java,Generics,Unchecked Exception,为什么main中的第一行不抛出ClassCastException,而第二行抛出ClassCastException import java.util.function.Function; class Scratch { static <T> T getSomething(Function<Integer, T> fun) { return (T) fun; } public static void main(String[]

为什么main中的第一行不抛出ClassCastException,而第二行抛出ClassCastException

import java.util.function.Function;

class Scratch {

    static <T> T getSomething(Function<Integer, T> fun) {
        return (T) fun;
    }

    public static void main(String[] args) {
        Scratch.<String>getSomething(x -> "hello");
        String something = Scratch.<String>getSomething(x -> "hello");
    }
}
import java.util.function.function;
课堂擦伤{
静态T getSomething(函数乐趣){
返回(T)乐趣;
}
公共静态void main(字符串[]args){
Scratch.getSomething(x->“hello”);
stringsomething=Scratch.getSomething(x->“hello”);
}
}

泛型只是一种编译时检查(请阅读)。因此,在运行时,您的
getSomething()
方法与此类似:

static Object getSomething(Function fun) {
    return fun;
}
String something = (String) Scratch.getSomething(x -> "hello");
现在您清楚地看到,第一行永远不会抛出异常

Scratch.getSomething(x -> "hello");
因为
函数
对象,因此可以毫无问题地返回

但是,第二行将抛出一个,因为它看起来类似于:

static Object getSomething(Function fun) {
    return fun;
}
String something = (String) Scratch.getSomething(x -> "hello");
函数
仍然是一个
对象
,因此可以从方法返回它,但它不是
字符串
,因此,您可以得到
类异常

代码编译得很好,因为您指示编译器您知道自己在做什么。您将得到一个
未选中的cast
警告,尽管在这一行:

 return (T) fun;

此警告应该是编译器向您(程序员)发出的一个指示,表明它(编译器)无法确保强制转换将成功。

区别在于,在第一种情况下,您不使用方法的结果,但在第二种情况下使用

强制转换是一个表达式,但它不是一个
语句表达式
。这意味着您不能编写以下内容:

(String) somethingReturningAString();
但你可以写:

String aString = (String) somethingReturningAString();
在编译时,编译器会在需要的地方以及可以插入的地方插入
checkcast
指令:

  • 它无法为第一个案例插入类型转换,因此不会进行检查
  • 它可以(而且必须)在第二种情况下插入强制转换,以确保它将实际是
    字符串的内容分配给
    字符串
    变量。因此,它会检查演员阵容,但失败了

值得注意的是,有些情况可能出乎意料,强制转换不是严格必需的,而是插入的。例如:

Scratch.<String>getSomething(x -> "hello").toString();

尽管
Object
有一个
toString()
方法,因此它可以在没有强制转换的情况下调用该方法。

无法回答这个问题,但显然您试图将函数强制转换为字符串,这不太可能工作。需要一个有趣的电话。在那里某处申请。因为你在第二种情况下使用结果,但在第一种情况下不使用。