为什么这段代码在 Java 1.6 中编译,但在 Java 1.7 中却没有?
以下代码在 Java 1.6 中编译良好,但在 Java 1.7 中无法编译。为什么?
代码的相关部分是对私有“数据”字段的引用。引用来自定义字段的同一类中,因此似乎是合法的。但它是通过一个通用类型的变量发生的。这段代码 -一个基于内部库中的类的精简示例 - 在 Java 1.6 中工作,但现在在 Java 1.7 中不起作用。
我不是在问如何解决这个问题。我已经这样做了。我试图找到一个解释为什么这不再起作用的解释。我想到了三种可能性:
- 根据JLS,此代码是不合法的,并且不应该编译(1.6编译器中存在错误,在1.7中修复)
- 根据JLS,此代码是合法的,应该编译(1.7编译器中引入了向后兼容性错误)
- 此代码在 JLS 中属于灰色区域
傅.java:
import java.util.TreeMap;
import java.util.Map;
public abstract class Foo<V extends Foo<V>> {
private final Map<String,Object> data = new TreeMap<String,Object>();
protected Foo() { ; }
// Subclasses should implement this as 'return this;'
public abstract V getThis();
// Subclasses should implement this as 'return new SubclassOfFoo();'
public abstract V getEmpty();
// ... more methods here ...
public V copy() {
V x = getEmpty();
x.data.clear(); // Won't compile in Java 1.7
x.data.putAll(data); // "
return x;
}
}
编译器输出:
> c:\tools\jdk1.6.0_11\bin\javac -version
javac 1.6.0_11
> c:\tools\jdk1.6.0_11\bin\javac c:\temp\Foo.java
> c:\tools\jdk1.7.0_10\bin\javac -version
javac 1.7.0_10
> c:\tools\jdk1.7.0_10\bin\javac c:\temp\Foo.java
Foo.java:18: error: data has private access in Foo
x.data.clear();
^
Foo.java:19: error: data has private access in Foo
x.data.putAll(data);
^
2 errors
补遗。如果引用是私有方法而不是私有成员变量,也会出现同样的问题。这在Java 1.6中有效,但在1.7中不起作用。
Foo2.java:
import java.util.TreeMap;
import java.util.Map;
public abstract class Foo2<V extends Foo2<V>> {
private final Map<String,Object> data = new TreeMap<String,Object>();
protected Foo2() { ; }
// Subclasses should implement this as 'return this;'
public abstract V getThis();
// Subclasses should implement this as 'return new SubclassOfFoo();'
public abstract V getEmpty();
// ... more methods here ...
public V copy() {
V x = getEmpty();
x.theData().clear(); // Won't compile in Java 1.7
x.theData().putAll(data); // "
return x;
}
private Map<String,Object> theData() {
return data;
}
}
编译器输出:
> c:\tools\jdk1.6.0_11\bin\javac c:\temp\Foo2.java
> c:\tools\jdk1.7.0_10\bin\javac c:\temp\Foo2.java
Foo2.java:18: error: theData() has private access in Foo2
x.theData().clear();
^
Foo2.java:19: error: theData() has private access in Foo2
x.theData().putAll(data);
^