当前位置: 首页 > 面试题库 >

ClassCast错误:Java 7与Java 8

白星腾
2023-03-14
问题内容

这是错误还是功能?以下代码在Java 7中运行正常,但在Java 8中引发异常:

最后一个命令在Java8中引发ClassCast异常,以上所有“等效”命令的工作方式相同。

我认为问题是在Java
8中,编译器决定String.value(char[])在最后一行使用而不是String.value(Object)在Java
7中使用。我认为这样做的方式应与向后兼容相同。我想念什么吗?

注意:正如Marko所建议的,这可能与Java 8中引入的目标类型推断有关。

public class Test {
    public static void main(String[] args) {
        System.out.println( getVal().getClass());  // String

        System.out.println( String.valueOf(Test.<Object>getVal()) );   // "abc"

        Object obj = getVal();
        System.out.println( String.valueOf(obj) );  // "abc"

        System.out.println( String.valueOf(getVal()) ); // 7: "abc", 8: Exception 
    }

    // returns a string for simplicity; imagine that given a field, it fetches values from a database
    @SuppressWarnings("unchecked")
    public static <T> T getVal() {
        return (T) "abc";
    }
}

Java 7中的结果:

class java.lang.String
abc
abc
abc

Java 8中的结果:

class java.lang.String
abc
abc
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to [C
    at Test.main(Test.java:11)

(注意:[C是一个字符数组)

两种Java都在Windows上:

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)

java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

问题答案:

String.valueOf是一个重载方法,您在必须从上下文推断参数类型的上下文中使用它。另一方面,类型推理规则在Java
8中已经得到了重大改进。最值得注意的是, 目标类型推断 已大大改进。因此,尽管在Java
8之前方法自变量站点未收到任何推断,但Object在您的情况下默认为默认值,在Java 8中,在这种情况下推断出了最特定的适用类型char[]

但是,请记住,在两种情况下,您使用的惯用法实际上都是无效的,因此编译器输出中的更改应指定为“陷阱”,而不是“错误”。

不幸的是,未经检查的强制转换有时是不可避免的,但是我无法想到在任何情况下都可以推断出不是由Class对象反射性地创建的某种东西的类型本身(与类型参数相反)。因此,您不太可能实际处于此处显示的位置,在该位置您可以根据调用站点上可接受的参数类型来推断类型。而且,使用重载方法执行此操作当然是不可行的,而将参数类型的选择留给推理。这只能“偶然”起作用。



 类似资料:
  • 问题内容: 我正在尝试通过Intellij IDEA将一个基本为空的项目部署到GAE。我创建了一个新项目,在appengine- web.xml中设置了我的项目ID,并保留了其他所有内容。我收到以下错误,完整日志在这里。 我尝试安装JDK 7,将所有内容都设置为使用该版本,并使用1.7和1.8中的JDK 8编译,似乎没有任何效果。 问题答案: Maven仍在使用Java 8

  • 问题内容: 我正在尝试编写一个非常简单的GUI应用程序,用于将一些记录插入数据库中,并读回一些记录(花哨的东西,只有1个表和3行,没有关系)。来源… 错误在这里 结束错误 我收到以下错误… (代码)0 (消息)SQL Server没有返回响应。连接已关闭。 (状态)08S01 我已验证用户,密码,服务器名称,端口和数据库名称都是正确的。如果我将用户名更改为无效的用户名,则会收到报告“无法登录”的错

  • 问题内容: 显然,Java7在循环优化方面存在一些讨厌的错误:Google搜索。 从报告和错误描述中,我很难判断该错误的重要性(除非您使用Solr或Lucene)。 我想知道的是: 我的(任何)程序受到影响的可能性有多大? 错误的确定性是否足以正常测试将其捕获? 注意:我不能让程序的用户使用该问题。 问题答案: 任何热点错误的问题在于,您需要先达到编译阈值(例如10000),然后才能获取它:因此,

  • 在运行我的项目时,我在android studio中收到ClassCastException。谁能告诉我是什么导致了这个错误。 com.intellij.psi.impl.source.PsiPlainTextFileImpl不能转换为com.intellij.psi.xml.XmlFile 谢谢。

  • 我有一个maven项目,并将intellij配置为使用Java8。我的一个同事推了一个更改,在界面中使用默认关键字。自从我同步了他的更改后,我的编译每次都失败了。 我目前被难住了,在网上找不到答案。

  • 问题内容: 我使用这个proguard文件: 但是在对代码进行一些更新之后,我出现了以下错误: 我尝试了: 但是仍然不起作用,怎么了?我真的不明白该怎么办。PS,您对优化我的文件有什么建议吗?提前致谢。 问题答案: 我有同样的问题。 我在这里找到了答案,并且对我有用:如何将ApacheHTTPAPI(旧版)添加为build.grade的编译时依赖项? 在顶层build.gradle文件中添加: 在