问题描述
在方法中给出以下内部类(IsSomething):
Given the following inner class (IsSomething) within a method:
public class InnerMethod {
private int x;
public class Something {
private int y;
public void printMyNumber(double x)
{
class IsSomething extends Something {
public void print() {
System.out.println(x);
}
}
}
}
}
为什么X变量必须是FINAL才能使它工作..?
(我说的是关于printMyNumber函数的X参数。)
Why does the X variable has to be FINAL to make it work..?(I'm talking ofc about the X parameter of the "printMyNumber" function.)
推荐答案
区别在于局部变量与类成员变量之间的关系。成员变量在封闭对象的生命周期中存在,因此它可以由内部类实例引用。但是,局部变量仅在方法调用期间存在,并且由编译器以不同方式处理,因为它的隐式副本是作为内部类的成员生成的。在没有声明局部变量final的情况下,可以更改它,导致细微的错误,因为内部类仍然引用该变量的原始值。
The difference is between local variables vs class member variables. A member variable exists during the lifetime of the enclosing object, so it can be referenced by the inner class instance. A local variable, however, exists only during the method invocation, and is handled differently by the compiler, in that an implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.
当我们想要访问本地时,第二个原因出现了内部类中的变量或
参数。这是实际的原因,正如我所知,
,最终的局部变量和参数是在JDK 1.1中引入Java语言的
。
The second reason comes in when we want to access a local variable or parameter from within an inner class. This is the actual reason, as far as I know, that final local variables and parameters were introduced into the Java language in JDK 1.1.
public class Access1 {
public void f() {
final int i = 3;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(i);
}
};
}
}
在run()方法中我们只能访问i如果我们把它放在外层的最后。要理解推理,我们必须
Inside the run() method we can only access i if we make it final in the outer class. To understand the reasoning, we have to
public class Access1 {
public Access1() {}
public void f() {
Access1$1 access1$1 = new Access1$1(this);
}
}
和
class Access1$1 implements Runnable {
Access1$1(Access1 access1) {
this$0 = access1;
}
public void run() {
System.out.println(3);
}
private final Access1 this$0;
}
由于i的值是final,编译器可以内联到内部
Since the value of i is final, the compiler can "inline" it into the inner
当局部变量的值可以为内部类的不同
实例进行更改,编译器将其作为内部类的
的数据成员添加,并允许它在构造函数中初始化。这背后的
背后的原因是Java没有指针,即C的
方式。
When the value of the local variable can change for different instances of the inner class, the compiler adds it as a data member of the inner class and lets it be initialised in the constructor. The underlying reason behind this is that Java does not have pointers, the way that C has.
考虑以下类:
public class Access2 {
public void f() {
for (int i=0; i<10; i++) {
final int value = i;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(value);
}
};
}
}
}
这里的问题是我们每次我们进行for循环时都必须创建一个新的本地数据成员,所以我今天想到了
The problem here is that we have to make a new local data member each time we go through the for loop, so a thought I had today
public class Access3 {
public void f() {
Runnable[] runners = new Runnable[10];
for (final int[] i={0}; i[0]<runners.length; i[0]++) {
runners[i[0]] = new Runnable() {
private int counter = i[0];
public void run() {
System.out.println(counter);
}
};
}
for (int i=0; i<runners.length; i++)
runners[i].run();
}
public static void main(String[] args) {
new Access3().f();
}
}
我们现在不需要申报额外的决赛局部变量。事实上,是不是真的
We now don't have to declare an additional final local variable. In fact, is it not perhaps true that
这篇关于在方法中声明类 - 最终关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!