20

I have installed the last JDK 8 ea b114 to test the new language features. However the inference in chained calls seems not to work yet.

If I write:

Iterator<String> it = new ArrayList<>().iterator(); 

the compiler give me an error.

However inference in argument position works well.

Maybe inference in chained calls will not be inserted?

3
  • You answered your own question there at the end.. Commented Nov 12, 2013 at 16:17
  • That's strange, I could have sworn that pretty much this situation is what got improved a lot ... Commented Nov 12, 2013 at 16:20
  • @JoachimSauer Inference has been thoroughly improved. Method invocations and constructor invocations are now inferred as a whole with the exception of the method receiver. (Btw, I still remember you from the sun forums. Took me a while to figure that out. :D) Commented Nov 12, 2013 at 17:26

2 Answers 2

17

As @Holger said, Java 8 improved contextual inference so that this works_

public static <T> Iterator<T> iter(Iterable<T> i) { return i.iterator(); } public static void main(String[] args) { Iterator<String> it = iter( new ArrayList<>() ); \____________________________/ } 

It didn't work in Java 7 — the inference on new ArrayList<>() could not depend on context.


It'll be a huge change to the language to do what you want in the question. John Rose started a similar discussion, see http://mail.openjdk.java.net/pipermail/lambda-dev/2013-July/010531.html


Too much inference and too much contextual dependency can be a bad thing. It's not so much that the compiler cannot handle the complexity - it can. It's about whether human programmers can handle it. I am sensing that Java 8 is already at a dangerous level that the codes will be difficult for humans to parse.

Sign up to request clarification or add additional context in comments.

3 Comments

Well, I see that there are corner case like the example in that mailing list where type inference might influence which of overloaded methods to choose. But I really wish that they implement type inference for the 99% of all cases where no overloaded methods exist (like in the iterator() example) and forbid it for overloaded methods only, instead of rejecting all cases just because of these 1% (or less) corner cases.
"I am sensing that Java8 is already at a dangerous level that the codes will be difficult for humans to parse." Features of IDEs like method-signature-on-hover (with the inferred generic type information shown) make it a lot easier to parse such things.
Iterator<Integer> a=new ArrayList<>().iterator(); , is getting me compile error in Java 8 though.
13

The latest specification (Public Review) is available at jcp.org. There is a paragraph in part D which discusses this point.

The receiver in a method invocation, field access, etc. (exp.foo()) is not a poly expression because the target type is unknown—it would be impossible to enumerate every type that has a particular member (foo, in this case). There has been some interest in allowing inference to "chain": in a().b(), passing type information from the invocation of b to the invocation of a. This adds another dimension to the complexity of the inference algorithm, as partial information has to pass in both directions; it only works when the erasure of the return type of a() is fixed for all instantiations (e.g. List). This feature would not fit very well into the poly expression model, since the target type cannot be easily derived.

8 Comments

Sounds like they want to force us again to add obsolete helper methods to our code just to make the compiler happy… :-(
@Holger All I can say is that it's a very hard problem. The guys working on the specification and implementation are a smart bunch. They write Java code too and I trust they'd want that to be as pleasant as possible. So they made it less pleasant than imaginable then I doubt it was for lack of trying.
I have no doubt they are smart and working hard. Still I don’t get why things which can be solved with a generic wrapper method following the always-same pattern ought to be any formal problem. And by the way, the fact that the Java 5 requirement of repeating every type parameter when creating an instance has been removed in Java 7 proves that there never was a real need for it. The logic behind it didn’t change between Java 5 and Java 7. So they didn’t try (enough) before. So maybe Java 10 will prove that the reason behind the Java 8 restriction never was an issue?
@Holger Those two are at different levels of difficulty. Constructor is kind of like static method in terms of inference; it's more like an oversight in java5 not to do inference on constructors. Chained method call is a completely different animal.
some related discussions started by john rose - mail.openjdk.java.net/pipermail/lambda-dev/2013-July/…
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.