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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© sanguodouble1   /  2014-4-18 09:57  /  2699 人查看  /  30 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

yanzhendong 发表于 2014-4-18 13:54
这应该是java的编程规范规定的,内部类是被当成外部类的成员来看待的,当一个内部类不是非静态时,这个内部 ...

你都没看清问题,
static final int a = 0;这个也是静态成员,也可以不会依赖于外部类实例对象,你怎么解释
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 14:01
你都没看清问题,
static final int a = 0;这个也是静态成员,也可以不会依赖于外部类实例对象,你怎么 ...

java是这样规定的,就像一个java源文件中只能有一个public类一样。
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 14:01
你都没看清问题,
static final int a = 0;这个也是静态成员,也可以不会依赖于外部类实例对象,你怎么 ...

还有,static final int a主要突出的是a是一个常量,前面加不加static都一样,因为类中的常量本来就只有一份,就相当于静态变量一样,
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 13:34
对啊,就是问你这个啊,

被static修饰的变量都是在堆中分配内存,而函数中的变量都是在栈中分配内存,所以不能在函数中使用static
回复 使用道具 举报
yanzhendong 发表于 2014-4-18 14:17
还有,static final int a主要突出的是a是一个常量,前面加不加static都一样,因为类中的常量本来就只有 ...

谁告诉你类中的常量只有一份的?
final常量,如果在非静态方法中,那么方法每次被调用,都会在栈内存中分配一个空间的好么
回复 使用道具 举报
yanzhendong 发表于 2014-4-18 14:29
被static修饰的变量都是在堆中分配内存,而函数中的变量都是在栈中分配内存,所以不能在函数中使用static ...

你说来说去也没说明白为什么在非静态内部类中可以用static final,外部类都没实例化,非静态内部类竟然已经有成员了?

这就好比先有爷爷,然后父亲,再儿子
现在你没爷爷,直接就有儿子了,这逻辑合适吗?

你要老整java规范,那就没法说了,而且java规矩都有他制定的道理, 你如果一定要说java规范
,那你倒是说说他为什么要这样规范?
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 15:10
你说来说去也没说明白为什么在非静态内部类中可以用static final,外部类都没实例化,非静态内部类竟然已 ...

静态常量和静态变量还是有区别的,你不要纠结于这里,就像方法中的内部类只能访问方法中的被final修饰的变量一样,这是语法规定,你只要知道这么一回事就行了,我也解释不清楚,求哪位大神帮忙解释一下:Q
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 15:06
谁告诉你类中的常量只有一份的?
final常量,如果在非静态方法中,那么方法每次被调用,都会在栈内存中分 ...

我说的是类中的常量,不是方法中的常量,方法中的常量和类中的常量还是有区别的,类中的常量是在常量区分配空间,方法中的常量是在栈中分配空间,
回复 使用道具 举报
yanzhendong 发表于 2014-4-18 15:38
静态常量和静态变量还是有区别的,你不要纠结于这里,就像方法中的内部类只能访问方法中的被final修饰的 ...

那我帮你解释一下你的问题,之所以方法内部类不能访问方法的局部变量,

这是因为局部变量和内部类的生命期是不一样的,局部方法在方法调用完后就消失了,而内部类只要有引用,就会一直存在。
这样就会出现,一个存在的内部类,去访问一个已经不存在的局部变量,这不是荒谬吗?
所以为了实现这个需求,java公司就规范内部类可以访问final的局部量,
注意,这时不是访问的这个量的本身,而是访问这个final的拷贝值
比如我在方法内定义一个 final int a = 10;
然后内部类就会把这个a 复制一份,作为自己的成员变量。而原来这个a,在方法调用完后,就消失了。
以后内部类访问的都是他自己的成员变量,但看起来就好像在访问局部变量一样,知道了吗?
而之所以需要什么成final ,是因为实际逻辑考虑的,如果不声明成final,那就可以会存在这种情况:你把一个已经消失的变量值改变了,这不是滑天下之大稽?

话说回来,任何规范都有他的初衷和因果,
是你自己理解不够深入,解释不通,却叫别人不要纠结?
回复 使用道具 举报
sanguodouble1 发表于 2014-4-18 12:03
兄弟,我不是要记住,我问的是原理

你就直接解释为什么

class Outer {
        public void outMethod() {
                int outI = 10;
                class Inner {
                        static int a = 5;  //编译报错
                        static final int b = 10;  //编译不报错
                }
        }
}
你定义了一个Outer类,这个类中的有个outMethod方法,而该方法中定义了一个内部类Inner,这样的结果就是可以通过outer类调用outmethod方法,即可直接调用outmethod方法中的变量或者方法。简单点理解就是,可以只用inner中的变量或者方法,这样的做法就会导致该程序中的static可有可无。但是,要注意了,final的用法:
首先看2个定义:
内部类的对象:脱离了其外围类的对象就不会存在。
静态变量:作用是让该类的所有对象共享一个状态。

原因分析:
因为你的内部类是非静态的,除了要依靠外部类实例外,还要依赖内部类实例。
而静态变量是不需要构建类实例的,两者是相矛盾的。
而final类型修饰的变量(即常量)可以离开类实例存活一段时间的。
所以final修饰过的不错。
你如果把内部类修饰成静态的就不会报错了。

综上所述:出现这种情况的主要原因,是外部类实例与内部类实例依赖问题。
回复 使用道具 举报
Sniper_qiu 发表于 2014-4-18 21:06
class Outer {
        public void outMethod() {
                int outI = 10;

先纠正你两点
1.内部类只要有引用存在,即使脱离了外围类对象也会存在
2.final类型的声明周期和普通变量是一样的,谁告诉你他可以离开实例存活一段时间的?不要网上随便看点就当公理好不好?存在就意味着可使用,你能在一个方法的外面使用它里面的final量?具体去看29楼

回到主题上:这个问题我其实是问的变量生命期的逻辑问题
你自己也说了“内部类是非静态的,除了要依靠外部类实例外,还要依赖内部类实例。而静态变量是不需要构建类实例的,两者是相矛盾的。”
而static final也是不需要构建实例的,为什么就不矛盾了?
回复 使用道具 举报
12
您需要登录后才可以回帖 登录 | 加入黑马