【问题标题】:Local Variable Type Inference with Conditional (Ternary) Operator of Different Types使用不同类型的条件(三元)运算符进行局部变量类型推断
【发布时间】:2019-09-20 03:21:22
【问题描述】:
var test = "Hello World!";

在 Java 10+ 中,上面的 sn-p 编译,test 在编译时被推断为String

但是,我们可以使用条件(三元)运算符来返回不同的类型,例如:

var test = new Random().nextBoolean() ? "Hello World!" : 123;

如果我们在运行时打印test.getClass(),它会输出:

  • 类 java.lang.String
  • 类 java.lang.Integer

这是有道理的,但是test 在编译时的类型是什么?是Object,还是别的什么?

【问题讨论】:

  • @Naman 我反对它是重复的,主要是因为我的代码在 Java 12 上编译,甚至在 Java 12 上运行他们的代码(他们说不会编译)编译就好了我。我的问题更多的是,这个变量的编译时类型是什么,为什么?不过,我可以看到两者之间的关系。
  • 好吧,当然可以这样做,这也是我实际上没有投票结束它的原因之一。但目前,这个问题及其答案既不相辅相成,也不是很清楚。也就是说,我仍然将其留给社区进一步投票。与链接相关,答案显示该错误已在更高版本的 JDK10 中修复。
  • related 以最后一个示例为例

标签: java var type-inference java-10


【解决方案1】:

有趣的是,Intellij 告诉我test 的类型不是Object,而是这个野兽:

java.io.Serializable & Comparable<? extends java.io.Serializable & Comparable<?> & constant.Constable & constant.ConstantDesc> & constant.Constable & constant.ConstantDesc

之所以会出现这种情况,是因为编译器将变量的类型推断为StringInteger之间的最接近公共超类,它们实际上是SerializableComparableConstableConstantDesc 在 Java 12 中。

有一篇有趣的文章详细阐述了不可能的类型,这些类型被称为(因为它们只能由编译器推断):Representing the Impractical and Impossible with JDK 10 “var”

如果我们要返回完全不相关的对象,例如 IntegerByteArrayOutputStream,那么我们会看到 Java 会将 test 的编译时类型推断为 Object

var test = new Random().nextBoolean() ? 123 : new ByteArrayOutputStream();

【讨论】:

  • This Q&A 还讨论了具有不可表示类型的变量的可能性,以及 Java 10 之前的构造。
  • JLS 15.25.3 的第三个项目符号涵盖了这一点。您所说的“最接近的公共超类”在这里称为两种类型的 lub最小上界。但你的直觉是正确的。
猜你喜欢
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 1970-01-01
  • 2020-03-30
  • 2012-01-22
相关资源
最近更新 更多