以下代码在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
Foo.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);
^
我建议反编译生成的两个类文件,然后区别应该是显而易见的。 – Landei
@Landei在1.7的情况下没有生成类文件,因为编译器拒绝编译它。 –