社区
Java SE
帖子详情
为什么内部类只能访问外部类中的 final型的常量
yuyang2007
2007-08-08 04:31:02
我在java中的一个类中定义了一个内部类,为什么在内部类中只能够访问外部类中的常量呢,即final 常量?
...全文
1697
7
打赏
收藏
为什么内部类只能访问外部类中的 final型的常量
我在java中的一个类中定义了一个内部类,为什么在内部类中只能够访问外部类中的常量呢,即final 常量?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fishriver
2011-02-27
打赏
举报
回复
匿名内部类使用所在方法传入的参数为什么要求使用final类型呢?
我们仔细研究下stack中随着方法调用的变化。
每个执行中的方法在内存stack中有一个专用的frame,ebp指向开始处,esp指向正在执行处。
方法的局部变量时直接存储在frame中的,而全局变量、final是存储在heap中。
当在这个frame中调用其他方法时(包括自己或其他对象的方法),会压栈,push ebp;生成新的frame。
要把前一个frame中的局部变量传递给新frame,一般使用的是相对位置。例如在新frame中使用上一个frame的变量会使用ebp-4,ebp-8的地址代替。
好了,在正常的调用过程中,都是一个frame,接着一个frame的,参数也是一个接一个传递的。
比如对象A,对象B,对象C,那么A调B,B调C,参数是A传到B,B传到C,可以很正常的通过相对位置找到这些参数。
你想想看,如果是使用匿名内部类,A中创建一个匿名类C,把参数传给他,这个时候并没有真正执行C的方法,你让C怎么记录这个参数地址?然后把这个匿名内部类放在B的方法中,B在调用C,调用过程没有变,A调B,B调C,但参数传递过程变了,A给C,跨了一个frame,由于C不知道B的frame有多长,所以它不可能通过相对位置找到A中的局部变量。
johncarmark
2008-01-21
打赏
举报
回复
1
如果定义一个局部内部类,并且局部内部类使用了一个在其外部定义的对象,为什么编译器会要求其参数引用是final呢?
注意:局部内部类,包括匿名内部类。
原因如下:
abstract class ABSClass{
public abstract void print();
}
public class Test2{
public static void test(final String s){//一旦参数在匿名类内部使用,则必须是final
ABSClass c=new ABSClass(){
public void print(){
System.out.println(s);
}
};
c.print();
}
public static void main(String[] args){
test("Hello World!");
}
}
JVM中每个进程都会有多个根,每个static变量,方法参数,局部变量,当然这都是指引用类型.基础类型是不能作为根的,根其实就是一个存储地址.垃圾回收器在工作时先从根开始遍历它引用的对象并标记它们,如此递归到最末梢,所有根都遍历后,没有被标记到的对象说明没有被引用,那么就是可以被回收的对象(有些对象有finalized方法,虽然没有引用,但JVM中有一个专门的队列引用它们直到finalized方法被执行后才从该队列中移除成为真正没有引用的对象,可以回收,这个与本主题讨论的无关,包括代的划分等以后再说明).这看起来很好.
但是在内部类的回调方法中,s既不可能是静态变量,也不是方法中的临时变量,也不是方法参数,它不可能作为根,在内部类中也没有变量引用它,它的根在内部类外部的那个方法中,如果这时外面变量s重指向其它对象,则回调方法中的这个对象s就失去了引用,可能被回收,而由于内部类回调方法大多数在其它线程中执行,可能还要在回收后还会继续访问它.这将是什么结果?
而使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.所以这才是final变量和final参数的根本意义.
vlinux
2008-01-21
打赏
举报
回复
如果这时外面变量s重指向其它对象,则回调方法中的这个对象s就失去了引用,可能被回收
----------------------------------------------------------------------
这点我不同意,因为如果真的允许这样的机制存在,那么回调方法被其他线程引用过去了,这个时候对象依附于回调的方法而被调用回调的其他线程所引用,所以该对象仍旧会被表示为被引用,而不会被GC掉。
我觉得之所以 “内部对象不能使用该内部类所在方法的局部变量,除非该变量为final” 这句话想要避免的错误是:
我们都知道,当一个方法结束的时候,其栈结构就会被销毁。但是从方法中创建的对象仍然可以在堆中。也就是说局部变量的寿命与方法本地内部类对象寿命不一定是一样的长,如果方法本地内部类依赖了方法的一个局部变量,那么当方法结束的时候,本地内部类却依然存活在对象堆之中,但是却找不到方法的局部变量了--随着方法的结束,其堆结构就挂菜了,该局部变量也就没了。为啥final就可以呢,哪是因为final变量的寿命要大于方法的寿命啦,呵呵。
方法的参数表面上看起来是从外面传递进来的,其实本质上就是一个局部的变量,所以也和普通的局部变量一样,必须设置成final才能被方法本地内部类访问。
That's all.
猪小烧
2007-08-09
打赏
举报
回复
规定来的吧
zdjray
2007-08-08
打赏
举报
回复
你说的东西其实比较难理解真正的用意
你说的应该是局部内部类
简单的来说是作用域的问题
就好像方法外面做的事情并不能改变方法内才定义的变量
因为你并不知道方法里面这个时候已经存在了这个局部变量了没有
而你说的情况是只有当要使用的变量是方法里面的变量,而且是在此方法内定义的类才有此限制
这个时候因为在这个内部类中方法里面的本地变量是失效的,也就是不在作用域内,所以是不能够访问的
但是为什么这里用final却又可以访问呢?
因为Java采用了一种copy local variable 的方式来实现,也就是说把定义为final的局部变量拷贝过来用,而引用的也可以拿过来用,只是不能重新赋值。从而造成了可以access local variable的假象
而这个时候由于不能重新赋值,所以一般不会造成不可预料的事情发生
其中的细节很难说清楚,需要求教语言设计者
yczz
2007-08-08
打赏
举报
回复
这是SUN公司为了安全着想
prettyboy07
2007-08-08
打赏
举报
回复
因为你写的是局部内部类,所以只能访问外部类final的局部变量
转:为什么匿名
内部类
和局部
内部类
只能
访问
final
变量
是变量的作用域的问题,因为匿名
内部类
是出现在一个方法的内部的,如果它要
访问
这个方法的参数或者方法
中
定义的变量,则这些参数和变量必须被修饰为
final
。因为虽然匿名
内部类
在方法的内部,但实际编译的时候,
内部类
编译成Outer.Inner,这说明
内部类
所处的位置和
外部类
中
的方法处在同
内部类
与
外部类
之间的
访问
目 录 1.
内部类
与
外部类
2.
内部类
的特点:
内部类
可以直接
访问
外部类
的成员(成员变量和成员方法),包括私有成员。 3.
内部类
与
外部类
之间的
访问
在测试类
中
调用成员
内部类
中
的方法:
外部类
访问
成员
内部类
中
的成员: 静态的成员
内部类
,
只能
访问
外部类
的静态成员 私有的成员
内部类
,外界就无法直接创建其对象,可以通过
外部类
的方法
访问
局部
内部类
,在外界没有直接创建其对象的语法 局部
内部类
访问
外部类
的局部变量: 1.
内部类
与
外部类
将一个类A 定义到另一个类B的内部,...
内部类
之局部
内部类
只能
访问
final
的局部变量
1.首先来了解一下局部
内部类
是如何
访问
局部变量的 Person类是
外部类
,LoInClassIntf是接口,localInClassRe是Person类的成员方法,且返回值类
型
为LoInClassIntf; 方法内定义了一个局部
内部类
LoInnerClass,该
内部类
实现了接口LoInClassIntf; 方法内还定义了一个
final
的局部变量a,定义了一个LoInnerClass类
型
的对象引用loInC; 代码如下: 1 //笔记23:
内部类
--局部
内部类
--实现接口,返回
内部类
对象
java
内部类
对象
访问
外部类
对象变量_深入理解Java
中
为什么
内部类
可以
访问
外部类
的成员...
展开全部
内部类
简介虽然Java是一门相对32313133353236313431303231363533e4b893e5b19e31333339666138比较简单的编程语言,但是对于初学者, 还是有很多东西感觉云里雾里,理解的不是很清晰。
内部类
就是一个经常让初学者感到迷惑的特性。 即使现在我自认为Java学的不错了,但是依然不是很清楚。其
中
一个疑惑就是为什么
内部类
对象可以
访问
外部类
对象
中
的成员(...
深入理解Java
中
为什么
内部类
可以
访问
外部类
的成员
内部类
简介 虽然Java是一门相对比较简单的编程语言,但是对于初学者, 还是有很多东西感觉云里雾里, 理解的不是很清晰。
内部类
就是一个经常让初学者感到迷惑的特性。 即使现在我自认为Java学的不错了, 但是依然不是很清楚。其
中
一个疑惑就是为什么
内部类
对象可以
访问
外部类
对象
中
的成员(包括成员变量和成员方法)? 早就想对
内部类
这个特性一探究竟了,今天终于抽出时间把它研究了一下。 内
Java SE
62,623
社区成员
307,257
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章