【自己现在的一些疑问记录在这儿,如果你是Java初学者,请跳过。如果你是高手,也请教和指正里面的不足,谢谢】
现在才感觉到自己有多么的菜,所以在这儿写一下关于Java的一些认识和想法。
1,对于static的理解。
静态类其生命周期。在单例模式中,其用的就是static的特性。单例模式比较好理解。就是使其构造器成为私有的,这样才能够做到,其他的人不能随便的构造该类的实例。但是这个就有一个关于static 的声明周期的问题,即,静态对象的生命周期从什么时候开始的,到什么时候结束。一般的类对象,只要没有引用或者闭环的引用,垃圾回收器会自动的将其回收(当然,什么时间回收,这是垃圾回收器自己的决定,甚至等到最后垃圾回收器也不会回收该对象)。
那么,这儿就有一个疑问,静态对象是什么时候开始的,和什么时候它该结束呢?
先来回答第一个问题。静态对象的生命周期是什么时候开始的。
举个例子:
class Test1{
static {
int i = 0;
System.out.println("这个是静态的语句块,观察其生命周期的开始!"+i);
}
}
public class MyTest0001{
public static void main(String[] args){
System.out.println("这个是MyTest0001中的输出!");
}
}
上面的这个例子中,在MyTest0001.java中没有用到任何的Test1,所以这个时候的Test1中的静态语句块肯定是不会执行的,但是,如果在MyTest0001中做一下两种改变,则其将会执行static的语句块。
public class MyTest0001 extends Test1{
public static void main(String[] args){
System.out.println("这个是MyTest0001中的输出!");
}
}
这个是MyTest0001继承了Test1,则将会输出 Test1中的打印语句。
public class MyTest0001 {
public static void main(String[] args){
Test1 a= new Test1();
System.out.println("这个是MyTest0001中的输出!");
}
}
这个是在main方法中实例化该对象,这个显然是要输出的Test1中的内容的。
其实本人现在还是有点晕,静态对象/变量的生命周期到底是一个什么情况,也请大家指教和相互的讨论~~
2,继承与初始化
总的来说初试化的过程如下:
首先:加载父类,然后子类。第二步:父类的static的初始化,然后是子类的static初始化。
第三步:必要的类都已经加载完毕,对象就可以创建了。首先对象中所有的基本类型都会被设置为默认值,对象的引用被设置为null。然后父类的构造器将被调用。然后是子类的变量的初试化,然后是子类的构造器。
//这个例子主要是用来说明初始化的顺序的
class Test0002{
private int i = 1;
protected int j;
public Test0002(){
System.out.println("i="+i+", j= "+j);
j = 2;
System.out.println("i="+i+", j= "+j);
}
static{
System.out.println("父类中的static语句块的初始化");
}
private static int x1 = printInt("这个是父类Test0002中的x1的初始化");
private int x11 = printInt("这个是父类Test0002中的x11的初始化");
static int printInt(String s){
System.out.println(s);
return 10;
}
}
public class MyTest0002 extends Test0002{
private int x2 = printInt("这个是子类MyTest0002中x2的初始化");
public MyTest0002(){
System.out.println(x2);
System.out.println(j);
}
private static int x3 = printInt("这个是子类MyTest0002中x3的初始化");
public static void main(String[] args){
System.out.println("创建MyTest0002对象");
MyTest0002 a = new MyTest0002();
}
}
如果看这段代码,其输出结果是什么呢?
其结果为:父类中的static语句块的初始化
这个是父类Test0002中的x1的初始化
这个是子类MyTest0002中x3的初始化
创建MyTest0002对象
这个是父类Test0002中的x11的初始化
i = 1, j = 0
i = 1, j = 2
这个是子类MyTest0002中x2的初始化
10
2
这个例子也说明了在继承以及初始化的过程。
首先:先初始化父类中的static变量修饰的语句块和变量(在本例中就是先初始化:
static{
System.out.println("父类中的static语句块的初始化");
} 和
private static int x1 = printInt("这个是父类Test0002中的x1的初始化");
(这儿也要注意一点,因为x1变量是一个静态的变量,所以给其赋值的方法也必须是静态的方法。如果将printInt(String s)前面的static去掉,则编译期间会出错,相关的知识请参考static的知识点)
)
这儿还需要注意的另一点:在父类中有一个变量:
private int x11 = printInt("这个是父类Test0002中的x11的初始化");
虽然printInt(String s)是一个静态的方法,但是x11是一个非静态变量,所以此时将不会对其初始化。
第二步,就是初始化子类中的static语句块或者变量。
即将会初始化:private static int x3 = printInt("这个是子类MyTest0002中x3的初始化");
所以输出结果中的前三条就是:
父类中的static语句块的初始化
这个是父类Test0002中的x1的初始化
这个是子类MyTest0002中x3的初始化
第三步就是要使用构造器创建对象了。(即将父类和子类中静态的变量和语句块执行完之后,就开始要创建对象了,所以就要进入main方法中进行了)
所以下一步的输出就是:
创建MyTest0002对象
但是在创建对象的时候,因为还有一个父类,所以一定要先初始化父类,所以执行到这一步的时候就会跳到父类,去创建父类的对象,
分享到:
相关推荐
介绍一下java程序初始化的顺序,这会对您以后的开发所有帮助
本篇文章主要介绍了Spring 中如何控制2个bean中的初始化顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
详细讲解java类中静态变量,普通标量,对象、基本类型的初始化顺序。
对java类初始化以及顺序,详解,由于转载仅供大家参考!
一个java代码初始化具体过程的的demo
具体内容见博客
Java初始化顺序1
“礼让”原则学习Java对象初始化顺序
作为一名程序员必须知道Java初始化顺序......
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
java面试题-类的初始化顺序.doc 大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,...
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,网上关于Java中对象初始化顺序的文章很多,这篇文章我们将详细介绍Java中对象初始化顺序。有需要的可以参考学习。
java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器
C++和Java初始化顺序的比较代码, 详细的解说请参考博客地址, http://blog.csdn.net/ostrichmyself/archive/2010/11/25/6035538.aspx
java对象的初始化顺序[参考].pdf
网上有很多关于Java中class的初始化顺序文章,但是本文通过图文更加详细的介绍了Java中class的初始化顺序,并对class的装载顺序进行了讲解,下面一起来看看。
java类中静态域、块,非静态域、块,构造函数的初始化顺序,通过本例子,能够清楚了解到java类的初始化顺序
所有代码块是从上往下顺序执行的,所以代码块里面使用到的变量如果在块下面初始化会有问题 执行构造方法中内容。 所以看见的空构造方法,只能说第三部没有需要执行的内容。 下面举例子 public class TestClass { ...