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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郝少普 中级黑马   /  2012-11-20 22:21  /  2179 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class Price{
  2.         // 类成员是 Price 的实例
  3.         final static Price ISDO = new Price(2.8);
  4.         // 定义一个类变量
  5.         static double num = 20;
  6.         // 一个 Price 的实例变量
  7.         double nump;
  8.         public Price(double n){
  9.                 // 计算实例变量的值
  10.                 nump = num - n;
  11.         }
  12. }
  13. public class PriceTest {
  14.         public static void main(String[] args) {
  15.                 System.out.println(Price.ISDO.nump);  // 1
  16.                 Price p = new Price(2.8);
  17.                 System.out.println(p.nump);                        // 2
  18.         }
  19. /*         结果 :   为何为此结果?
  20.         -2.8
  21.         17.2*/
  22. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

11 个回复

倒序浏览
在初始化ISDO时num的值为0,所以ISDO.nump=-2.8;初始化一个对象的时候他的数据域的初始化要早于构造方法,并且按数据域的声明顺序来初始化这些数据域,当ISDO初始化的时候num还没被初始化为20,它为0.

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
本帖最后由 王震阳 于 2012-11-20 22:55 编辑

这个问题我想明白了,还是final和静态的问题。这也是java中的一个难点。
//该句话是静态的因此当该类加载的时候,就去调用构造函数了,这时候num的值还没有被赋予,因此此时num=0,n=2.8,因此被final修饰的ISDO的nump变量
//的值就成了0-2.8=2.8了,并且在final的作用写,该值被固定下来,直到该类的生命周期结束才释放。对于p。nump的值就好理解多了
//因为new Price()的时候,重新创建了一个实例给P了,此时num=20,p.nump=20-2.8=17.2.
  1. class Price{
  2.         // 类成员是 Price 的实例
  3.         final static Price ISDO = new Price(2.8);//该句话是静态的因此当该类加载的时候,就去调用构造函数了,这时候num的值还没有被赋予,因此此时num=0,n=2.8,因此被final修饰的ISDO的nump变量
  4.                                                                                                 //的值就成了0-2.8=2.8了,并且在final的作用写,该值被固定下来,直到该类的生命周期结束才释放。对于p。nump的值就好理解多了
  5.                                                                                                 //因为new Price()的时候,重新创建了一个实例给P了,此时num=20,p.nump=20-2.8=17.2.
  6.         // 定义一个类变量
  7.         static double num = 20;
  8.         // 一个 Price 的实例变量
  9.         double nump;
  10.         public Price(double n){
  11.                 // 计算实例变量的值
  12.                 nump = num - n;
  13.         }
  14. }
  15. public class PriceTest {
  16.         public static void main(String[] args) {
  17.                 System.out.println("1:"+Price.ISDO.nump);  // 1
  18.                 Price p = new Price(2.8);
  19.                 System.out.println(p.nump);                        // 2
  20.         }
  21. /*         结果 :   为何为此结果?
  22.         -2.8
  23.         17.2*/
  24. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
你们去参考类初始化时初始化的顺序
回复 使用道具 举报
本帖最后由 张学永 于 2012-11-20 22:57 编辑

package com.itheima.zxyio;
class Price{
    // 类成员是 Price 的实例
    final static Price ISDO = new Price(2.8);
    // 定义一个类变量
    static double num = 20;
    // 一个 Price 的实例变量
    double nump;
    public Price(double n){
            // 计算实例变量的值
                System.out.println("num="+num);
            nump = num - n;
    }
}
public class Test {
    public static void main(String[] args) {
               
            System.out.println("Price.ISDO.nump="+Price.ISDO.nump);  // 1
            Price p = new Price(2.8);
            System.out.println("p.nump="+p.nump); //2
                              
    }

}
将以上代码做测试,输出结果为:
num=0.0
Price.ISDO.nump=-2.8
num=20.0
p.nump=17.2
可以分析了:
刚开始的时候final static Price ISDO = new Price(2.8)是类的成员,它随着类的加载而加载。
final static Price ISDO = new Price(2.8);
static double num = 20;
而你的ISDO是比num先加载的,而ISDO加载的时候,num只有默认值0;
类的成员被加载的时候都有默认初始化值。而static double num 的默认值为0;所以ISDO在加载的时候用到的num为0,得到的nump为-2.8
当ISDO加载完毕后,num才被赋值为20,被所有对象所共享。

而如果把上面加载顺序改为
static double num = 20;
final static Price ISDO = new Price(2.8);
这时候num是优先于ISDO加载的,这样输出结果就都是17.2了。。。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
本帖最后由 王亚运 于 2012-11-20 23:07 编辑

说明:google找到的答案。
还是没看懂,分享下。
  1. class Price{

  2.     final static Price INSTANCE = new Price(2.8);

  3.     static double initPrice = 20;

  4.     double currentPrice;

  5.     public Price(double discount){

  6.         currentPrice = initPrice - discount;

  7.     }

  8. }

  9. public class PriceTest{

  10.     public static void main(String[] args){

  11.         System.out.println(Price.INSTANCE.currentPrice);          //1

  12.         Price p = new Price(2.8);

  13.         System.out.println(p.currentPrice);                                 //2

  14.     }

  15. }
复制代码
[size=14.44444465637207px]程 序中1、2行代码都访问到Price实例的currentPrice实例变量,而且程序都是通过new Price(2.8);来创建Price实例的。 表明上看,程序输出两个Price的currentPrice都应该返回17.2,但实际上程序并没有输出两个17.2,而是输出了-2.8和17.2.下面从内存角度来分析这个程序。第一次用到Price类时,程序开始对Price类进行初始化,初始化分成以下两个阶段:a、系统为Price的两个类变量分配内存空间。b、按初始化代码的排列顺序对类变量执行初始化。在 a阶段,系统纤维INSTANCE、initPrice两个变量分配内存空间,此时INSTANCE、initPrice的值为默认值null和0.0. 接着初始化进入b阶段,程序按顺序依次为INSTANCE和initPrice进行赋值。对INSTANCE赋值时要调用Price(2.8),创建 Price实例,此时立即执行代码:currentPrice = initPrice - discount;为currentPrice进行赋值,此 时initPrice类变量的值还是默认值0.0,因此赋值的结果是currentPrice等于-2.8.接着,程序再将initPrice赋值为 20,但此时对INSTANCE的currentPrice的实例变量已经不起作用了。    当Price类初始化完成后 INSTANCE类变量引用到一个currentPrice为-2.8的Price实例,而initPrice的类变量值为20.0.以后再创建 Price实例时,currentPrice的实例变量的值才等于20.0-discount


不明白,final static Price INSTANCE = new Price(2.8);
什么意思。。。。
源地址:http://www.cnblogs.com/yangfengtao/archive/2012/10/18/2729838.html

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
张学永 发表于 2012-11-20 22:47
package com.itheima.zxyio;
class Price{
    // 类成员是 Price 的实例

不错  +1
哈哈
回复 使用道具 举报
王亚运 发表于 2012-11-20 23:02
说明:google找到的答案。
还是没看懂,分享下。程 序中1、2行代码都访问到Price实例的currentPrice实例变 ...

看楼上的回答,他回答的不错
回复 使用道具 举报
奚华 发表于 2012-11-20 22:44
在初始化ISDO时num的值为0,所以ISDO.nump=-2.8;初始化一个对象的时候他的数据域的初始化要早于构造方法, ...

嗯,是这个道理
回复 使用道具 举报
王震阳 发表于 2012-11-20 22:45
这个问题我想明白了,还是final和静态的问题。这也是java中的一个难点。
//该句话是静态的因此当该类加载的 ...

具体来说,应该是属于初始化的问题
回复 使用道具 举报
张超 中级黑马 2012-11-21 07:18:16
11#
奚华 发表于 2012-11-20 22:44
在初始化ISDO时num的值为0,所以ISDO.nump=-2.8;初始化一个对象的时候他的数据域的初始化要早于构造方法, ...

你好 有点疑问 ,
final static Price ISDO = new Price(2.8);

这句的创建new Price(2,8)创建对象的时候,难道只对num和nump初始化,而不对他们赋值吗
回复 使用道具 举报
王阳 中级黑马 2012-11-21 20:25:08
12#
个人理解这个就是final静态变量和静态变量的问题,还有就是初始化顺序的问题,首先,final定义的变量是不可被修改的。不过这里定义的是一个是实例对象,不过它依然是不可修改的,包括里面的值,由于初始化顺序的问题,final静态变量会在静态变量之前,所以即便静态变量的值被初始化了,也无法改变在他之前已经初始化了的final静态变量了,而且在初始化final静态变量时候里面的值已经被初始化结束了。这也就是前后两次输出结果不一致的原因,不过如果换一下顺序就没有问题了。所以总结了下,这个问题就是静态变量初始化的顺序,已经final不可以被修改的问题
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马