在 java 7 中编译的代码在 Java 8 中无法编译。请提供解释

Code that compiles in java 7 does not compile in Java 8. Please provide an explanation

为什么下面的代码编译不通过Java 8. 我知道类型推断是这里的罪魁祸首,但我想得到一个解释。

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> {
     }
}

明确引用 Holger 的正确评论:

在 JLS 8 中,这是在 §18.5.2 中确定的,其中包含这句话(在第 6 个主要项目符号内):

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.

我突出显示了相关部分。

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.

两个版本都定义了使用原始类型参数(需要未经检查的转换)调用 find(..) 具有通过擦除声明的 return 获得的 return 类型输入 EB.

如果 Java 7 的编译器没有报告这个错误,那么这是一个错误。