本帖最后由 司懿卓 于 2013-1-20 16:55 编辑
张政 发表于 2013-1-20 15:30
他这个类又是在哪里的呢 是堆中还是栈中 或者就是我在本地磁盘上的哪个class文件? 是本地的class文件的 ...
静态成员,就是使用static修饰的成员。非静态成员就是没有static修饰的成员。成员包括成员变量(Field),方法(函数),初始化块,内部类等。
b.静态成员和非静态成员的区别:
静态成员也是类成员,是属于类的。可以通过类名直接调用。非静态成员是属于对象的,必须创建对象后才可以调用。
因为java运行的机制问题,和静态、非静态的区别,所以其运行顺序是有很大的差别的。先浅显说下java运行机制,首先呢,在编译后,运行时,JVM会寻找主方法入口,也就是程序的开始。这时,如果创建对象,创建对象之前,会先加载主方法(main方法)所在的类,因为静态成员都是类所属的。所以,在主类加载后呢,所有的静态成员都会随着加载。这时呢,因为对象还没有创建成功,非静态成员还不存在。比如,我网购买了个手机,但是手机还没到我手上,我怎么去使用呢? 肯定需要等到手机到了后才可以。 这就是java中静态成员不能访问非静态成员的原因。
其实,随着主类的加载,还有一系列的动作在之前操作。那就是,该类的所有父类进行初始化。因为,该类继承了父类,如要需要调用到父类的成员,肯定要知道父类中的情况。这样,该类的最高父类开始进行初始化,然后是其子类,最后才是该类。其实,非静态成员的初始化和静态成员的一样。不过,是需要创建对象后才执行的。而且,初始化块是在构造器之前执行的。
上面有说到成员所属问题,和子父类的先后初始化问题。下面就简单的说下顺序,然后通过代码来表现跟直观。
初始化相关的成员有:
静态初始化块;非静态初始化块;构造器;
静态初始化块是类成员,类加载,就进行初始化操作。
非静态初始化块是对象所属,创建对象,就进行初始化操作。
构造器,通过 new来调用构造器创建对象。调用后,是先执行初始化块,然后才是构造器。- class Root
- {
- static //静态初始化块
- {
- System.out.println("Root的静态初始化块");
- }
- { //非静态初始化块
- System.out.println("Root的普通初始化块");
- }
- public Root() //构造器
- {
- System.out.println("Root的无参数的构造器");
- }
- }
- class Mid extends Root
- {
- static{
- System.out.println("Mid的静态初始化块");
- }
- {
- System.out.println("Mid的普通初始化块");
- }
- public Mid()
- {
- System.out.println("Mid的无参数的构造器");
- }
- public Mid(String msg)
- {
- //通过this调用同一类中重载的构造器
- this();
- System.out.println("Mid的带参数构造器,其参数值:"
- + msg);
- }
- }
- class Leaf extends Mid
- {
- static{
- System.out.println("Leaf的静态初始化块");
- }
- {
- System.out.println("Leaf的普通初始化块");
- }
- public Leaf()
- {
- //通过super调用父类中有一个字符串参数的构造器
- super("黑马程序员");
- System.out.println("执行Leaf的构造器");
- }
- }
- public class Test
- {
- public static void main(String[] args)
- {
- new Leaf();
- new Leaf();
- }
- }
复制代码上面代码运行结果是:
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:黑马程序员
Leaf的普通初始化块
执行Leaf的构造器
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:黑马程序员
Leaf的普通初始化块
执行Leaf的构造器
上面程序创建了两次对象,但是为什么静态成员只执行了一次呢?
是因为,静态成员是类所属的,随着类的加载而执行。第一次创建对象的时候,就被初始化了。那么第二次创建还有必要再次进行初始化么?完全不用的。其实,它们的运行顺序很简单,清楚了成员所属、和继承、运行机制也就清楚了。
-------------------------------------------------------------------------------------------------
这是我之前的一篇博客,但是感觉很不满意. 就重写了.. 你参考下吧.
还有,创建的对象都是在堆中的. 静态的是在方法区中. 只有局部变量等临时数据是在栈中的.
如果还不太懂,就把视频多看几遍吧. |