据我所知,匿名内部类中的内部方法可以使用final varibles或class字段。 它们之间有显着差异吗? 例如:
final int[] intArr = new int[1];
Button testButton1 = (Button) findViewById(R.id.btnTest1);
testButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intArr[0]++;
Log.i("test", String.valueOf(intArr[0]));
}
});
Button testButton2 = (Button) findViewById(R.id.btnTest2);
testButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intArr[0]--;
Log.i("test", String.valueOf(intArr[0]));
}
});
我有2个按钮,它们都使用 intArr [0] ,可以获取并设置它的值。如果我将 intArr [0] 替换为某些类字段,例如 private int value; ,则会出现相同的行为 基于此,我得出结论,类字段和最终变量基本相同(我的意思是它们在字节码中表示相同)并且仅在范围和分配值的可能性方面存在差异。 我是对的吗?
答案 0 :(得分:2)
(我的意思是它们在字节码中表示相同)
让我们来看看。拿这个代码
class Example {
private static int[] outside = new int[]{1};
public static void main(String [] args){
final int[] inside = new int[]{2};
Object inner = new Object(){{
System.out.println(outside[0]);
System.out.println(inside[0]);
}};
}
}
将其编译为两个类,然后使用javap -c
对其进行反汇编以获取
class Example {
Example();
Code:
0: aload_0
1: invokespecial #2 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: newarray int
3: dup
4: iconst_0
5: iconst_2
6: iastore
7: astore_1
8: new #3 // class Example$1
11: dup
12: aload_1
13: invokespecial #4 // Method Example$1."<init>":([I)V
16: astore_2
17: return
static int[] access$000();
Code:
0: getstatic #1 // Field outside:[I
3: areturn
static {};
Code:
0: iconst_1
1: newarray int
3: dup
4: iconst_0
5: iconst_1
6: iastore
7: putstatic #1 // Field outside:[I
10: return
}
和
final class Example$1 {
final int[] val$inside;
Example$1(int[]);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field val$inside:[I
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
12: invokestatic #4 // Method Example.access$000:()[I
15: iconst_0
16: iaload
17: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
20: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_0
24: getfield #1 // Field val$inside:[I
27: iconst_0
28: iaload
29: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
32: return
}
我们看到变量inside
是作为类Example$1
内的字段创建的,而变量outside
是通过{{1}中自动生成的方法access$000
访问的}}。因此没有 - 它们在字节码中没有相同的表示。
答案 1 :(得分:1)
最终变量仍然是变量。不同之处在于您只能分配一次值。否则他们的行为相同。字段也可以是最终的(尽管它被称为常量),它的范围保持不变。
final
关键字也称为“修饰符”,因为它会修改成员的行为,而不是将其转换为其他内容。
请记住,您仍然可以更改最终变量指向的对象。在您的情况下,您可以修改数组,尽管变量是最终的。你不能做的是为你的变量分配另一个数组。
答案 2 :(得分:0)
final
指的是常量变量。你不能改变常量的值。但是你可以改变非最终成员变量的值
答案 3 :(得分:0)
外部类中的字段通过Outer.this
引用,实际上是final
本地字段。所以在某种程度上,并没有什么区别。显然,final
只对变量有意义,而不是它指向的对象。
想象一下,如果您将外部this
复制到封闭方法中的本地final
字段。
final Outer outer = this;
testButton1.setOnClickListener(new View.OnClickListener() {
outer
与匿名内部类中的Outer.this
行为相同。