当前位置: 首页 > 知识库问答 >
问题:

JDK8类型推理问题

欧阳俊明
2023-03-14

我正在尝试运行以下代码,由于类型推断,它在JDK8下编译得很好:

public static <A,B> B convert(A a) {
  return (B) new CB();
}
public static void main(String[] args) {
  CA a = new CA();
  CB b = convert(a); //this runs fine
  List<CB> bl = Arrays.asList(b); //this also runs fine
  List<CB> bl1 = Arrays.asList(convert(a)); //ClassCastException here
}

但是,运行此命令会抛出ClassCastException:CB无法强制转换为[Ljava.lang.Object,但CB b=convert(a)可以正常工作。

知道为什么吗?

共有1个答案

秋建义
2023-03-14

每当你创建一个带有签名的泛型方法,promise返回调用者想要的任何东西时,你都是在自找麻烦。您应该从编译器那里得到一个“未检查”的警告,基本意思是:可能会发生意外的< code>ClassCastException。

你希望编译器推断

List<CB> bl1 = Arrays.asList(YourClass.<CA,CB>convert(a));

而编译器实际上推断出

List<CB> bl1 = Arrays.asList(YourClass.<CA,CB[]>convert(a));

据我所知,因为它更喜欢不需要varargs打包的方法调用(这与pre-varargs代码兼容)。

这会失败,因为您的转换方法不返回预期的数组类型。

 类似资料:
  • 我正在尝试将一个项目切换到Java8,并在日食月神和javac的类型推断之间遇到了奇怪的差异。使用JDK 1.7.0_65 javac,这段代码编译得很好。JDK 1.8.0_11 抱怨 toString(字符[]) 和 toString(可抛出)都匹配“toString(getKey(代码,空)]”行。日食 Luna 4.4 (I20140606-1215) 使用任一 JDK 愉快地编译它: 我

  • 我试图扫描JEP-286关于局部类型推断的信息。我看到这只适用于局部变量-理解。因此,这确实有效: 另一方面,我确实看到这并不能编译: 很明显,事实并非如此,因为JEP是这么说的。现在我的问题是: 声明为的公共/受保护成员失败是完全合理的,至少IMO是如此。但是,为什么即使它是,它也不能编译呢?我只能假设您仍然可以通过反射来获取该变量(我无法获取这样的局部字段)……而获取该变量需要进行转换,很可能

  • 当然,如果我给IntelliJ添加更多上下文,比如: 这是正确的,但在Java10 var推断类型上下文中,这是错误的: 我理解编译器不能推断的输入类型。如果我写: 编译器的错误更加不可读(但包含更多关于推理失败原因的提示),如下所示:

  • 查看我在某处(这里是游乐场)找到的这个Typescript4.2片段: 我的头不能绕着它。TS如何处理这件事?它怎么不卡在无限递归里?具体地说,对于和的情况,悬停在变量上显示TS将类型解析为和。这是怎么回事?

  • 条款二:理解auto类型推导 如果你已经读过Item1的模板类型推导,那么你几乎已经知道了auto类型推导的大部分内容,至于为什么不是全部是因为这里有一个auto不同于模板类型推导的例外。但这怎么可能,模板类型推导包括模板,函数,形参,但是auto不处理这些东西啊。 你是对的,但没关系。auto类型推导和模板类型推导有一个直接的映射关系。它们之间可以通过一个非常规范非常系统化的转换流程来转换彼此。

  • 这节介绍TypeScript里的类型推论。即,类型是在哪里如何被推断的。 TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型。如下面的例子 let x = 3; 变量x的类型被推断为数字。 这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时。 大多数情况下,类型推论是直截了当地。 后面的小节,我们会浏览类型推论时的细微差别。 当需要从几个表达式中推断类型时候