Can someone please explain type inference to me?
Not that I don't understand the idea. It's simple:
final map := new HashMap<String,List<Thing>>();
is equal to
final HashMap<String,List<Thing>> map =
new HashMap<String,List<Thing>>();
And who really wants that kind of line in their code, eh? Why write things twice, anyway?
The proposal in Neal's blog is considerably sane too, because it offers a way to allow a developer to choose not to use type inference. Some people even offered generic-type inference according to the types passed to the constructor:
final numbers := new ArrayList<>(1, 2)
is just the same as
final ArrayList<Integer> numbers = new ArrayList<Integer>(1, 2)
And again, who wants all this extra verbosity anyway? But let's take a look at a few possible following lines of code:
// compiler error: sort accepts the List interface This is okay, my mistake.
Collections.sort(numbers);
// compiler error: this is a list of Integers, not Numbers.
list.add(new Double(2.0));
Now, I realise that some language changes also change the way we developers do things; the for loop change was a great change, and obviously there was probably someone going "oh, but you can't access the iterator/array index and it's really useful to be able to". In the end, it's not that needed; more than that, some people still complain that the for construct could be even better with an additional (optional) colon, followed by the name of a local variable to hold the usually implicit iterator/array index.
The question is, how many of these instances are actually there? And how many instances of these variable creations are eventually doomed to explicit definitions due to return values, method parameters, specific generic type requirements, or just because they don't want to be declared final? This is an interesting question, and looking at Yielder as a test case, I wonder how much of it could be transformed to this new syntax, and how much is forced to stay explicit?
I will try (with the little free time I actually have) to chart this out, if it's of any interest to any of you. I would also appreciate something similar done in return, done on your own projects, if possible!
Update: I made a mistake when writing this post, note above. I guess I was tired to think when I started writing it, and didn't notice the mistake later on. I still stand behind what I say about inference of generic types, and I still think interfaces should be used instead of concrete classes, though.
Comments (11)
final List<? extends Number> numbers = new ArrayList<? extends Number>(1, 2)Either way, I think the trick will be to ensure that the inferred type syntax does not break the 'statically typed' nature of the Java programming language. Edited by Avah to add generic formatting, hope this is what you meant...List, and not, to take an example of another top interface ofArrayList,RandomAccess? The same goes for generic types, too - it's just even more complex there, I think, because it might be? extends Tor? super T, according to some crazy logic.. :)