java 程序加载过程---3--类中申明同时申明类的静态对象 创建类的实例 访问类的静态变量 调用类的静态方法 使用反射方法 初始化类的子类对象 直接使用java.exe 调用某个类
2014-02-17 23:13
1356 查看
java 程序加载过程---3---申明类的静态对象===》常见的应用是单例模式(饿汉式)
大家知道,只要打开任何一个开源软件,看到很多在类申明时候同时申明一个静态对象,此种情况JVM是如何加载的呢?
以下步骤是针对下面程序例子来剖析,执行顺序会受到申明的静态对象位置而不一样
Step1:加载父类的静态变量
Step2:加载父类的静态代码块
Step3:加载子类的静态变量(public static int k=0; )
Step4:public static StaticTest s1=new StaticTest("s1"); ===》会引起对象实例化的过程
Step4.1 :父类类中静态变量(类变量)(如若已经加载,JVM会跳过,不会重复赋值)
Step4.2 :父类中静态代码块(如若已经加载,JVM会跳过,不会重复赋值)
Step4.3 :子类的中静态变量(类变量)(如若已经加载,JVM会跳过,不会重复赋值)
Step4.4 :子类中的静态代码块(如若已经加载,JVM会跳过,不会重复赋值)
Step4.5:父类中的非静态变量
Step4.6:父类中的非静态代码块
Step4.7:父类构造函数
Step4.8:子类中的非静态变量
Step4.9:子类中的非静态代码块
Step4.10:子类构造函数
以下代码已经给出了代码执行顺序以Step注释的
class FatherStaticTest
{
public FatherStaticTest()//Step4.3 Step8.2
{
System.out.println("I am in the class Father");
}
public static int fi=100; //Step1
public int fii=200;//Step4.1 Step8.1
static //Step2
{
System.out.println("fi is"+fi);
}
{//Step4.2
System.out.println("fii is "+fii);
}
}
public class StaticTest extends FatherStaticTest {
public static int k=0; //Step3
public static StaticTest s1=new StaticTest("s1");//Step4
public static int i=print("i"); //Step5
public static int n=99; //Step6
public int j=print("j"); //Step4.4 Step8.3
{ //Step4.5 Step 8.4
print("构造块");
}
static //Step7
{
print("静态块");
}
public static int print(String s)
{
System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);
++n;
return ++i;
}
public StaticTest(String s) //Step4.6 Step 8.5
{
System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);
++i;
++n;
}
public static void main(String[] args) {
new StaticTest("Ben"); //Step8
//StaticTest.print("ben");
}
}
执行结果如下:
D:\myjava>java StaticTes
4000
t
fi is100
fii is 200
I am in the class Father
1:j i=0 n=0
2:构造块 i=1 n=1
3:s1 i=2 n=2
4:i i=3 n=3
5:静态块 i=4 n=99
fii is 200
I am in the class Father
6:j i=5 n=100
7:构造块 i=6 n=101
8:Ben i=7 n=102
D:\myjava>
大家知道,只要打开任何一个开源软件,看到很多在类申明时候同时申明一个静态对象,此种情况JVM是如何加载的呢?
以下步骤是针对下面程序例子来剖析,执行顺序会受到申明的静态对象位置而不一样
Step1:加载父类的静态变量
Step2:加载父类的静态代码块
Step3:加载子类的静态变量(public static int k=0; )
Step4:public static StaticTest s1=new StaticTest("s1"); ===》会引起对象实例化的过程
Step4.1 :父类类中静态变量(类变量)(如若已经加载,JVM会跳过,不会重复赋值)
Step4.2 :父类中静态代码块(如若已经加载,JVM会跳过,不会重复赋值)
Step4.3 :子类的中静态变量(类变量)(如若已经加载,JVM会跳过,不会重复赋值)
Step4.4 :子类中的静态代码块(如若已经加载,JVM会跳过,不会重复赋值)
Step4.5:父类中的非静态变量
Step4.6:父类中的非静态代码块
Step4.7:父类构造函数
Step4.8:子类中的非静态变量
Step4.9:子类中的非静态代码块
Step4.10:子类构造函数
以下代码已经给出了代码执行顺序以Step注释的
class FatherStaticTest
{
public FatherStaticTest()//Step4.3 Step8.2
{
System.out.println("I am in the class Father");
}
public static int fi=100; //Step1
public int fii=200;//Step4.1 Step8.1
static //Step2
{
System.out.println("fi is"+fi);
}
{//Step4.2
System.out.println("fii is "+fii);
}
}
public class StaticTest extends FatherStaticTest {
public static int k=0; //Step3
public static StaticTest s1=new StaticTest("s1");//Step4
public static int i=print("i"); //Step5
public static int n=99; //Step6
public int j=print("j"); //Step4.4 Step8.3
{ //Step4.5 Step 8.4
print("构造块");
}
static //Step7
{
print("静态块");
}
public static int print(String s)
{
System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);
++n;
return ++i;
}
public StaticTest(String s) //Step4.6 Step 8.5
{
System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);
++i;
++n;
}
public static void main(String[] args) {
new StaticTest("Ben"); //Step8
//StaticTest.print("ben");
}
}
执行结果如下:
D:\myjava>java StaticTes
4000
t
fi is100
fii is 200
I am in the class Father
1:j i=0 n=0
2:构造块 i=1 n=1
3:s1 i=2 n=2
4:i i=3 n=3
5:静态块 i=4 n=99
fii is 200
I am in the class Father
6:j i=5 n=100
7:构造块 i=6 n=101
8:Ben i=7 n=102
D:\myjava>
相关文章推荐
- EF(Entity Framework)发生错误”正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不保证 DbContext 的实例成员和相关类是线程安全的。 临时解决了这个问题,在Context的构造函数中,禁用了自动初始化:
- 内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例
- 【Java面试题】42 TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!
- java 程序加载过程---2-创建类实例对象
- java程序练习:尝试创建一个父类,在父类中创建两个方法,在子类中覆盖第二个方法,为子类创建一个对象,将他向上转型到基类并调用这个方法。
- 使用java反射中的getMethod,invoke方法调用对象方法的实例
- 今天发现c#中的实例后的对象是不能调用静态方法,以前学Java的时候是可以的.
- 【Java进阶-Java动态代理与AOP】03 创建动态类的实例对象及调用其方法
- 静态变量、实例变量初始化时机,以及子类隐藏父类成员时,创建子类对象的一些问题
- JavaSE第六十四讲:使用反射机制调用对象的私有方法、访问对象的私有成员变量
- 09_通过读取配置文件的方式来使用反射完成对实例对象方法调用
- 黑马程序员--java中父类和子类都有构造方法时,子类对象的初始化过程
- 《黑马程序员》 静态方法中不能直接创建内部类实例对象的原因
- java创建一个子类对象是会调用父类的构造方法会不会创建父类
- static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法
- Java初始化顺序(静态变量、静态初始化块、实例变量、实例初始化块、构造方法)
- 从父类构造器调用子类覆盖方法看Java初始化过程
- java反射调用配置文件构造类对象,使用其方法
- 用JAVA语言编写程序:包含两个类,一个类Cricle中包含计算圆周长,面积的方法。在另一个类Compute中给出半径值为10,创建对象,并调用Cricle类中的方法,计算该对象的面积、周长并显示出结
- 今天发现c#中的实例后的对象是不能调用静态方法,以前学Java的时候是可以的.