java 匿名初始化_Java:匿名类的初始化和构造函数

我想了解一个我在处理匿名课程时遇到的奇怪行为.

我有一个类在其构造函数中调用受保护的方法(我知道,设计很差,但这是另一个故事…)

public class A {

public A() {

init();

}

protected void init() {}

}

然后我有另一个扩展A的类并重写init().

public class B extends A {

int value;

public B(int i) {

value = i;

}

protected void init() {

System.out.println("value="+value);

}

}

如果我编码

B b = new B(10);

我明白了

> value=0

这是预期的,因为超级类的构造函数在B ctor之前被调用,然后值仍然是.

但是在使用像这样的匿名类时

class C {

public static void main (String[] args) {

final int avalue = Integer.parsetInt(args[0]);

A a = new A() {

void init() { System.out.println("value="+avalue); }

}

}

}

我希望得到值= 0因为它应该或多或少等于B类:编译器自动创建一个新的类C $1,它扩展A并创建实例变量来存储匿名类的方法中引用的局部变量,模拟关闭等……

但是当你运行这个时,我得到了

> java -cp . C 42

> value=42

最初我认为这是因为我使用的是java 8,并且可能在引入lamdbas时,他们改变了匿名类在引擎盖下的实现方式(你不再需要最终版),但我尝试使用java 7也得到了相同的结果……

实际上,用javap查看字节码,我可以看到B是

> javap -c B

Compiled from "B.java"

public class B extends A {

int value;

public B(int);

Code:

0: aload_0

1: invokespecial #1 // Method A."":()V

4: aload_0

5: iload_1

6: putfield #2 // Field value:I

9: return

...

而对于1加元:

> javap -c C\$1

Compiled from "C.java"

final class C$1 extends A {

final int val$v;

C$1(int);

Code:

0: aload_0

1: iload_1

2: putfield #1 // Field val$v:I

5: aload_0

6: invokespecial #2 // Method A."":()V

9: return

....

有人能告诉我为什么会有这种差异吗

有没有办法使用“普通”类复制匿名类的行为?

编辑:

澄清问题:为什么匿名类的初始化会破坏初始化任何其他类的规则(在设置任何其他变量之前调用超级构造函数)?

或者,有没有办法在inovking超级构造函数之前在B类中设置实例变量?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值