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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 胡威 黑马帝   /  2011-11-18 10:14  /  2103 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Java代码  
public class OuterClass{   
     class InnerClass{   
         private static int i;   
     }   
}  

public class OuterClass{
     class InnerClass{
         private static int i;
     }
} 对于java类加载顺序我们知道,首先加载类,执行static变量初始化,接下来执行对象的创建,如果我们要执行代码中的变量i初始化,

那么必须先执行加载OuterClass,再加载Innerclass,最后初始化静态变量i,问题就出在加载Innerclass上面,我们可以把InnerClass看成OuterClass的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载InnerClass必须在实例化OuterClass之后完成 ,java虚拟机要求所有的静态变量必须在对象创建之前完成,这样便产生了矛盾。

Verion 0.11:

对于红色标记的部分,当时理解上有误,我们知道InnerClass可以有静态常量(static final),那么InnerClass类加载一定在OuterClass对象创建之前完成,但这还不足以说明为什么非静态内部类里面不能有静态的变量(基本类型 或对象因用),这里面涉及到Java语言的定义以及JVM的类加载的原理方面的知识,我将进一步研究这个问题,技术是严谨的,也希望各位读者提出宝贵的意见。

回复 使用道具 举报
这样说你可能更只管明白一些了,首先静态成员是随着类的加载而加载的,

你既然定义了内部类的静态成员,那么它的生命周期一定很长

而如果你的内部类又恰恰不是静态的话,相当于外部类的非静态成员

而外部类的非静态成员是在对象生成时才加载,如果没有生成对象的话,

那么内部类的静态成员生命周期反而比自己所在类的都长

这样就矛盾了
回复 使用道具 举报
Java代码  
public class OuterClass{   
     class InnerClass{   
         private static int i;   
     }   
}  

public class OuterClass{
     class InnerClass{
         private static int i;
     }
} 对于java类加载顺序我们知道,首先加载类,执行static变量初始化,接下来执行对象的创建,如果我们要执行代码中的变量i初始化,

那么必须先执行加载OuterClass,再加载Innerclass,最后初始化静态变量i,问题就出在加载Innerclass上面,我们可以把InnerClass看成OuterClass的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载InnerClass必须在实例化OuterClass之后完成 ,java虚拟机要求所有的静态变量必须在对象创建之前完成,这样便产生了矛盾。

Verion 0.11:

对于红色标记的部分,当时理解上有误,我们知道InnerClass可以有静态常量(static final),那么InnerClass类加载一定在OuterClass对象创建之前完成,但这还不足以说明为什么非静态内部类里面不能有静态的变量(基本类型 或对象因用),这里面涉及到Java语言的定义以及JVM的类加载的原理方面的知识,我将进一步研究这个问题,技术是严谨的,也希望各位读者提出宝贵的意见。

评分

参与人数 1技术分 +2 收起 理由
admin + 2

查看全部评分

回复 使用道具 举报
为什么内部类中定义了静态成员,内部类就必须是静态?

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

9 个回复

倒序浏览
首先,这个是Java语言规范规定的内容。其次,你可以想象一下如何去指向这个静态成员。非静态内部类是通过外部类的this指针指向的。那么对于非静态内部类的动态成员,可以通过两个this指针确定位置。但是如果允许静态成员会出现什么情况?首先,静态成员是不能通过任何this指针的,但是为了确定这个成员,必须确定这个成员所在的类实例。但是这个实例必须通过一个this指针确定。这在语法以及处理上都会造成很大的麻烦
我的想法:Java 中的静态成员可以不用类的对象实例就可以被访问,定义为类的内部类如果不是声明为静态的内部类,那么创建外部类的实例对象的时候就会一起初始化内部类,既然非静态的内部类无论如何都一定会被初始化,那么静态成员就没有任何意义了。
(以上内容来自传智论坛,希望对你有帮助。老师记得给我加分哦,黑马我实现梦想的方)

评分

参与人数 1技术分 +2 收起 理由
admin + 2

查看全部评分

回复 使用道具 举报
由于静态的只能和静态的(不管是属性还是方法)交流,所以静态内部类只能访问外部类的静态变量和静态方法,非静态的不能访问。但可以访问静态内部类自己定义的非静态成员,因为默认情况下静态内部类的内部都是静态的。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
崔浩 黑马帝 2011-11-21 08:36:38
7#
内部类也是相当于一个类的属性,当你把一个内部类定义成一个静态的时候,相当于静态成员只能访问静态的相关属性,

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
moonlight 黑马帝 2011-11-21 11:15:08
8#
你要充分的理解静态内部类就好了如下是,慢慢理解一下
静态内部类:
   a.静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例。
   b.静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,就必须通过外部类的实例去访问。
   c.在静态内部类中可以定义静态成员和实例成员。
   d.客户类可以通过完整的类名直接访问静态内部类的静态成员

回复 使用道具 举报
程立彬 黑马帝 2011-11-23 13:42:16
9#
因为静态成员是在类初始化,还没有被创建对象的时候调用的,如果不把内部类定义成静态的,那么他就要在外部类初始化之后,建立对象后才被初始化了,这样,和内部类中的静态成员就有了冲突,所以如果内部类里面有静态成员就要把内部类定义成静态的

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马