匿名内部类的构造器
2019-12-22 16:04:59来源:博客园 阅读 ()
匿名内部类的构造器
匿名内部类的构造器
来看一个例子:
class A{ public B f() { return new B() { { setName("annoyInner"); //非静态初始块,等同于构造方法 } //。。。 //可以自定义成员变量、成员方法 //可以重写父类方法 }; } public static void main(String[] args) { A a = new A(); System.out.println(a.f().getName()); } } class B{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public B() { System.out.println("B的无参构造"); } }
打印结果:
B的无参构造
annoyInner
在匿名类中,可用花括号括起来进行一些必要的初始化操作,表示非静态初始化块,等同于构造方法。由于没有方法名,此构造方法不区分有参无参,那么怎么在匿名构造方法中使用参数呢?
class A{ public B f() { String name = "annoyInner"; return new B() { { setName(name); //直接使用局部变量即可 } //。。。 //可以自定义成员变量、成员方法 //可以重写父类方法 }; } public static void main(String[] args) { A a = new A(); System.out.println(a.f().getName()); } } class B{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public B() { System.out.println("B的无参构造"); } }
打印结果同上。匿名类中直接使用局部变量或成员变量即可,相当于匿名类的有参构造器(Java 中局部内部类和匿名内部类访问的局部变量必须由 final 修饰,以保证内部类和外部类的数据一致性。但从 Java 8 开始,添加了 Effectively final 功能,我们可以不加 final 修饰符,由系统默认添加。详情可点击《Java8新特性之Effectively final》进行学习。)
接下来又有个问题,匿名类的构造器能不能重载呢?
答案是不能,还是因为匿名类没有名字,连赋予参数的地方都没有,但是你可以这样写:
class A{ public B f() { return new B() { { setName("annoyInner1"); } { setName("annoyInner2"); } { setName("annoyInner3"); } //... }; } public static void main(String[] args) { A a = new A(); System.out.println(a.f().getName()); } }
打印结果是annoyInner3,这相当于是多个初始化块,会依次执行,并不是构造器的重载,但是这样写跟写在一个初始化块中没有什么区别。
我们都知道匿名类实例化时会默认调用父类的无参构造,如何调用父类的有参构造?加上super(name)是不行的:
class A{ public B f() { return new B("annoyInner") { { //super(name); //编译报错 } }; } public static void main(String[] args) { A a = new A(); System.out.println(a.f().getName()); } } class B{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public B() { System.out.println("B的无参构造"); } public B(String name) { this.name = name; System.out.println("B的有参构造"); } }
打印结果如下,直接在匿名类的表达式中使用父类的有参构造即可
B的有参构造
annoyInner
下面是一个很常见的匿名类的运用,经常看见有人这么写:
ArrayList<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; Map m = new HashMap() { { put("name","zhangsan"); put("age",18); } };
看到这个,我只想说:
花里胡哨!!!
拿arrayList为例,外层的花括号创建了一个继承于ArrayList的匿名类,里层的花括号表示在这个匿名类的初始化块中调用了继承而来的add方法,实际上这个匿名类和ArrayList没有什么区别。这样写好像是简洁了一些,但是可读性也要差一些,也并不会带来多少性能上的优化,目前本人还不知道会不会引发什么问题。不过取决于个人喜好,用用也无妨。
原文链接:https://www.cnblogs.com/xiaohang123/p/12080429.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 构造函数中的this()和super() 2020-06-10
- Java连载120-反射机制获取构造方法和父类、父接口 2020-06-05
- HashMap:源代码(构造方法、put、resize、get、remove、rep 2020-06-04
- Java连载119-反编译类的某个方法已经构造方法 2020-06-01
- LeetCode 105. 从前序与中序遍历序列构造二叉树 2020-05-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash