为什么一个匿名类不能访问它的封闭类的变量? [英] Why can't an anonymous class access variables of its enclosing class?

查看:115
本文介绍了为什么一个匿名类不能访问它的封闭类的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在阅读关于java中的匿名类,它说你可以访问封闭类的方法,而不是本地变量。为什么是这样的?我在说这个:

I'm reading about anonymous classes in java and it says you can access the methods of the enclosing class, but not the local variables. Why is it like this? I'm talking about this:

编辑:旧的例子不正确,不能反映我的意思。这应该是一个更好的例子,根据它在这里编写的部分访问封闭类的成员 http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

The older example was incorrect not reflecting what I meant. This should be a better example according with what its being written here in the section "Accessing members of enclosing class" 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
            }
        }
    }
}

这个限制解决了什么问题?

So what problem is this restriction solving?

推荐答案

这来自早期版本的Java内部类规范。

This comes from early version Java Inner Classes Specification.

官方规范网址,例如来自 VM spec 2.14 不适用于链接腐蚀: http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html

Official specification URL, referred eg from VM spec 2.14 is gone for link rot: http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html

1999年1月17日快照可以在回传机获得,相应的规格部分是引用本地变量

January 17, 1999 snapshot can be obtained at wayback machine though, respective spec section is References to local variables.

应该如何工作,描述如下(我标记最相关的语句粗体):

The way how things are supposed to work, is described as follows (I marked most relevant statement bold):


块可以访问局部变量。这使编译器的工作复杂化。以下是本地类的上一个示例:

A class definition which is local to a block may access local variables. This complicates the compiler's job. Here is the previous example of a local class:

    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();
    }


$ b $ p

为了让局部变量对内部类的方法可见,编译器必须将变量的值复制到内部类可以访问它的位置。对同一变量的引用可以在不同的地方使用不同的代码序列,只要在每个地方产生相同的值,以致名称在其范围的所有部分中始终表示相同的变量。

In order to make a local variable visible to a method of the inner class, the compiler must copy the variable's value into a place where the inner class can access it. References to the same variable may use different code sequences in different places, as long as the same value is produced everywhere, so that the name consistently appears to refer to the same variable in all parts of its scope.

按照惯例,数组的局部变量被复制到私有字段 val $ array 内部类。 (因为数组 final ,所以这些副本不会包含不一致的值。) ...

By convention, a local variable like array is copied into a private field val$array of the inner class. (Because array is final, such copies never contain inconsistent values.) ...

你看,语言设计者希望在每次创建这样的副本时,复制的局部变量的值都是一致的。他们的动机很可能是开发人员不必担心在内部类的副本之外查看 以检查其是否已在那里更改:

You see, language designers wanted value of copied local variable to be "consistent" every time such a copy is created. Their motivation was most likely that developers would need not worry to look outside of the copy of inner class to check whether it has been changed out there:

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






同名推理适用于匿名类:


Note although spec example uses named class, same reasoning applies to anonymous classes:

// ...
    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
    }

这篇关于为什么一个匿名类不能访问它的封闭类的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆