Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have always wondered why Java does not do type inference given that the language is what it is, and its VM is very mature. Google's Go is an example of a language with excellent type inference and it reduces the amount of typing one has to do. Is there any special reason behind this feature not being a part of Java?

share|improve this question
3  
backwards compatibility rules in a language as old and popular as java –  ratchet freak Jan 18 '13 at 23:43
4  
@ratchetfreak Could type inference not be added in a backwards-compatible way? Older programs would just be providing more type information than necessary. –  Brian Marshall Jan 19 '13 at 0:15
1  
It may have some unintended effects when used with Type Erasure. docs.oracle.com/javase/tutorial/java/generics/… –  Zachary Yates Jan 19 '13 at 1:09
1  
Write a whole hell of a lot more code once. Create new problems by solving simple problems with extreme prejudice everywhere. –  Erik Reppen Jan 19 '13 at 3:35
2  
Note that Java 8 will bring a lot of type inference with its Lambda feature: you can write complex lambdas without mentioning any types and everything being inferred. –  Joachim Sauer Jan 19 '13 at 11:12

4 Answers 4

up vote 30 down vote accepted

Technically speaking, Java does have type inferencing when using generics. With a generic method like

public <T> T foo(T t) {
  return t;
}

The compiler will analyze and understand that when you write

// String
foo("bar");
// Integer
foo(new Integer(42));

A String is going to be returned for the first call and an Integer for the second call based on what was input as an argument. You will get the proper compile-time checking as a result. Additionally, in Java 7, one can get some additional type inferencing when instantiating generics like so

Map<String, String> foo = new HashMap<>();

Java is kind enough to fill in the blank angle brackets for us. Now why doesn't Java support type inferencing as a part of variable assignment? At one point, there was an RFE for type inferencing in variable declarations, but this was closed as "Will not fix" because

Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns. Second, the redundancy allows the programmer to declare the intended type, and thereby benefit from a cross check performed by the compiler.

The contributor who closed this also noted that it just feels "un-java-like", which I am one to agree with. Java's verbosity can be both a blessing and a curse, but it does make the language what it is.

Of course that particular RFE was not the end of that conversation. During Java 7, this feature was again considered, with some test implementations being created, including one by James Gosling himself. Again, this feature was ultimately shot down.

With the release of Java 8, we now get type inference as a part of lambdas as such:

List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));

The Java compiler is able to look at the method Collections#sort(List<T>, Comparator<? super T>) and then the interface of Comparator#compare(T o1, T o2) and determine that first and second should be a String thus allowing the programmer to forgo having to restate the type in the lambda expression.

share|improve this answer
1  
First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns - yes, if it's HashMap<String, Integer> map = foo.getMap() then I agree - in C# I typically don't use var in such cases, even though I could. But this argument does not hold water if it's HashMap<String, Integer> map = new HashMap<String, Integer>(). This is true redundancy and I see no benefit in having to write the type name twice. And how I would benefit here from a compiler cross check, I don't understand at all. –  Konrad Morawski Mar 19 at 15:10
1  
Yes and that's good for generics, but I still miss the equivalent of C#'s var in Java. –  Konrad Morawski Mar 19 at 15:25
1  
As for it being "un-java-like", this (cheesy) story comes to mind ;) 9gag.com/gag/2308699/-this-is-how-things-are-done-around-here –  Konrad Morawski Mar 19 at 15:27
2  
Further, the return type of a function is often either obvious or unnecessary, and even in cases where it is not your IDE can flag up the type in half a second. –  Phoshi Mar 19 at 15:27
1  
@GlennNelson of course, but so is C# (yes I'm biased, I prefer it over Java). I am not saying Java's design is accidental - that's a bit of a straw man argument on your part now :) Obviously it's a result of certain design choices, and these choices can be debated or questioned, why shouldn't they be. They're not just right or wrong, trade offs are involved. Things like verbosity are a matter of taste, mine may be different than yours and no amount of design experience can remove the subjectivity factor. Btw correct me if I'm wrong, but lambda expressions were once considered un-java-like, too –  Konrad Morawski Mar 22 at 20:10

Well, first off, type inference has nothing to do with the maturity of the runtime, whether that runtime is a 30 year old CPU or a VM that is so new the bits are still shiny. it's all about the compiler.

That said, it is allowed for generics, the reason why it's not allowed for non-generic types seems to be because of philosophy -- there's nothing preventing the designers from adding it.

share|improve this answer

As far as I know, when Java was designed at the beginning of the nineties type inference was not that popular among mainstream languages (but it was already a very well known concept, e.g. in ML). So, I can imagine that type inference was probably not supported because Java was aimed at programmers coming from C++, Pascal, or other mainstream languages that did not have it (principle of least surprise).

Also, one of the design principles of Java is to write things explicitly to make sure that the programmer and the compiler have the same understanding of the code: duplicating information reduces the chances of errors. Of course, it may be a matter of taste whether typing a few more characters is worth the extra safety it provides, but this was the design philosophy followed for Java: write things explicitly.

I do not know if Java will get type inference in the future but IMO that would be a big revolution for the language (as Glenn Nelson mentioned, it was described as "un-java-like") and then one might also consider dropping the name Java in favour of a new name.

If you want to use a JVM language with type inference you can use Scala.

share|improve this answer

I can think of a few possible reasons. One is that explicit typing is self-documenting. Java generally makes this a priority over concision. Another reason might be in cases where the type is somewhat ambiguous. Like when a type or any subtype might satisfy a routine. Let's say you want to use a List, but someone comes along and uses a method exclusive to ArrayList. The JIT would infer an ArrayList and carry on even if you wanted a compilation error.

share|improve this answer
3  
How does GridBagLayout gridbag = new GridBagLayout(); add to self documentation? Its pure repetition. –  Anders Lindén Dec 9 '13 at 22:54
2  
It disambiguates from a case where the two types are not the same. You could just as easily assign an instance of a subclass. –  jiggy Dec 10 '13 at 23:25
    
Let's say you want to use a List, but someone comes along and uses a method exclusive to ArrayList. The JIT would infer an ArrayList and carry on even if you wanted a compilation error - I don't understand this bit. Type inference takes place at the moment of instatiating a variable, not calling a method on it. Could you perhaps show an example of what you meant? –  Konrad Morawski Mar 19 at 15:13
    
@KonradMorawski: I assume he means that if a method returns ArrayList, the type will be inferred to that. If you want to treat a type as something other than the return type, you can't use inference. I don't understand how this could ever be a problem in a codebase anywhere near sane, though. –  Phoshi Mar 19 at 15:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.