java初始化

最近在研究java代码的生命周期。这其中遇到一个java代码初始化的问题。

  代码如下:


public class JvmTest {

private static int count1;

private static int count2 = 0;

private static JvmTest JvmTest =new JvmTest();

public JvmTest() {

System.out.println("JvmTest");

count1++;

count2++;

}

public static JvmTest getInstance() {

return JvmTest;

}

public static void main(String[] args) {

System.err.println("count1=" + JvmTest.count1);

System.err.println("count2=" + JvmTest.count2);

}

}

  这段代码运行之后的结果是什么呢?

  如果你已经有答案了,请看下面这段代码:


public class JvmTest {

private static JvmTest JvmTest =new JvmTest();

private static int count1;

private static int count2 = 0;

public JvmTest() {

System.out.println("JvmTest");

count1++;

count2++;

}

public static JvmTest getInstance() {

return JvmTest;

}

public static void main(String[] args) {

System.err.println("count1=" + JvmTest.count1);

System.err.println("count2=" + JvmTest.count2);

}

}

  这段运行结果又是什么呢?

  我开始对运行结果也比较疑惑,然后仔细分析了一下,问题就出在java代码的初始化上。因为这个测试类是带有main函数的,它会在程序运行时即执行。所以这属于主动引用,这种情况会促使类的初始化。初始化过程中,在调用成员方法之前,它首先会按顺序对静态成员变量进行赋值,如果无值可赋就给一个默认值。说到这里我想上面两段代码的结果也就好解释了。

  第一段首先count1和count2值都是0,一个是类加载过程中默认的0,一个是赋值为0,然后执行了new操作,对count1和count2进行自加,所以到这里,count1和count2的值都是1.而第二段则是先new操作对count1和count2都自加,变成1,然后再对count2进行赋值操作,所以count2的值又从1改成了0.

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-23 23:03:52

java初始化的相关文章

java 初始化-Java类的初始化顺序问题

问题描述 Java类的初始化顺序问题 一般在Java对象能够调用方法之前,此类中的成员变量就已经初始化完毕,那如果这个成员是匿名内部类呢?也会等到这个匿名内部类中的代码全部跑完吗? 解决方案 Java初始化顺序1在new B一个实例时首先要进行类的装载.(类只有在使用New调用创建的时候才会被java类装载器装入)2,在装载类时,先装载父类A,再装载子类B3,装载父类A后,完成静态动作(包括静态代码和变量,它们的级别是相同的,安装代码中出现的顺序初始化)4,装载子类B后,完成静态动作类装载完成,

java对象转化-有时候我发现java初始化的一个对象不用new关键词的哦

问题描述 有时候我发现java初始化的一个对象不用new关键词的哦 是不是用get╳╳方法就可以得到一个对象,或者初始化一个对象呢,有时候我发现java初始化的一个对象不用new关键词的哦 解决方案 new的过程是在java虚拟机中分配内存地址,也就是分配地盘给你,如果你没有立足之地你怎么做其他事情.在spring框架中是已经帮你new好了,直接等你使用,这样可以提高效率.get/set方法只是获取值和赋值的方法而已. 解决方案二: get是封装过的 其实里边还是在new,只是你看不到.单利模式

java初始化学习总结

作为初始化的一种具体操作形式,构建器应使大家明确感受到在语言中进行初始化的重要性.与C++的程序设计一样,判断一个程序效率如何,关键是看是否由于变量的初始化不正确而造成了严重的编程错误(臭虫).这些形式的错误很难发现,而且类似的问题也适用于不正确的清除或收尾工作.由于构建器使我们能保证正确的初始化和清除(若没有正确的构建器调用,编译器不允许对象创建),所以能获得完全的控制权和安全性. 在C++中,与"构建"相反的"破坏"(Destruction)工作也是相当重要的,

深入理解Java初始化的含义

可以这样认为,每个类都有一个名为Initialize()的方法,这个名字就暗示了它得在使用之前调用,不幸的是,这么做的话,用户就得记住要调用这个方法,java类库的设计者们可以通过一种被称为构造函数的特殊方法,来保证每个对象都能得到被始化.如果类有构造函数,那么java就会在对象刚刚创建,用户还来不及得到的时候,自动调用那个构造函数,这样初始化就有保障了. 我不知道原作者的描述和译者的理解之间有多大的差异,结合全章,我没有发现两个最关键的字""和"".至少说明原作者

图解 & 深入浅出Java初始化与清理:构造器必知必会

在面向对象编程中,编程人员应该在意"资源".比如 1 <font color="#000000">String hello = "hello": </font> 在代码中,我们很在意在内存中String类型的hello,它是有一个生命周期的.在它生命周期中,初始化(initialization)和清理(cleanup)是两个重要的环节.尤其是C程序中,很多bug会出现在对象初始化和清理的环节.这样会造成一些程序安全问题.

java 初始化 对象-导出类中默认创建基类的子对象

问题描述 导出类中默认创建基类的子对象 读<Java编程思想第四版>第7章复用类,7.2.1初始化基类中, 描述当创建一个导出类对象的时候会自动创建一个基类子对象. 那如果我继承自一个抽象类,那么编译器会怎么处理呢? 解决方案 抽象类是不能实例化的,基类的构造函数只是设置了这个类的属性等,这个对象是一个子类的对象,只是可以用父类指向它而已. 也就是说创建一个子类的时候,没有创建两个对象,而是一个对象.

Java 初始化过程

问题描述 public class TestStaticCon { public static int a = 0; static { a = 10; System.out.println("静态代码块在执行a=" + a); } { a = 8; System.out.println("非静态代码块在执行a=" + a); } public TestStaticCon() { this("a在类带参构造方法中的值:" + a); // 调用另外

Java初始化块与构造器执行顺序有不明白的地方

问题描述 classRoot{static{System.out.println("Root的静态初始化块");}{System.out.println("Root的普通初始化块");}publicRoot(){System.out.println("Root的无参数的构造器");}}classMidextendsRoot{static{System.out.println("Mid的静态初始化块");}{System.out

9个Java初始化和回收的面试题

Java的初始化和回收相关知识是公司在面试开发人员时常考察的问题,这里列出了8大常见的题型. 1.Java中是如何区分重载方法的? 通过重载方法的参数类型和顺序来进行区分的. 注意:若参数类型和顺序均相同时,不管参数名是否相同,编译器均会报错,提示方法已经被定义.且不能根据返回值类型来区分,如果根据返回值来区分的话,有时程序里调用方法时并不需要返回值,那么程序都无法确定该调用那个重载方法. 2.阅读以下程序,解释其中的错误. public static void testLong(long i)

Java 初始化问题

问题描述 代码如下:public class Test{Test t = new Test();public static void main(String[] args){Test t = new Test();}} 想请问一下,程序为何会报错误:Exception in thread "main" java.lang.StackOverflowError: 堆栈溢出了:据我测试得到的结果是:上面那行初始化代码一直循环执行导致堆栈溢出,想知道为什么? PS:第一次在ITeye发帖,以