Java 7中的类型推断,何时以及为什么应该使用它?

Java 7中的类型推断,何时以及为什么应该使用它?,java,generics,java-7,type-inference,Java,Generics,Java 7,Type Inference,看起来他们生成了相同的bytebote 那么,什么时候以及为什么我们应该使用类型推断而不是另外两种呢?类型推断只是一种捷径,它为实例化参数化类型提供了不必要的漫长道路。泛型仍然是通过类型擦除来实现的,因此您的字节码将只具有原始类型。正如您的示例所示,Java泛型是通过类型擦除来实现的,并且泛型代码在运行时与非泛型代码没有什么不同。这使得泛型纯粹是一种编译时特性,增加了类型安全性,以利于开发人员 在您的示例中,new ArrayList(),new ArrayList(),和new ArrayLi

看起来他们生成了相同的bytebote


那么,什么时候以及为什么我们应该使用类型推断而不是另外两种呢?

类型推断只是一种捷径,它为实例化参数化类型提供了不必要的漫长道路。泛型仍然是通过类型擦除来实现的,因此您的字节码将只具有原始类型。

正如您的示例所示,Java泛型是通过类型擦除来实现的,并且泛型代码在运行时与非泛型代码没有什么不同。这使得泛型纯粹是一种编译时特性,增加了类型安全性,以利于开发人员

在您的示例中,
new ArrayList()
new ArrayList()
,和
new ArrayList()
,这三者之间实际上没有什么区别-重要的是它被分配到的变量的类型。仍然不鼓励使用
new ArrayList()
,因为它看起来像是遗留代码,可能会让其他开发人员感到困惑。它将导致编译器/IDE显示标准的“原始类型”警告,因此会分散注意力。但至少对于无参数构造函数来说就是这样

然而,对于任何接受泛型参数的构造函数来说,提供类型参数或使用类型推断确实很重要。考虑这个例子:

  @Test
  public void TypeInferenceTest() {
    inference();
    uncheckedAssignment();
    explicit();
  }

  private void inference() {
    ArrayList strings = new ArrayList();
    strings.add("abc");
    String s = (String)strings.get(0);

    Assert.assertThat(s, Matchers.is("abc"));
  }

  private void uncheckedAssignment() {
    ArrayList strings = new ArrayList();
    strings.add("abc");
    String s = (String)strings.get(0);

    Assert.assertThat(s, Matchers.is("abc"));
  }

  private void explicit() {
    ArrayList strings = new ArrayList();
    strings.add("abc");
    String s = (String)strings.get(0);

    Assert.assertThat(s, Matchers.is("abc"));
  }
Collection ints=Arrays.asList(1,2,3);
List strings1=新阵列列表(ints);//编译!
List strings2=新阵列列表(ints);//不会编译
List strings3=新阵列列表(ints);//不会编译

至于为什么要使用
new ArrayList(ints)
而不是
new ArrayList(ints)
,那么,它就不那么冗长了,并且避免了重复已在分配给的变量中指定的泛型类型。

其他人已经介绍了它生成相同代码的原因。因此,要回答实际问题,简短的回答是:

Collection<Integer> ints = Arrays.asList(1, 2, 3);

List<String> strings1 = new ArrayList(ints);         // compiles!
List<String> strings2 = new ArrayList<String>(ints); // won't compile
List<String> strings3 = new ArrayList<>(ints);       // won't compile
ArrayList strings=new ArrayList();
因为它比这更简短,同时传达了相同的含义(对人类和编译器):

ArrayList strings=new ArrayList();
但避免不必要地引起如下警告:

   ArrayList<String> strings = new ArrayList<String>();
ArrayList strings=new ArrayList();
关于更简短的问题,这是:

   ArrayList<String> strings = new ArrayList();
ArrayList strings=new ArrayList();
这不是很糟糕,而且把它打印出来也没有什么害处(毕竟,我们都这么做了很多年了)。但如果你最终写了这样的东西:

   ArrayList<String> strings = new ArrayList<String>();
Map myMap=newhashmap();
如果您必须键入两次,则会变得更加乏味:

   Map<String, Map<Widget<Spork>, Bar<Llama>>> myMap = new HashMap<>();


这并不能真正回答问题。我不同意。类型推断只是一条捷径;如果您的字节码没有类型信息,则反编译的代码将反映这一点。所以,现在很容易看出,1和2之间没有区别。
   ArrayList<String> strings = new ArrayList<String>();
   Map<String, Map<Widget<Spork>, Bar<Llama>>> myMap = new HashMap<>();
<String, Map<Widget<Spork>, Bar<Llama>>>