java 内部类 构造函数_匿名内部类的构造器

匿名内部类的构造器

来看一个例子:

classA{publicB f() {return newB() {

{

setName("annoyInner"); //非静态初始块,等同于构造方法

}//。。。//可以自定义成员变量、成员方法//可以重写父类方法

};

}public static voidmain(String[] args) {

A a= newA();

System.out.println(a.f().getName());

}

}classB{privateString name;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicB() {

System.out.println("B的无参构造");

}

}

打印结果:

B的无参构造

annoyInner

在匿名类中,可用花括号括起来进行一些必要的初始化操作,表示非静态初始化块,等同于构造方法。由于没有方法名,此构造方法不区分有参无参,那么怎么在匿名构造方法中使用参数呢?

classA{publicB f() {

String name= "annoyInner";return newB() {

{

setName(name); //直接使用局部变量即可

}//。。。//可以自定义成员变量、成员方法//可以重写父类方法

};

}public static voidmain(String[] args) {

A a= newA();

System.out.println(a.f().getName());

}

}classB{privateString name;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicB() {

System.out.println("B的无参构造");

}

}

打印结果同上。匿名类中直接使用局部变量或成员变量即可,相当于匿名类的有参构造器(Java 中局部内部类和匿名内部类访问的局部变量必须由 final 修饰,以保证内部类和外部类的数据一致性。但从 Java 8 开始,添加了 Effectively final 功能,我们可以不加 final 修饰符,由系统默认添加。

接下来又有个问题,匿名类的构造器能不能重载呢?

答案是不能,还是因为匿名类没有名字,连赋予参数的地方都没有,但是你可以这样写:

classA{publicB f() {return newB() {

{

setName("annoyInner1");

}

{

setName("annoyInner2");

}

{

setName("annoyInner3");

}//...

};

}public static voidmain(String[] args) {

A a= newA();

System.out.println(a.f().getName());

}

}

打印结果是annoyInner3,这相当于是多个初始化块,会依次执行,并不是构造器的重载,但是这样写跟写在一个初始化块中没有什么区别。

我们都知道匿名类实例化时会默认调用父类的无参构造,如何调用父类的有参构造?加上super(name)是不行的:

classA{publicB f() {return new B("annoyInner") {

{//super(name);//编译报错

}

};

}public static voidmain(String[] args) {

A a= newA();

System.out.println(a.f().getName());

}

}classB{privateString name;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicB() {

System.out.println("B的无参构造");

}publicB(String name) {this.name =name;

System.out.println("B的有参构造");

}

}

打印结果如下,直接在匿名类的表达式中使用父类的有参构造即可

B的有参构造

annoyInner

下面是一个很常见的匿名类的运用,经常看见有人这么写:

ArrayList list = new ArrayList() {{

add("A");

add("B");

add("C");

}};

Map m= newHashMap() {

{

put("name","zhangsan");

put("age",18);

}

};

看到这个,我只想说:

花里胡哨!!!

拿arrayList为例,外层的花括号创建了一个继承于ArrayList的匿名类,里层的花括号表示在这个匿名类的初始化块中调用了继承而来的add方法,实际上这个匿名类和ArrayList没有什么区别。这样写好像是简洁了一些,但是可读性也要差一些,也并不会带来多少性能上的优化,目前本人还不知道会不会引发什么问题。不过取决于个人喜好,用用也无妨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值