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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄昆 中级黑马   /  2012-7-16 10:23  /  1429 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Test{
         static double d=12.1234;
         static int i=f();
       
            
            public static void main(String[] args) {
                new Tes();
            }
            static int f(){
                System.out.println(d);
                return 3;
            }
        }
打印结果为:12.1234
public class Test{
         
         static int i=f();
         static double d=12.1234;
            
            public static void main(String[] args) {
                new Tes();
            }
            static int f(){
                System.out.println(d);
                return 3;
            }
        }
打印结果为:0.0
问题:为什么两个静态变量调换了一下位置,它的打印结果就不一样了呢?求解释

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

8 个回复

正序浏览
jeffreyno1 发表于 2012-7-16 11:20
这个问题主要考察了对象初始化的过程。

对象的初始化过程如下:

讲解的详细明了,:victory:
回复 使用道具 举报
黄昆 中级黑马 2012-7-16 11:24:17
8#
孙新强 发表于 2012-7-16 11:22
恩 准备的怎么样了

还行吧,我现在就在黑马宿舍住的呢
回复 使用道具 举报
黄昆 中级黑马 2012-7-16 11:24:11
7#
孙新强 发表于 2012-7-16 11:22
恩 准备的怎么样了

还行吧,我现在就在黑马宿舍住的呢
回复 使用道具 举报
hkylp 发表于 2012-7-16 11:18
喔,看见熟人了,孙新强,我是黄昆呀! 你也要来黑马呀?

恩 准备的怎么样了
回复 使用道具 举报
这个问题主要考察了对象初始化的过程。

对象的初始化过程如下:
new Test();这句话都做了什么事情?
1.因为new用到了Test.class,所以会先找到Test.class文件加载到内存中
2.执行该类中的static代码块(在方法区中),这个例子中没有静态代码块,故忽悠此步骤
3.在堆内存中开辟空间,分配内存地址
4.在堆内存中建立对象的特有属性,并进行默认初始化,在这一步将d和i进行默认初始化,分别初始化为0.0和0
5.对属性进行显式初始化,在此步骤中分别执行d=12.1234;和i=f();
6.对对象进行构造代码块初始化,此例没有构造代码块,忽略
7.对对象进行对应的构造函数初始化,此例没有构造函数,忽略


综上所述,此例中的对象初始化过程简化成以下步骤:
1.加载Test.class文件到内存
2.在堆内存中开辟空间,分配内存地址
3.在堆内存中建立对象的属性,并进行默认初始化:d=0.0; i=0
4.对属性进行显式初始化:d=12.1234; i=f();


分析清楚了以上过程,楼主的问题自然可以解答了。
第一段代码是:
        static double d=12.1234;
        static int i=f();
执行过程是:
1.d=0.0; i=0
2.d=12.1234
3.i=f()
4.执行f();//打印d,此时d的结果是12.1234


第二段代码是:
        static int i=f();
        static double d=12.1234;
执行过程是:
1.i=0; d=0.0
2.i=f()
3.执行f();//打印d,此时d的结果是0.0
4.d=12.1234

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 不错

查看全部评分

回复 使用道具 举报
孙新强 发表于 2012-7-16 11:16
这个问题应该从编译和加载顺序的角度考虑:
在这个程序中,虽然成员变量和方法都是静态的,但是具体的加载 ...

喔,看见熟人了,孙新强,我是黄昆呀! 你也要来黑马呀?
回复 使用道具 举报
这个问题应该从编译和加载顺序的角度考虑:
在这个程序中,虽然成员变量和方法都是静态的,但是具体的加载顺序不一样。
在第一个程序中,程序在编译的时候,确认了,d是double 类型,i是int型,f()是int类型方法,在new Test()的时候加载时顺序加载,d—>i—>f(),这样打印出的结果就是12.1234
在第二个程序中,编译时,也都确认了各个变量和方法的类型均已确认,加载顺序是i—>f()—>d,这样打印出的结果就是0.0

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
public class Test{
         static double d=12.1234; //1
         static int i=f();//2
            public static void main(String[] args) {
                new Test();            }
            static int f()  //3
           {    System.out.println(d);
                return 3;
            }
        }

主函数中 new Tes();创建一个对象,因为定义的变量和方法都是静态的,所以都加载到内存中。按照顺序加载 ,1 ,2,3 static double d=12.1234会首先加载,这样执行到第二步的时候会调用3.打印结果就是
12.1234

第二种方式:
public class Test{
   
    static int i=f();
    static double d=12.1234;
      
       public static void main(String[] args) {
           new Test();
       }
       static int f(){
           System.out.println(d);
           return 3;
       }
   }
先执行这一句。static int i=f();  因为用到了方法f().所以直接调用
   static int f(){
                System.out.println(d);
                return 3;
            }
此时    static double d=12.1234; 并没有加载进来。System.out.println(d); 这个会打印d的默认值0.0

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

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