【问题标题】:Type Inference: Java 7 Type Parameters类型推断:Java 7 类型参数
【发布时间】:2014-08-05 13:00:59
【问题描述】:

今天我们讨论了 Java 7 在我们公司的优势。由于 Java 7 有可能定义以下行

Map<String, List<String>> myMap = new HashMap<String, List<String>>();

作为

Map<String, List<String>> myMap = new HashMap<>();

我们就上述主题进行了长时间的讨论。我们中的一些人认为这是类型推断(如 C# 中的 var 关键字)并且类型将在运行时计算,其他人认为这只是声明某个变量的一种更简单的方法并且没有推断,因为类型在编译时由上下文已知。

请提供说明。该技术是如何工作的?

编辑: 官方 Oracle 文档没有提供关于此的精确文档。 http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

【问题讨论】:

标签: java generics java-7 type-inference variable-declaration


【解决方案1】:

其实是类型推断。

菱形运算符 (&lt;&gt;) 允许将赋值的右侧定义为具有与左侧相同类型参数的真正泛型实例无需再次键入这些参数(因为编译器推断从左侧的类型)。

来自Angelika Langer's Generics FAQ:

It(菱形运算符)表示空尖括号,用于 new -expression 中的类型推断。

更多信息:

【讨论】:

  • 当然。请记住,参数化类型(又名泛型)在编译期间会被删除。因此,它们没有经过运行时类型检查。编译器确实会检查它们,但在编译时(之后它们会被擦除)。
  • @EdwinBuck 正确,但与这个问题有关的意义是什么?即使没有发生类型擦除,答案也不会改变。类型推断仍然会发生。
  • 类型擦除总是发生在泛型上。这就是为什么你不能对它们进行任何运行时类型推断的原因,这就是为什么这个陈述与菱形推断是否在运行时发生有关(这是问题中的一个人假设的一部分)
【解决方案2】:

“我们中的一些人认为这是类型推断(就像 C# 中的 var 关键字)并且类型将在运行时计算,其他人认为这只是声明某个变量的一种更简单的方法并且没有推断,因为的类型在编译时由上下文已知。”

Ref: 泛型类的定义格式如下:

class name<T1, T2, ..., Tn> { /* ... */ }

类型参数部分由尖括号 () 分隔,跟在类名之后。它指定类型参数(也称为类型变量)T1、T2、...和Tn。

编译时去掉类型参数,通过Type Erasure的过程将其转换为Raw Type,即上面的声明将转换为:

class name { /* ... */ }

至于用泛型声明某个类的语法如下:

-- (Case I)
Map<String, List<String>> myMap = new HashMap<String, List<String>>(); 

OR

-- (Case II)
Map<String, List<String>> myMap = new HashMap<>();

在case I 中,右侧的声明是多余的,可以从对象的左侧声明中推断,因此从Java7 开始在右侧编写被认为是不必要的

【讨论】:

    【解决方案3】:

    首先请注意,new HashMap&lt;String, List&lt;String&gt;&gt;() 和new HashMap&lt;Integer, String&gt;() 和new HashMap() 之间的编译字节码绝对没有区别,因为它们在类型擦除之后是相同的。因此,无论您在对象创建中放入括号(如果有)中的任何内容,都只会在编译时使用。

    有人说,使用菱形运算符,编译器“推断”了其中的类型。但是让我们考虑一下为什么编译器需要“推断”这一点。为什么编译器需要知道里面有什么?

    如果您调用的构造函数采用K 或V 类型的一些参数,那么括号中的类型很重要,因为它作为对可以作为参数传递的对象类型的约束。在这种情况下,编译器应该推断它。

    但是,在问题的情况下,您正在调用不带参数的构造函数,编译器实际上并不需要知道括号中的内容 - 编译器是否知道没有区别,因为 1 ) 它不需要它来生成字节码,并且 2) 我们知道存在一些可以工作的类型(没有参数类型会导致编译失败)。所以在这种情况下,编译器可能不会“推断”,如果它不想。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多