局部内部类,又叫本地内部类,是定义在方法内部的类,只在定义其的代码块中是可见的。 如果想调用局部内部类的方法,必须在方法中实例化这个类。
看以下例子:
class TestDemo{
private int a = 20;
private int b = 30;
public void test(){
int data1 = 10;
final int data2 =100;
/** 局部内部类 */
class InnerClass{
// 可以定义与外部类同名的变量
private int a = 40;
// 和成员内部类一样,局部内部类中也不能定义静态成员
//private static int b = 50;
private static final int c = 60; //立即数
/** 内部类的构造方法 */
public InnerClass(){
System.out.println("test():InnerClass init!!");
}
/** 局部类的普通方法 */
public void print(){
// 如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量
System.out.println("c :"+c);
System.out.println("a :"+a);
// 用this.变量名访问的也是内部类变量
System.out.println("a :"+this.a);
// 用外部类名.this.内部类变量名访问的是外部类变量
System.out.println("a :"+TestDemo.this.a);
// 如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
System.out.println("b :"+b);
// 局部内部类不能访问非最终局部变量,直到JDK 1.7
System.out.println("data1 :"+ data1);
/* 从JDK 1.8开始,局部内部类可以访问局部内部类中的非最终局部变量,但不
建议这样使用,见下面解释 */
System.out.println("data2 :"+ data2);
}
}
/** 调用内部类的方法 */
// 1.在方法中先实例化一个内部类对象
InnerClass in = new InnerClass();
// 2.通过该对象调用内部方法
in.print();
}
}
/** 主类 */
public class Demo {
public static void main(String[] args) {
// 实例化TestDemo类对象来调用类方法
TestDemo demo = new TestDemo();
demo.test();
}
}
结果是:
test():InnerClass init!!
c :60
a :40
a :40
a :20
b :30
data1 :10
data2 :100
对于内部类使用的形参为何要用final修饰的解释:
在内部类编译成功后,它会产生一个class文件,该class文件与外部类并不是同一class文件,仅仅只保留对外部类的
引用。当外部类传入的参数需要被内部类调用时,内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入
的参数进行备份,自己内部方法调用的实际上是自己的属性而不是外部方法传递进来的参数。在内部类中的属性和外部方
法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,也就是说在内部类中对属性
的改变并不会影响到外部的形参,但是从程序的角度分析这是难以理解和不可接受的,所以为了保持参数的一致性,就规
定使用final来避免形参的不改变。