Java内部类分为4个部分进行阐述,分别为概览、成员内部类、局部内部类和匿名内部类。
在本文中是Java内部类的局部内部类,主要讲局部内部类的概念和在使用局部内部的过程中,需要注意的一个细节。
在一个类的方法内部定义另外一个类,那么另外一个类就称作为局部内部类。
class OutterClass { void test() { class InnerClass//局部内部类 { } } }
在上述代码中,InnerClass定义在OutterClass的test方法的内部,因此InnerClass是局部内部类。
如果局部内部类访问了一个局部变量,那么该局部变量必须使用final修饰
示例代码:
package com.rk.innerclass; class OutterClass { void test() { int i = 100; final int x = i;//局部变量 class InnerClass//局部内部类 { void print() { System.out.println("test方法中x的值为:" + x); } } InnerClass inner = new InnerClass(); inner.print(); System.out.println("i=" + i + ",x=" + x); } } public class InnerClassLearn { public static void main(String[] args) { OutterClass outter = new OutterClass(); outter.test(); } }
在上述代码中,OutterClass类的test方法中定义了一个x变量(final int x = 100;),由于在局部内部类InnerClass中需要访问x变量,x变量需要用final修饰。
进一步解释一下,为什么x需要被final进行修饰:
(1)x变量什么时候从内存中消失? test方法执行完毕之后x就会消失。
(2)当test方法执行完毕之后,那么x马上从内存中消失,而InnerClass对象在方法执行完毕的时候还没有从内存中消失,而InnerClass对象的print方法还在访问着x变量,这时候的x变量已经消失了,那么就给人感觉x的生命变量已经被延长了。
换一种更好理解的方式来说,如果OutterClass类的test的方法需要执行5秒钟,而InnerClass类的print方法需要执行10秒钟。在经过5秒之后,①OutterClass类的test方法就要执行完毕了,局部变量x也会从栈内存上消失,而②InnerClass类的print方法还在继续执行中,还需要访问变量x,那么①和②之间就产生了冲突。
解决方案: 如果一个“局部内部类”访问一个“局部变量”的时候,那么就让“该局部内部类”访问“这个局部变量”的复制品。
用myeclipse的1.4版本的Java Compiler进行编译,再用jd.exe(Java Decompiler)进行反编译,得到如下代码:
class OutterClass { class 1$InnerClass//这里将“局部内部类”变成了“成员内部类” { private final int val$x;//这里定义了一个final修饰的val$x变量 1$InnerClass(int paramInt)//创建了一个带参数的构造方法 { this.val$x = paramInt; } void print() { System.out.println("test方法中x的值为:" + this.val$x);//这里使用的是自身的val$x变量 } } void test() { int i = 100; int x = i; 1.InnerClass inner = new 1.InnerClass(x);//这里调用1.InnerClass类的构造函数 inner.print(); System.out.println("i=" + i + ",x=" + x); } }
用myeclipse的1.5版本的Java Compiler进行编译,再用jd.exe(Java Decompiler)进行反编译,得到如下代码:
class OutterClass { void test() { int i = 100; final int x = i; Object inner = new Object()//这里用到了匿名内部类 { void print() { System.out.println("test方法中x的值为:" + x); } }; inner.print(); System.out.println("i=" + i + ",x=" + x); } }
原文:http://lsieun.blog.51cto.com/9210464/1763928