@Test
public void TypeInferenceTest() {
inference();
uncheckedAssignment();
explicit();
}
private void inference() {
ArrayList<String> strings = new ArrayList<>();
strings.add("abc");
String s = strings.get(0);
assertThat(s, is("abc"));
}
private void uncheckedAssignment() {
ArrayList<String> strings = new ArrayList();
strings.add("abc");
String s = strings.get(0);
assertThat(s, is("abc"));
}
private void explicit() {
ArrayList<String> strings = new ArrayList<String>();
strings.add("abc");
String s = strings.get(0);
assertThat(s, is("abc"));
}
The code above used three ways to instantiate a list: type inference, open generic type and closed generic type.
But if I decompile the generated bytecode using JD-GUI, this is the result:
@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"));
}
Looks like they generated the same bytebote.
So when and why should we use type inference instead of the other two?
Others have covered why it generates the same code. So, to answer the actual question - the short answer is to prefer this:
ArrayList<String> strings = new ArrayList<>();
Because it's briefer than this, while conveying the same meaning (to humans and to the compiler):
ArrayList<String> strings = new ArrayList<String>();
But avoids unnecessarily causing a warning like this:
ArrayList<String> strings = new ArrayList();
As for being briefer, this:
ArrayList<String> strings = new ArrayList<String>();
Isn't that bad, and there's no real harm in typing it out (after all, we've all been doing it for years). But if you wind up writing something like:
Map<String, Map<Widget<Spork>, Bar<Llama>>> myMap = new HashMap<>();
It becomes far more tedious if you have to type this twice:
<String, Map<Widget<Spork>, Bar<Llama>>>
The type inference is just a shortcut for an unnecessarily long way of instantiating paremeterized types. Generics are still implemented by type-erasure, so your bytecode will only have the raw types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With