Java8不兼容类型

Java8不兼容类型,java,java-8,java-7,compatibility,javac,Java,Java 8,Java 7,Compatibility,Javac,下面是简单的代码 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class SimpleTest { public static void main(String[] args) { final ArrayList<Map<String, Object>> maps = ne

下面是简单的代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SimpleTest {

    public static void main(String[] args) {
    final ArrayList<Map<String, Object>> maps = newArrayList(
        createMap("1", "a", Collections.EMPTY_MAP, Collections.EMPTY_MAP),
        createMap("2", "b", Collections.EMPTY_MAP, Collections.EMPTY_MAP),
        createMap("3", "c", Collections.EMPTY_MAP, Collections.EMPTY_MAP)
    ); 

    System.out.println(" maps = " + maps);
    }

    public static Map<String, Object> createMap(String value1, String value2, Map<String, Object> object1, Map<String, Object> object2) {
       Map<String, Object> map = new HashMap<>();
       map.put("value1", value1);
       map.put("value1", value1);
       map.put("object1", object1);
       map.put("object2", object2);
       return map;
    }    

    public static <E> ArrayList<E> newArrayList(E... elements) {
    ArrayList<E> list = new ArrayList<E>(elements.length);
    Collections.addAll(list, elements);
    return list;
    }
}
当我使用
-source 1.8
或no
-source
选项时,一切正常。现在,当JAVA_HOME指向JDK 7时,无论我是否使用
-source 1.7
,代码都会编译

最初,这个问题是关于一个软件,其中POM文件的
设置为
1.7
,构建在JDK 8上失败,但在JDK 7上没有问题


现在来问一个问题——是什么导致了这种情况的发生?在我看来,这是一种重大的疏忽。为什么在jdk8上编译
source
设置为
1.7
时失败

您可以将代码简化为不需要第三方库的自包含示例:

public class Test2 {
    @SafeVarargs
    static <T> ArrayList<T> newArrayList(T... arg) {
        return new ArrayList<T>(Arrays.asList(arg));
    }
    private final List<Map<String, Object>> maps = newArrayList(
        createMap(null, Collections.EMPTY_MAP)
     );

    public static Map<String, Object> createMap(String id, Map<String,String> m) {
        return null;
    }
}
使之成为一种通用方法。然后,jdk1.7将产生相同的错误。但引用的规则适用于所有方法调用



相反,使用Java 8 compliance编译它成功的事实源于新的目标类型推断,它具有完全不同的规则。

那么,你是说这段代码使用JDK 7编译,而不使用JDK 8编译吗?是的,正是这样。更重要的是,Maven中的编译器设置在这两种情况下都设置为1.7,请明确定义我们在这里比较的内容。您是使用JDK 8编译器还是JDK 7编译器编译?或者您是使用源代码为1.8的JDK 8编译器进行编译,还是使用源代码为1.7的JDK 7编译器进行编译?另外,您发布的代码没有
java.util.ArrayList
(使用原始类型),因此我不确定您是如何得到该错误的。在源代码设置为1.8的JDK 8上对我有效,但在源代码设置为1.7(相同JDK)时给出了完全相同的错误。这里是NetBeans 8.0.2。@Tunaki:番石榴在这里是不相关的。这个例子可以简化为在没有任何第三方库的情况下重现问题。我想,我在你发布答案时编辑了这个问题,并给出了建议。剩下的一个问题是为什么
-source 1.8
让JDK 8编译器编译它?没错,我在提交答案后看到了编辑。但是最后一句话总结了它,Java8规则是完全不同的。
newArrayList
调用的通用签名是从目标类型派生的。请注意,当您将调用更改为
Test2.newArrayList(…)
时,它也将在Java7中正常工作,尽管它在Java8中的工作方式仍存在一些细微的差异。完全解释Java8规则将超出回答的范围。解释了一些差异。感谢您对该答案的引用。
public class Test2 {
    @SafeVarargs
    static <T> ArrayList<T> newArrayList(T... arg) {
        return new ArrayList<T>(Arrays.asList(arg));
    }
    private final List<Map<String, Object>> maps = newArrayList(
        createMap(null, Collections.EMPTY_MAP)
     );

    public static Map<String, Object> createMap(String id, Map<String,String> m) {
        return null;
    }
}
public static <T> Map<String, Object> createMap(String id, Map<String,String> m)