浅谈java内部类( 三 )


【注意】所谓的不同步主要是针对基本类型来说的,如果是对象之类的话因为拷贝的是引用所以仍然可以“同步”
如何突破必须用final的限制我们上面说到,局部内部类所使用的方法形参必须用final修饰的限制 。
例如
public void outterPrint (String data) {// 没加上finalclass LocalInner {public void changeData () {data = https://www.isolves.com/it/cxkf/yy/JAVA/2022-10-27/"我想修改data的值";// 在这一行编译报错}} }复制
提示:
Cannot refer to a non-final variable data inside an inner class defined in a different method复制
那么,如果我们有对该形参必须能修改的硬性需求怎么办?
你可以通过一种有趣的方式绕开它:使用一个单元素数组 。因为用final修饰的基本类型的变量不允许修改值,但是却允许修改final修饰的单元素数组里的数组元素, 因为存放数组的变量的值只是一个引用,我们修改数组元素的时候是不会修改引用指向的地址的,在这点上final并不会妨碍我们:
Outter.java
public class Outter {public void outterPrint (final String []data) {class LocalInner {public void innerPrint () {data[0] = "堂而皇之地修改它!!";// 修改数据System.out.print(data[0]);// 输出修改后的数据}}LocalInner i = new LocalInner();i.innerPrint();}}复制
Test.java:
public class Test {public static void main (String [] args) {Outter o = new Outter();String [] data = https://www.isolves.com/it/cxkf/yy/JAVA/2022-10-27/new String [1];data[0] = "我是数据";o.outterPrint(data);// 修改数据并且输出}}复制
结果输出:
堂而皇之地修改它!!复制
【注意】局部类不能用public或private访问符进行声明!!
匿名内部类倘若我们再把局部内部类再深化一下, 那就是匿名内部类
匿名内部类的使用方式new [超类/接口] {/* 类体 */}复制
让我们看看下面这个例子:
Other.java:
public class Other {}复制
Outter.java:
public class Outter {public void outterPrint (String data) {Other o = new Other() {}; // 匿名内部类}}复制
何谓之匿名?“诶,不是说好的匿名吗? 那么为什么还有个Other的类名呢?”
Other o = new Other() {/* 匿名内部类的类体 */};复制
实际上,这里的Other并不是我们的匿名内部类,而是我们匿名内部类的超类,上面一行代码其实相当于(用成员内部类来表示的话)
// annoymous翻译为匿名public class Outter {private class annoymous extends Other{}public void outterPrint () {Other a = new annoymous();}}复制
同时要注意,我们在使用匿名内部类的方式,是在定义一个内部类的同时实例化该内部类:
new Other() {/* 匿名内部类的类体 */};// new操作和定义类的代码是紧紧结合在一起的复制
匿名函数的作用用匿名函数的作用在于在一些特定的场景下写起来很简单,例如事件监听器:
ActionListener listener = new ActionListener() {public void actionPerformed(ActionEvent e) {}};复制
避免了再创建另外一个类文件
讲的有点乱, 对匿名内部类做个总结:
1. 省略被定义的类的类名
2. 必须结合超类或者接口使用,即 new [超类/接口] { /* 类体 */ }
3. 在定义该匿名类的同时实例化该匿名类
4. 在一些场景下能简化代码
【注意】匿名类不能有构造器, 因为构造器和类同名,而匿名类没有类名,所以匿名类不能有构造器
文章总结我们使用内部类的原因主要有三点:
1.实现数据隐藏, 避免多余的可见性
2.自由访问外部类的变量
3. 在使用监听器等场景的时候使用匿名内部类,避免增加的大量代码
关于成员内部类, 方法局部类,匿名内部类的关系
从成员内部类,方法局部类到匿名内部类是一个不断深入的关系, 成员内部类进一步隐藏可见性就成为了方法局部类, 方法局部类省去类名,并将类的定义和实例化操作合并到一起,就是匿名内部类 。因此,匿名内部类沿袭了成员内部类和方法局部类的基本特特性
内部类的一些特殊的要求
1.局部类不能用public或private访问符进行声明
2.局部类所使用的外部类方法的形参必须用final修饰
3. 匿名内部类不能有构造器
参考资料:
《java核心技术 卷1》—— Cay S. Horstmann, Gary Cornell




推荐阅读