`
kingquake21
  • 浏览: 267872 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?

    博客分类:
  • Java
阅读更多

局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?

public class OuterClass {
	private int memberField = 10;
	
	public void outerDo(){
		final int localField = fromOther();
		
		class InnerClass{
			public void innerDo(){
				memberField = localField;
			}
		};
	}

	private int fromOther() {
	    return 20;
    }
}
 

局部变量和成员变量对于内部类而言,具有一定的共性,都是该内部类外面的变量。如果要求内部类只能访问final的局部变量是为了确保局部变量不被修改的话,那么内部类访问成员变量应该也有类似的限制才对

 

 

我认为是由于他们的存活范围导致了这个区别:

首先内部类的实例可以在方法结束后依然存活,局部变量在方法结束后却无法存活,所以在内部类中无法访问NON-final的局部变量;

而成员变量的存活时间是取决于外部类的实例的,内部类实例中都会引用当前外部类实例,所以他们拥有一致的生命周期,于是可以访问成员变量。

 

剩下的问题是,为什么可以访问final的局部变量呢?

如果将一个访问了final的局部变量的内部类进行反编译,可以发现该变量是被作为构造函数的参数传入进去的,与之一起传入的参数还有外部类实例

......

com.study.innerclass.OuterClass$1InnerClass(com.study.innerclass.OuterClass, int);
  Code:
   Stack=2, Locals=3, Args_size=3
   0:    aload_0
   1:    aload_1
   2:    putfield    #12; //Field this$0:Lcom/study/innerclass/OuterClass;
   5:    aload_0
   6:    iload_2
   7:    putfield    #14; //Field val$localField:I
   10:    aload_0
   11:    invokespecial    #16; //Method java/lang/Object."<init>":()V
   14:    return
  LineNumberTable:
   line 9: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      15      0    this       Lcom/study/innerclass/OuterClass$1InnerClass;

 

 

既然javac是这样处理内部类的,那么这与为内部类提供一个带参数的构造函数就没什么两样了!

public class OuterClass {
	private int memberField = 10;
	
	public void outerDo(){
		int localField = fromOther();
		
		class InnerClass{
			private int local;
			public InnerClass(int local) {
				this.local = local;
            }
			public void innerDo(){
				memberField = this.local;
			}
		};
		new InnerClass(localField);
	}

	private int fromOther() {
	    return 20;
    }
}
分享到:
评论

相关推荐

    局部内部类和匿名内部类使用局部变量为什么要final1

    因此,内部类访问的"局部变量"实际上是内部类自身的成员,而不是原始的局部变量。 例如: ```java public class Test { public static void main(String[] args) { Change c = method(); c.change(); // 访问...

    Java中局部内部类可以访问它所在方法中定义的final修饰的局部变量的合理解释.doc

    ### Java中局部内部类可以访问它所在方法...- 非final局部变量不能被局部内部类访问,因为它们可能在方法执行过程中发生变化。 - 这种设计保证了局部内部类的灵活性和安全性,同时也展示了Java语言对内部类的强大支持。

    final修饰成员变量和局部变量.md

    本文章是关于final部分知识所作的自我总结,内容为final对成员变量和局部变量修饰的简要解答,除了对自我java学习的一个小结,也希望能够帮助到在java路上对该内容疑惑的同行

    局部变量用final的讨论

    这是因为内部类可以访问外部类的final或effectively final变量,而这些变量被视为常量。 3. **代码优化**:JVM可能会对`final`局部变量进行优化,如逃逸分析,将它们存储在栈上而不是堆上,提高运行效率。 4. **...

    Java成员变量类变量局部变量的区别共5页.pdf.zip

    Java编程语言中有三种主要的变量类型:成员变量(也称为实例变量)、类变量(也称为静态变量)和局部变量。...对于成员变量,如果希望所有对象都有相同的值,可以考虑将其设置为final以防止意外修改。

    Java基础权限控制与final,内部类

    final变量不能被重新赋值,这适用于局部变量、成员变量和静态变量。final变量通常用于声明常量,以提高代码的可读性和安全性。 在Java中,引用类型的概念也很重要。引用类型变量存储的是对象的引用,而不是对象本身...

    JAVA内部类总结

    1. **访问权限**:局部内部类可以访问方法内的局部变量,但这些变量必须声明为final。 2. **实例化**:局部内部类只能在其定义的方法或构造函数内部实例化。 3. **示例**: ```java public void method() { final...

    final类,方法,变量

    同样,在Java 8及更高版本中,`final`局部变量可以作为lambda表达式的捕获变量,保证了lambda表达式只能读取而不能修改这些变量。 在工具方面,IDEs如Eclipse和IntelliJ IDEA提供了很好的支持来使用`final`关键字。...

    内部类分类及应用

    方法内部类对象不能使用该内部类所在方法的非final局部变量。 四、匿名内部类 匿名内部类是指不具有名称的内部类。匿名内部类适合使用场景包括:只用到类的一个实例、类在定义后马上用到、类非常小、给类命名并...

    java 内部类使用(内部匿名类)

    这种内部类的生命周期仅限于该方法的执行,可以访问方法的局部变量和参数,但对这些局部变量的访问有一些限制,它们必须是final或者等效于final的。 4. **局部内部类**:定义在方法、块或者构造器内部的类称为局部...

    java代码笔记2010-06-01:Java内部类 静态内部类 局部内部类 明明内部类;StringBuffer reverse的使用;

    这使得局部内部类可以访问它所在范围内的所有变量,包括局部变量,但这些变量必须是final的。局部内部类主要用来实现某个特定功能,其生命周期与包含它的方法或块相同。 4. **明明内部类**: "明明内部类"可能是指...

    day11【final、权限、内部类】.pdf

    内部类的使用场景通常是因为一个类的内部包含了另一个类的实例,内部类可以无条件访问外部类的成员。如汽车类中包含一个发动机类,汽车类是外部类,发动机类是内部类。 ### 引用类型 引用类型在Java中指所有非基本...

    java内部类详解

    由于其局部性,局部内部类可以访问方法内的所有局部变量和参数,但这些变量必须是 final 或 effectively final。局部内部类不能声明为 static,也不能被外部类访问,除非通过方法返回。 4. 匿名内部类(Anonymous ...

    Java内部类访问规则.doc

    - 局部内部类可以直接访问外部类的成员,并且可以访问该方法中的局部变量,但这些局部变量必须是最终的(`final`)或者本质上不可变的。 **5. 匿名内部类:** - 匿名内部类是没有名称的内部类,通常用于实现接口或...

    内部类 匿名内部类 内部接口 对比说明

    2. **局部内部类**:定义在方法内部的类,具有局部变量的特性,不能有静态属性和方法,也不能在类外直接访问。它可以访问外部类的所有成员以及所在方法的final变量。局部内部类主要用于方法内部的特定逻辑,对外不...

    java语言--内部类总结

    局部内部类可以访问方法的局部变量,但这些变量必须声明为final。 - 静态内部类:与普通成员内部类不同,静态内部类可以像普通类一样通过类名直接创建实例,无需外部类的实例。但它不能直接访问外部类的非静态成员...

    内部类详解,看了他就不用看其他资料了

    - 局部内部类可以访问外部类的所有成员,但不能直接访问同方法内的普通局部变量,除非该变量被声明为`final`。 - `final`局部变量的生命周期比方法长,即使方法执行完毕,与之关联的局部内部类对象仍然可以访问它...

Global site tag (gtag.js) - Google Analytics