繁体   English   中英

为什么允许从静态对象进行非静态引用?

[英]Why is it allowed to make a non-static reference from static object?

这是一个例子:

public class Test extends Activity {

    Button button;
    public int i;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                i = 10; // How can this be possible?
            }
        });
    }
}

那不是静态对象。 这就是为什么有可能的原因。

  • 匿名(内部)类(在这种情况下为new View.OnClickListener() )不是静态的,它们是非静态的内部类。

  • 非静态内部类与包含其创建内部类的外部类(在本例中为Test )的实例具有隐式关系。 它像内部类一样具有隐含的ivar,它指向外部类的相关实例。

  • 内部类可以访问实例变量,像i通过该关系,其外部类的。

静态对象在哪里? 您拥有的是一个匿名内部类,但是当您使用new关键字调用构造函数时,您在其中实例化了它。

 i = 10; // How can this be possible?

i是班级成员,可以通过班级方法访问您的代码,

您期望什么?

这里没有可见的静态物体。 您有一个匿名内部类的实例( View.OnClickListener ),但是没有静态对象。

编辑:我想知道您是否将static变量与局部( 成员) final变量混淆了。 这与静态变量没有直接关系,但是我可以看到(自我描述的)新手如何使它们困惑。

任何在内部类中使用但未声明的局部变量,形式方法参数或异常处理程序参数都必须声明为final ,并且必须在内部类主体之前进行明确分配。

修改你的榜样,下面是不是允许的情况下:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        int i = 0; // This is non-final; access to it from an inner class is not allowed.
        button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                i = 10; // Compiler error
            }
        });
    }

这里还有另一种不允许的:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final int i = 0; // This is final; read-only access to it from an inner class is allowed.
        button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                i = 10; // Compiler error -- can't modify a final variable.
            }
        });
    }

但这允许的:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final int i = 0; // This is final; read-only access to it from an inner class is allowed.
        button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                int j = i; // OK
            }
        });
    }

对此进行解释:可能是因为您正在创建的View.OnClickListener类型的(匿名)类不是静态的,因此对它的外部类保留了隐藏的引用。 话虽如此:

        @Override
        public void onClick(View v) {
            i = 10;
        }

等效于:

        @Override
        public void onClick(View v) {
            Test.this.i = 10;
        }

那有意义吗?

我认为混淆来自于OnClickListenerView限定的事实。 它实际上不是static 以下是等效的:

import android.view.View;
...
button.setOnClickListener(new View.OnClickListener() {

import android.view.View;
import android.view.View.OnClickListener;
...
button.setOnClickListener(new OnClickListener() {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM