Java 为什么允许从静态对象进行非静态引用?
以下是一个例子:Java 为什么允许从静态对象进行非静态引用?,java,android,Java,Android,以下是一个例子: 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);
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关键字调用构造函数时,您在它的实例中创建了它
i = 10; // How can this be possible?
i
是类成员,可以通过类方法访问您的代码
你期待什么?这里看不到静态物体。您有一个匿名内部类的实例(视图
OnClickListener
),但没有静态对象
编辑:我想知道您是否混淆了静态变量和。这与静态变量没有直接关系,但我可以看出(自我描述的)新手可能会把它们弄糊涂
任何局部变量,形式化方法
参数或异常处理程序
已使用但未在中声明的参数
内部类必须声明为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
}
});
}
这是另一个不允许的:
@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
}
});
}
但这是允许的:
@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
}
});
}
- 匿名(内部)类(
new View.OnClickListener()
在本例中)不是静态的,它们是非静态的内部类
- 非静态内部类与创建内部类所通过的包含外部类(
Test
)的实例具有隐含关系。它与内部类类似,具有指向外部类的相关实例的隐含ivar
- 内部类可以通过这种关系访问外部类的IVAR,如
i
对此的解释:这是可能的,因为您正在创建的View.OnClickListener
类型的(匿名)类不是静态的,因此保留了对其外部类的隐藏引用。也就是说:
@Override
public void onClick(View v) {
i = 10;
}
相当于:
@Override
public void onClick(View v) {
Test.this.i = 10;
}
这有意义吗?我认为混淆是因为OnClickListener
是由视图限定的。它实际上不是静态的。以下是等效的:
import android.view.View;
...
button.setOnClickListener(new View.OnClickListener() {
及
你凭什么认为那是一个静止的物体编辑:如果这是斯尼皮说的,我道歉。我真的在要求澄清。您认为什么是静态的,为什么会这样认为?如果是静态的,您的意思是它不可访问,是吗?@org.life.java:静态内部类不能访问它定义的类的非静态字段,因为它与该类的特定实例没有关联。这就是你要问的吗?@ColinD我知道,但是Cristian的意思是它不能访问静态数据fields@org.life.java当前位置我看不出他说的话有任何暗示。