A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© doomsday 高级黑马   /  2015-4-8 15:58  /  2275 人查看  /  27 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 doomsday 于 2015-4-9 13:03 编辑

class A{
        public void show() {
                int a = 1;
                class B{
                        public void xx() {
                                System.out.println(a);
                        }
                }
        }
}

27 个回复

正序浏览
学习一下、
回复 使用道具 举报
会的,内部类访问局部变量一定要用final,还是养成良好的习惯呢
回复 使用道具 举报
君嘘 发表于 2015-4-9 01:05
java 8新特性。
某段java8新特新的描述。
在Java8以前,如果要在内部类访问外部对象的一个本地变量,那么 ...

就是这样的,但我就不明白为啥jdk1.8会这样弄
回复 使用道具 举报
还是会报错的吧
回复 使用道具 举报
doomsday 发表于 2015-4-9 00:28
你确定你的eclipse支持jdk8吗?你试试在dos窗口下编译呢

java 8新特性。
某段java8新特新的描述。
在Java8以前,如果要在内部类访问外部对象的一个本地变量,那么这个变量必须声明为final才行。在Java8中,这种限制被去掉了,代之以一个新的概念,“effectively final”。它的意思是你可以声明为final,也可以不声明final但是按照final来用,也就是一次赋值永不改变。换句话说,保证它加上final前缀后不会出编译错误。
回复 使用道具 举报 1 0
JarryHorse 发表于 2015-4-8 22:28
我JDK8,这跟JDK版本无关,这是Java底层机制决定的,方法在栈中运行,内部类对象存放在堆中,存在方法运 ...

就是和版本有关,1.8的新特性。
局部内部类可以访问局部变量。
一当访问之后,局部变量就相当于被final修饰。
回复 使用道具 举报
一定会报错,你这是定义局部内部类,局部内部类只能访问final 修饰的局部变量
回复 使用道具 举报
JarryHorse 发表于 2015-4-8 23:26
哥们儿你这就太不厚道了,如果您理解得还不是很深入就得好好琢磨琢磨了,如果你理解了还说出这话我就当你 ...

楼主已经说了很清楚了,jdk1.8
这是1.8的新特性,别说我调戏大家。

回复 使用道具 举报
JarryHorse 发表于 2015-4-8 23:36
我的是这样的,老毕视频中第9天第4节的第4分20秒开始,有对这个知识点的讲解
...

你确定你的eclipse支持jdk8吗?你试试在dos窗口下编译呢
回复 使用道具 举报
doomsday 发表于 2015-4-8 22:44
我用eclips和直接dos窗口下编译都是一样的

我的是这样的,老毕视频中第9天第4节的第4分20秒开始,有对这个知识点的讲解

图片1.png (20.16 KB, 下载次数: 96)

图片1.png
回复 使用道具 举报
不会报错,内部类
回复 使用道具 举报
君嘘 发表于 2015-4-8 23:09
能编译的 ,而且能运行。保持楼主的代码不变,在show方法上new个B对象调用xx方法。打印结果是1没错 ...

哥们儿你这就太不厚道了,如果您理解得还不是很深入就得好好琢磨琢磨了,如果你理解了还说出这话我就当你是在调戏大家:lol
回复 使用道具 举报
doomsday 发表于 2015-4-8 23:10
用你的话说,这个就应该提示“无法为最终变量a分配值”
我反编译class后a并没有被final修饰
...

你搞错了吧  这样是能编译的啊。我都试过了。。
回复 使用道具 举报
君嘘 发表于 2015-4-8 23:03
从内部类引用的本地变量必须是最终变量或实际上的最终变量
你从这句话看出了什么,不是已经说明了a必须被f ...


用你的话说,这个就应该提示“无法为最终变量a分配值”
我反编译class后a并没有被final修饰
回复 使用道具 举报
JarryHorse 发表于 2015-4-8 22:28
我JDK8,这跟JDK版本无关,这是Java底层机制决定的,方法在栈中运行,内部类对象存放在堆中,存在方法运 ...

能编译的 ,而且能运行。保持楼主的代码不变,在show方法上new个B对象调用xx方法。打印结果是1没错
回复 使用道具 举报
本帖最后由 君嘘 于 2015-4-8 23:04 编辑
doomsday 发表于 2015-4-8 22:47
你没看明白提示吗?意思是要把a申明为最终,意思是还没申明为final
如果你把a修饰为final的话 a++会提示“ ...

从内部类引用的本地变量必须是最终变量或实际上的最终变量
你从这句话看出了什么,不是已经说明了a必须被final修饰么。

可以这么理解:你没有用final修饰变了,虚拟机默认帮你加上了。当出现错误操作的时候,虚拟机当然是提醒你a是要被final修饰,final修饰的变量是最终变量,是不可改变的。
然后你加上final的话,虚拟机认为你知道用final修饰,但是不知道final修饰的变量不能改变值,所以提示当然要变一变。
回复 使用道具 举报
本帖最后由 doomsday 于 2015-4-8 22:49 编辑
君嘘 发表于 2015-4-8 22:40
因为被final修饰的变量不能改变啊。
异常说明不是很清楚了么,最终变量嘛。 你a++不是等于修改变量么。。 ...

你没看明白提示吗?意思是要把a申明为最终,意思是还没申明为final
如果你把a修饰为final的话 a++会提示“无法为最终变量a分配值”
回复 使用道具 举报
JarryHorse 发表于 2015-4-8 22:28
我JDK8,这跟JDK版本无关,这是Java底层机制决定的,方法在栈中运行,内部类对象存放在堆中,存在方法运 ...



我用eclips和直接dos窗口下编译都是一样的
回复 使用道具 举报
doomsday 发表于 2015-4-8 22:38
如果默认为final修饰 那么改成a++编译,为什么会报错“从内部类引用的本地变量必须是最终变量或实际上的 ...

因为被final修饰的变量不能改变啊。
异常说明不是很清楚了么,最终变量嘛。 你a++不是等于修改变量么。。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马