局部内部类为什么只能访问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;
}
}
分享到:
相关推荐
因此,内部类访问的"局部变量"实际上是内部类自身的成员,而不是原始的局部变量。 例如: ```java public class Test { public static void main(String[] args) { Change c = method(); c.change(); // 访问...
### Java中局部内部类可以访问它所在方法...- 非final局部变量不能被局部内部类访问,因为它们可能在方法执行过程中发生变化。 - 这种设计保证了局部内部类的灵活性和安全性,同时也展示了Java语言对内部类的强大支持。
本文章是关于final部分知识所作的自我总结,内容为final对成员变量和局部变量修饰的简要解答,除了对自我java学习的一个小结,也希望能够帮助到在java路上对该内容疑惑的同行
这是因为内部类可以访问外部类的final或effectively final变量,而这些变量被视为常量。 3. **代码优化**:JVM可能会对`final`局部变量进行优化,如逃逸分析,将它们存储在栈上而不是堆上,提高运行效率。 4. **...
Java编程语言中有三种主要的变量类型:成员变量(也称为实例变量)、类变量(也称为静态变量)和局部变量。...对于成员变量,如果希望所有对象都有相同的值,可以考虑将其设置为final以防止意外修改。
final变量不能被重新赋值,这适用于局部变量、成员变量和静态变量。final变量通常用于声明常量,以提高代码的可读性和安全性。 在Java中,引用类型的概念也很重要。引用类型变量存储的是对象的引用,而不是对象本身...
1. **访问权限**:局部内部类可以访问方法内的局部变量,但这些变量必须声明为final。 2. **实例化**:局部内部类只能在其定义的方法或构造函数内部实例化。 3. **示例**: ```java public void method() { final...
同样,在Java 8及更高版本中,`final`局部变量可以作为lambda表达式的捕获变量,保证了lambda表达式只能读取而不能修改这些变量。 在工具方面,IDEs如Eclipse和IntelliJ IDEA提供了很好的支持来使用`final`关键字。...
方法内部类对象不能使用该内部类所在方法的非final局部变量。 四、匿名内部类 匿名内部类是指不具有名称的内部类。匿名内部类适合使用场景包括:只用到类的一个实例、类在定义后马上用到、类非常小、给类命名并...
这种内部类的生命周期仅限于该方法的执行,可以访问方法的局部变量和参数,但对这些局部变量的访问有一些限制,它们必须是final或者等效于final的。 4. **局部内部类**:定义在方法、块或者构造器内部的类称为局部...
这使得局部内部类可以访问它所在范围内的所有变量,包括局部变量,但这些变量必须是final的。局部内部类主要用来实现某个特定功能,其生命周期与包含它的方法或块相同。 4. **明明内部类**: "明明内部类"可能是指...
内部类的使用场景通常是因为一个类的内部包含了另一个类的实例,内部类可以无条件访问外部类的成员。如汽车类中包含一个发动机类,汽车类是外部类,发动机类是内部类。 ### 引用类型 引用类型在Java中指所有非基本...
由于其局部性,局部内部类可以访问方法内的所有局部变量和参数,但这些变量必须是 final 或 effectively final。局部内部类不能声明为 static,也不能被外部类访问,除非通过方法返回。 4. 匿名内部类(Anonymous ...
- 局部内部类可以直接访问外部类的成员,并且可以访问该方法中的局部变量,但这些局部变量必须是最终的(`final`)或者本质上不可变的。 **5. 匿名内部类:** - 匿名内部类是没有名称的内部类,通常用于实现接口或...
2. **局部内部类**:定义在方法内部的类,具有局部变量的特性,不能有静态属性和方法,也不能在类外直接访问。它可以访问外部类的所有成员以及所在方法的final变量。局部内部类主要用于方法内部的特定逻辑,对外不...
局部内部类可以访问方法的局部变量,但这些变量必须声明为final。 - 静态内部类:与普通成员内部类不同,静态内部类可以像普通类一样通过类名直接创建实例,无需外部类的实例。但它不能直接访问外部类的非静态成员...
- 局部内部类可以访问外部类的所有成员,但不能直接访问同方法内的普通局部变量,除非该变量被声明为`final`。 - `final`局部变量的生命周期比方法长,即使方法执行完毕,与之关联的局部内部类对象仍然可以访问它...