0

Why does the following code do not compile in Java 8. I know type inference is the culprit here, But I would like to have an explanation.

public class TypeInferenceProblem {

    class ATest<E extends B>
    {

        private E find(C<? extends E> CObj)
        {
            return null;
        }

        public void findCs(List<? extends C<? extends E>> cList)
        {

            find(new C());// This compiles fine
            for (C cObj : cList)
                {
                    E cachedEntity = find(cObj); // This cause error in java 8 but works fine in java 7
                }
        }
    }

     class B{
     }

     class C <T> {
     }
}
Jerin Joseph
  • 759
  • 1
  • 7
  • 22
  • I get the same error in Java 7 as Java 8. See for yourself: [Java 8 exploding](https://ideone.com/u10I2y), and [Java 7 exploding](https://ideone.com/k86kSz) – Bohemian Nov 25 '16 at 08:59
  • Why do you call that class `LambdaTypeInferenceProblem` when there are no lambdas involved (and can’t, in supposed to be Java 7 code)? – Holger Nov 25 '16 at 09:18
  • @Bohemian: this is not a prove. It has been noticed before, that Ideone always uses the Java 8 compiler, even when it claims to use Java 7. You can even use lambda expressions there. – Holger Nov 25 '16 at 09:27
  • 1
    When you pass the [*raw type*](http://stackoverflow.com/q/2770321/2711488) `C` to `find`, you are basically disabling generics, thus, can’t expect `E` to be returned. I think, this *should* have been rejected by previous versions as well and it’s a bug that it wasn’t. – Holger Nov 25 '16 at 09:47
  • @Bohemian: See [lambda expression in Java 7](https://ideone.com/b9Hrj5)… – Holger Nov 25 '16 at 09:49
  • @Holger I named it LambdaTypeInferenceProblem as the issue occurs only in java 8 and there was change in compiler for type inference. – Jerin Joseph Nov 25 '16 at 09:55
  • The changes in the type inference are much broader. And only partly related to lambda expressions. – Holger Nov 25 '16 at 09:57
  • @Holger - I totally agree to that. :) And are you sure that if I pass in a type without generics into a function then we can return another type from that function. – Jerin Joseph Nov 25 '16 at 09:59
  • @Holger _When you pass the raw type C to find, you are basically disabling generics, thus, can’t expect E to be returned._ the above comment was regarding this comment. Can i actually return another type from the function. If not then what problem is the compiler trying to solve by this new error. – Jerin Joseph Nov 25 '16 at 10:02
  • But what is the question? – Holger Nov 25 '16 at 10:03

1 Answers1

1

Just to give definite references to Holger's correct comments:

In JLS 8 this is determinged in §18.5.2, which contains this sentence (inside the 6th major bullet):

If unchecked conversion was necessary for the method to be applicable during constraint set reduction in §18.5.1, then the parameter types of the invocation type of m are obtained by applying θ' to the parameter types of m's type, and the return type and thrown types of the invocation type of m are given by the erasure of the return type and thrown types of m's type.

I highlighted the relevant piece.

A similar sentence was already present in JLS 7 §15.12.2.6:

Otherwise, if unchecked conversion was necessary for the method to be applicable, then the result type is the erasure (§4.6) of the method's declared return type.

Both versions amount to defining that an invocation of find(..) with a raw type argument (which requires unchecked conversion) has a return type that is obtained by erasing the declared return type E to B.

If compilers for Java 7 did not report this error, then this was a bug.

Stephan Herrmann
  • 7,963
  • 2
  • 27
  • 38
  • I found a discussion mentioning a javac bug in this area: https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643#c31 and downwards. Further down you see that ecj was changed "to align with javac behavior" (despite the known bug). The javac bug has never been resolved, just the new inference in Java 8 bypassed the issue. Not sure though, if it's the same issue as in this question. – Stephan Herrmann Nov 26 '16 at 12:36
  • Thank you :) That explains it – Jerin Joseph Nov 28 '16 at 06:23