Adr*_*rez 18 java closures class
我正在阅读java中的匿名类,它说你可以访问封闭类的方法,但不能访问局部变量.为什么会这样?我在说这个:
编辑:旧的例子是错误的不反映我的意思.这应该是一个更好的例子,根据它在"访问封闭类的成员"部分http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html中所写的内容.
public class MyClass {
public interface SomeInterface{
public void someOtherMethod();
}
public void someMethod(int someLocalVar) {
SomeInterface myClass = new SomeInterface(){
public void someOtherMethod(){
someLocalVar = 0; // This must be final to work
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么这个限制解决有什么问题呢?
gna*_*nat 15
这来自早期版本的Java内部类规范.
官方规范URL,例如来自VM spec 2.14的链接腐烂消失:http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html
1999年1月17日快照可以在回程机器上获得,相应的规格部分是对局部变量的引用.
事物应该如何工作的方式描述如下(我标记了最相关的声明粗体):
块的本地类定义可以访问局部变量.这使编译器的工作变得复杂.这是本地类的前一个示例:
Run Code Online (Sandbox Code Playgroud)Enumeration myEnumerate(final Object array[]) { class E implements Enumeration { int count = 0; public boolean hasMoreElements() { return count < array.length; } public Object nextElement() { { return array[count++]; } } return new E(); }为了使局部变量对内部类的方法可见,编译器必须将变量的值复制到内部类可以访问它的位置.对同一变量的引用可以在不同的地方使用不同的代码序列,只要在任何地方产生相同的值,使得名称始终在其范围的所有部分中引用相同的变量.
按照惯例,将局部变量like
array复制到val$array内部类的私有字段中.(由于array是final,这样的副本不会包含值不一致.) ...
你知道,语言设计者希望每次创建这样的副本时,复制的局部变量的值都是"一致的".他们的动机很可能是开发人员不必担心在内部类的副本之外查看它是否已被更改:
Enumeration myEnumerate(Object array[], int copy) { // array not final, let's see...
for (int i = 0, i < 2; i++ ) { // loop to have several copies
class E implements Enumeration {
int count = 0;
public boolean hasMoreElements()
{ return count < array.length; }
public Object nextElement() {
{ return array[count++]; }
} // we hope to be done with E... oh no
array = null; // not final => can change
if (i == copy) {
return new E(); // we need to look outside of E
// to figure value of array it uses
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
注意虽然spec示例使用命名类,但同样的推理适用于匿名类:
// ...
for (int i = 0, i < 2; i++ ) { // loop to have several copies
if (i == copy) {
return new Enumeration() {
int count = 0;
public boolean hasMoreElements()
{ return count < array.length; }
public Object nextElement() {
{ return array[count++]; }
} // we hope to be done... oh no
}
array = null; // not final => can change
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*ick 11
内部类可以访问final封闭类的变量.
这是一个有趣的备忘录:
实际上,原型实现确实允许从内部类中引用非final变量.用户强烈抗议,抱怨说他们不想要这个!原因很有趣:为了支持这些变量,有必要对它们进行堆分配,并且(至少在那个时候),普通的Java程序员对堆分配和垃圾收集仍然相当不安.当没有出现"new"关键字时,他们不赞成在"桌面下"执行堆分配的语言.
| 归档时间: |
|
| 查看次数: |
4080 次 |
| 最近记录: |