`
shawnccx
  • 浏览: 165686 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

初始化对象,静态属性值不正确

 
阅读更多
问题代码:

class Singleton {
  private static Singleton obj = new Singleton();
  public static int counter1;
  public static int counter2 = 0;
  private Singleton() {
    counter1++;
    counter2++;
  }
  public static Singleton getInstance() {
    return obj;
  }
}
public class MyMain {
public static void main(String[] args) {
   Singleton obj = Singleton.getInstance();
   System.out.println("obj.counter1==" + obj.counter1);
   System.out.println("obj.counter2==" + obj.counter2);
}

}
执行结果是:
obj.counter1==1
obj.counter2==0

你有没有被此结果吓一跳?乍看程序代码,你很可能会认为counter1和counter2的值一定会相等,但执行结果显然不是如此.




因为程序在class constructor内,还未将static field初始化时(这时候,counter1和counter2都是0),就调用instance constructor,而instance constructor竟然还会去更动static field的值,使得counter1和counter2都变成1。然后instance constructor执行完,回到class constructor,再把counter2的值设为0(但是counter1维持不变)。最后的结果:counter1等于1,counter2等于0。




改正程序,方法有三:

-方法一:将singleton field的宣告调到counter1与counter2 field之后。这是最好的作法。
-方法二:将counter2=0的宣告中,「=0」的部分删除。这种作法只有在希望
-方法三:将初始化的动作搬到class constructors内,自行撰写,而不依赖编译器产生。这是最保险的作法。




分享到:
评论

相关推荐

    超级有影响力霸气的Java面试题大全文档

    Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。 25、JSP中动态INCLUDE与静态INCLUDE的区别?  动态INCLUDE用jsp:...

    QUALCOMM平台BUIW开发文档

     不取消监听对象可能产生的结果 107  注意 108  BPOINT1和BPOINT 3的错误。 108  内存泄露(BPOINT1) 108  内存重复释放(BPOINT3) 108  内存越界 109  内存问题的建议 109  采取的措施 109  ...

    《Java程序设计》课程实验指导书程序代码(答案)(实验三)

    《Java程序设计》课程实验指导书程序代码(答案)(实验三),个人原创,仅供参考与交流。 希望多多交流,共同进步!...注意:构造方法用于对成员变量初始化,无参数的构造方法将成员变量初始化为0值。

    java 面试题 总结

    Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。 22、JSP中动态INCLUDE与静态INCLUDE的区别? 动态INCLUDE用jsp:...

    精易模块[源码] V5.15

    2、修复上个版本校正API正确申明后“普通填表”类返回不能初始化BUG。 3、新增“类回调_取类地址”类回调(带实例)源码来自东灿的ECallBack。 4、新增“类回调_释放回调”释放回调子程序地址。 5、新增“系统_调用...

    java中千万别乱用!Lombok不是万能的

    在构建器中:对于目标类中的所有的属性和未初始化的 final 字段,都会在构建器中创建对应属性 在构建器中:创建一个无参的 default 构造函数 在构建器中:实体类中的每个参数,都会对应创建类似于 setter 的方法,...

    SQLHelper.cs

    此方法将返回一个 SqlParameter 对象数组,这些对象已使用缓存(与传递给该方法的连接字符串和命令文本相对应)中的参数的名称、值、方向和数据类型等进行了初始化。 注意: 用作参数集的键的连接字符串通过简单的...

    突破程序员基本功的16课.part2

    5.8.3 静态初始化块启动新线程执行初始化 5.8.4 注意多线程执行环境 5.9 小结 第6课 流程控制的陷阱 6.1 switch语句陷阱 6.1.1 default分支永远会执行吗 6.1.2 break的重要性 6.1.3 switch表达式的类型 6.2...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    3.初始化对象 生成对象的最后一步是执行构造方法,进行初始化。由于对构造方法可以进行重写 ,所以通过给出不同个数或类型的参数会分别调用不同的构造方法。 例子:以类 Rectangle 为例,我们生成类 Rectangle 的对象...

    20春北交《JAVA语言设计》在线作业一-0006参考答案.doc

    有错误,数组anar在初始化以前不能正常输出 C.2 D.1 答案:C 6.设 x、 y为已定义的类名,下列声明x类的对象x1的语句中正确的是( ) A.y x1; B.x x1=x(); C.static x x1; D.public x x1=new x(int 123); 答案:C 7.执行...

    delphi编译错误.txt

    Cannot initialize thread local variables 不能初始化线程局部变量 Cannot override a static method 不能覆盖静态方法 Cannot read a write-only property 不能读取只写属性 Case label outside of range of case ...

    C++复习资料之系列

    后,下面不正确的赋值语句是( b )。 (a) *p2 = b; (b) p1 = a; (c) p2 = p1; (d) c = *p1 *(*p2); 16.执行语句 int a = 10,b;int &pa = a,&pb = b; 后,下列正确的语句是( b )。 (a) &pb = a; ...

    .net数据访问类 SQL Helper 类

    此方法将返回一个 SqlParameter 对象数组,这些对象已使用缓存(与传递给该方法的连接字符串和命令文本相对应)中的参数的名称、值、方向和数据类型等进行了初始化。 注意: 用作参数集的键的连接字符串通过简单的...

    软件工程-理论与实践(许家珆)习题答案

    答:主要的软件开发方法有:结构化开发方法、Jackson(JSP、JSD)方法、原型化开发方 法、维也纳开发方法(VDM)和面向对象的开发方法。 6. 软件生命期各阶段的任务是什么? 答:软件生命期瀑布模型分为六个阶段: ...

    java随机数

    在Java EE多线程应用程序的环境中,随机生成实例对象仍然可以被存储在类或其他实现类,作为一个静态属性。幸运的是,java.util.Random是线程安全的,所以不存在多个线程调用会破坏种子(seed)的风险。 另一个值得...

    JAVA面试题最全集

    静态变量和静态方法的意义,如何引用一个类的静态变量或者静态方法? 50.JAVA语言如何进行异常处理,关键字:thorws,throw,try,catch,finally 51.Object类(或者其子类)的finalize()方法在什么情况下被调用? 52....

    Java-Web程序设计题库(1).doc

    在预定义中声明的变量将在JSP页面初始化时初始化 27、在JSP中使用标记时,不会出现的属性是( C )。 A.name B.property C.value D.以上皆不会出现 28、page指令用于定义JSP文件中的全局属性,下列关于该指令用法的描述...

    java面试800题

    (1)初始化对象的存储空间为零或null值; (2)调用父类构造函数; (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式; (4)调用本身构造函数。" Q0053 "Public class Servlet extends HttpServlet...

Global site tag (gtag.js) - Google Analytics