相比较其他类型的内部类,局部内部类还有一个显著的优点。它不仅可以访问包含着它的外围类,还可以访问在方法、作用域中的局部变量,但是前提是这些变量要用final修饰。这个特点看似天经地义,毕竟内部类在方法中,为什么不能访问方法的局部变量呢?不妨看一下下面的例子:
在有些情况下,在方法执行过程中,方法中的一条语句将局部内部类作为一个参数传递给其他的方法,而后方法结束。在其他的方法调用内部类时,内部类中原方法的局部变量已经随着方法的结束被释放,这个时候无法找到局部变量。
正是这个原因,才让我们明白一个局部内部类访问作用域中的局部变量是需要处理的,不是天经地义的。 编译器会为那些在局部内部类中要用到的局部变量做备份,也正是做备份的原因,导致局部变量需要用final修饰,如果不是这样,很有可能局部变量后来被修改,导致和备份的内容不一样从而出错。
(五) 匿名内部类
在局部内部类的基础上再深入一步,如果我们只需要用到这个类一次,那么我们只需要创建一个对象就好,不用命名了。这种不命名的内部类被称作匿名内部类。
1.表示匿名内部类
那么问题来了,如果我们不去命名一个内部类,我们怎么才能知道我们创建的是什么东西呢?解决的方法是,我们用实现一个接口或者扩展一个超类来表示我们正在编写的内部类。
package Inner;/** * * @author QuinnNorris * 匿名内部类,实现了CallBack接口 */public class AnonymousInner { private int interval; private boolean beep; public AnonymousInner(int interval, boolean beep) { this.interval=interval; this.beep=beep; }//构造器 public void start() { //匿名内部类,我们只知道它是一个实现了CallBack的子类,因为匿名,他没有自己的名字。 //CallBack接口要存在,我们不可空穴来风的创建匿名类。 CallBack cb = new CallBack(){ public void solve(String result){ result="result"; } }; }}1234567891011121314151617181920212223242526271234567891011121314151617181920212223242526272.匿名内部类的构造器
需要注意的是,匿名内部类没有构造器。这是理所当然的,因为它本身连名字都没有,它只能使用父类的构造方法,如果匿名内部类实现的是接口那么更简单,只需要在后面跟上一对空的圆括号即可,就像我们刚才例子中做的那样。如果是继承父类,则需要使用父类构造器。
3.匿名内部类与局部内部类
因为匿名内部类也存在于方法之中,所以,局部内部类的final理论也适用于匿名内部类。
匿名类在处理一些代码较短、事件较为简单的内容时具有很大的优势,更切实际,也更易于理解。现在很多很火的技术中,这种匿名机制也已经屡见不鲜了。
(六) 静态内部类(嵌套内部类)
有的时候,其实我们用内部类只是为了把一个类隐藏在另外一个类内部,甚至不需要这两个类之间的联系。那么这个时候可以把内部类声明为static,取消两个类产生的引用,这就是静态内部类(也叫嵌套内部类)。当我们把什么东西和静态的联系到一起时,还是那套理论,这个东西和对象无关,纯粹变成了类的产物。那么静态内部类的特点也很好推断:
静态内部类不再有对外围类的引用特权静态内部类能够使用外围类的静态变量,能使用同时也能被外围类的静态方法使用只有内部类可以被声明为静态类如果需要在外围类之外使用静态内部类,可以用OuterClass.InnerClass的方法静态内部类一般设置为public而不是private,便于调用(七) 总结
如果你喜欢,内部类一共可以被分为四种:成员内部类(我们一开始举例的最普通的内部类),局部内部类,匿名内部类,静态内部类。这四种各有各的特点,在运用的时候要综合考虑。除此之外,我们还一起研究了在虚拟机中内部类的实现情况,这是很有必要的,懂得它的原理才能在使用时判断的更准,在出错时直击要害。
from: http://blog.csdn.net/quinnnorris/article/details/54864491?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io