学习任务:

视频学习

动手测试局部内部类特点

理解局部内部类final问题

局部内部类和成员内部类的区别是它所处的位置与其不同,局部内部类犹如局部变量,它是在一个方法中,或在一个局部的代码块中去定义一个内部类。

如下代码:

package com.pbteach.javase.oop.innerclass;


/**
 * 局部内部类测试
 * @author 攀博课堂
 * @version v1.0
 */
public class FirstOuterClass2 {
	
	public void getFirstInnerClassObj(){
		
		//在方法中创建一个局部内部类
		class FirstInnerClass{
			//构造方法
			public FirstInnerClass() {
				//得到个部类对象的引用
				System.out.println(FirstOuterClass2.this);
			}
			//普通方法
			public FirstInnerClass getInstance() {
				System.out.println(this);
				return this;
			}
			
		}
		FirstInnerClass firstInnerClass = new FirstInnerClass();
		FirstInnerClass instence = firstInnerClass.getInstance();
		
		
		if(true) {
			//在局部代码块中创建局部内部类
			class FirstInnerClass2{
				//构造方法
				public FirstInnerClass2() {
					//得到个部类对象的引用
					System.out.println(FirstOuterClass2.this);
				}
				//普通方法
				public FirstInnerClass2 getInstance() {
					System.out.println(this);
					return this;
				}
				
			}
			FirstInnerClass2 firstInnerClass2 = new FirstInnerClass2();
			FirstInnerClass2 instence2 = firstInnerClass2.getInstance();
		}
		
		
	}
	public static void main(String[] args) {
		FirstOuterClass2 firstOuterClass2 = new FirstOuterClass2();
		firstOuterClass2.getFirstInnerClassObj();
	}
}

运行结果如下:

com.pbteach.javase.oop.innerclass.FirstOuterClass2@15db9742
com.pbteach.javase.oop.innerclass.FirstOuterClass2$1FirstInnerClass@6d06d69c
com.pbteach.javase.oop.innerclass.FirstOuterClass2@15db9742
com.pbteach.javase.oop.innerclass.FirstOuterClass2$1FirstInnerClass2@7852e922

注意:不同电脑所输出的实例的内存地址不一致。

从上边输出可以看出,局部内部类的实例名在外部类后边加$1内部类名,如下:

com.pbteach.javase.oop.innerclass.FirstOuterClass2$1FirstInnerClass

局部内部类的特点如下:

局部内部类只在它的作用域中被实例化,不能使用外部类对象去实例化。

局部内部类不能使用private、public等权限修饰,因为它不属于外部类的成员。

局部内部可以访问外部类对象的成员,并拥有外部类对象的引用。

局部内部类只允许使用作用域内的final常量。

局部内部类只允许使用作用域内的final常量,针对这个特点说明如下:

1)局部内部类与成员内部类一样拥有外部类对象的引用,所以可以访问外部类对象的成员。该特点可参考“成员内部类”知识点,在此不再演示。

2)局部内部类也可以使用它所在作用域范围的局部变量,但它却不能更改局部变量的值。

在局部内部类FirstInnerClass中要使用局部变量a,报编译期错误,如下:

image-20210621163640520

首先在getFirstInnerClassObj()方法中定义局部变量int a=0;

在局部内部类中可以使用该变量a,但却不能更改,否则报编译期错误,错误提示为:在封闭范围内的局部变量为final,这个封闭的范围是指局部内部类。

强调一下:出现这个提示并不是说在局部内部类中只能定义final常量,而是内部类去使用它以外的局部变量时有这个限制。

为什么会有这个限制呢?

由于局部变量和局部内部类它们的生命期可能不同, 比如:一个方法的返回值是一个局部内部类对象,如下代码

package com.pbteach.javase.oop.innerclass;

/**
* 测试局部内部类
* @author 攀博课堂
* @version v1.0
*/
public class FirstOuterClass2 {
	
	//最终返回局部内部类对象
	public Processor getProcessor() {
		//局部变量在方法结束即被回收
		int a = 1;
		class ProcessorCustom extends Processor{

			@Override
			public void process() {
//				a++;//不允许更改局部变量的值,因为它是final
				System.out.println(a+1);
			}
			
		}
		
		ProcessorCustom processorCustom = new ProcessorCustom();
		//返回局部内部类对象
		return processorCustom;
	}

此时方法返回后方法内的局部变量则被垃圾回收,但是局部内部类对象依然存在,所以当局部类使用了外部的局部变量时编译器会统一将局部变量作为final,在jdk7中编译器强制要求将局部内部类使用的局部变量定义为final,jdk8中则没有此要求,不过编译器会自动加上final修饰符。

提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题