Java静态变量初始化的一个实例的分析

来源:互联网 发布:linux如何解压tar.gz 编辑:程序博客网 时间:2024/06/08 10:44
class Singleton {public static Singleton ps = new Singleton();public static int a = 2;public static int b = 0;private Singleton() {super();a++;b++;}public static Singleton getInstance() {return ps;}}public class Test{public static void main(String[] args){Singleton mysingleton = Singleton.getInstance();System.out.println(Singleton.a);System.out.println(Singleton.b);}}
控制台输入和输出:
E:\eclipse\workspace\JavaTest\src\minglu>javac Test.javaE:\eclipse\workspace\JavaTest\src\minglu>javap -c SingletoCompiled from "Test.java"class minglu.Singleton extends java.lang.Object{public static minglu.Singleton ps;public static int a;public static int b;public static minglu.Singleton getInstance();  Code:   0:   getstatic       #4; //Field ps:Lminglu/Singleton;   3:   areturnstatic {};  Code:   0:   new     #5; //class minglu/Singleton   3:   dup   4:   invokespecial   #6; //Method "<init>":()V   7:   putstatic       #4; //Field ps:Lminglu/Singleton;   10:  iconst_2   11:  putstatic       #2; //Field a:I   14:  iconst_0   15:  putstatic       #3; //Field b:I   18:  return}E:\eclipse\workspace\JavaTest\src\minglu>javap -c TestCompiled from "Test.java"public class minglu.Test extends java.lang.Object{public minglu.Test();  Code:   0:   aload_0   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V   4:   returnpublic static void main(java.lang.String[]);  Code:   0:   invokestatic    #2; //Method minglu/Singleton.getInstance:()Lminglu/Singleton;   3:   astore_1   4:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;   7:   getstatic       #4; //Field minglu/Singleton.a:I   10:  invokevirtual   #5; //Method java/io/PrintStream.println:(I)V   13:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;   16:  getstatic       #6; //Field minglu/Singleton.b:I   19:  invokevirtual   #5; //Method java/io/PrintStream.println:(I)V   22:  return}
<pre class="java" name="code">class Singleton {public static int a = 2;public static int b = 0;public static Singleton ps = new Singleton();private Singleton() {super();a++;b++;}public static Singleton getInstance() {return ps;}}public class Test{public static void main(String[] args){Singleton mysingleton = Singleton.getInstance();System.out.println(Singleton.a);System.out.println(Singleton.b);}}

控制台输入和输出E:\eclipse\workspace\JavaTest\src\minglu>javac Test.javaE:\eclipse\workspace\JavaTest\src\minglu>javap -c SingletonCompiled from "Test.java"class minglu.Singleton extends java.lang.Object{public static int a;public static int b;public static minglu.Singleton ps;public static minglu.Singleton getInstance();  Code:   0:   getstatic       #4; //Field ps:Lminglu/Singleton;   3:   returnstatic {};  Code:   0:   iconst_2   1:   putstatic       #2; //Field a:I   4:   iconst_0   5:   putstatic       #3; //Field b:I   8:   new     #5; //class minglu/Singleton   11:  dup   12:  invokespecial   #6; //Method "<init>":()V   15:  putstatic       #4; //Field ps:Lminglu/Singleton;   18:  return}
E:\eclipse\workspace\JavaTest\src\minglu>javap -c TestCompiled from "Test.java"public class minglu.Test extends java.lang.Object{public minglu.Test();  Code:   0:   aload_0   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V   4:   returnpublic static void main(java.lang.String[]);  Code:   0:   invokestatic    #2; //Method minglu/Singleton.getInstance:()Lminglu/Singleton;   3:   astore_1   4:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;   7:   getstatic       #4; //Field minglu/Singleton.a:I   10:  invokevirtual   #5; //Method java/io/PrintStream.println:(I)V   13:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;   16:  getstatic       #6; //Field minglu/Singleton.b:I   19:  invokevirtual   #5; //Method java/io/PrintStream.println:(I)V   22:  return}


</pre><p class="java" name="code"></p><p class="java" name="code"></p><pre class="java" name="code">
public class Test6 { <br /><br />public static void main(String[] args) { <br />Test6 t6 = new Test6(); <br />} <br />} <br /><br />通过javap将上面的代码反编译为虚拟机指令,如下: <br /><br />public class com.zte.practical1.Test6 extends java.lang.Object{ <br />public com.zte.practical1.Test6(); <br />  Code: <br />   0:   aload_0 <br />   1:   invokespecial   #8; //Method java/lang/Object." <init>":()V <br />   4:   return <br /><br />public static void main(java.lang.String[]); <br />  Code: <br />   0:   new     #1; //class com/zte/practical1/Test6 <br />   3:  <span style="color:#ff00;"> dup </span><br />   4:   invokespecial   #16; //Method " <init>":()V <br />   7:   astore_1 <br />   8:   return <br />} </p><p><br /></p><p>这个上下文中的作用,我个人不是很理解为什么要使用dup指令。 <br /><br />下面是《深入JAVA虚拟机》书中dup指令解释的原话:要执行dup指令,Java虚拟机复制了操作数栈顶部的一个字长的内容,然后在将复制的内容压入栈。本指令能够从操作数栈顶不复制任何单字长的值。 <br /></p><p><pre class="java" name="code">  0:  new    #1; //从内存中申请一块类 com.zte.practical1.Test6 的对象空间,将空间的地址放入栈顶  3:  dup //将第0步得到的类Test6 的对象空间地址复制一份,放入栈顶.为什么要复制?//这是因为:执行第4步(即下一步)的指令(即:调用Test6()构造器时,是需要对象的引用的,即://是用Test6()构造器对这个引用所代表的对象空间做初始化的.另外:解析#16时,也要用到它是属于哪个对象的引用.  4:  invokespecial  #16; //Method " <init>":()V  //执行这一指令时,用到第3步中的引用.//执行完成后,第3步的引用已经从栈中弹出了  7:  astore_1  //将此时的栈顶值(正是第0步放入的对象的引用,该引用的对象空间已由3-4两步初始化过了)//弹出,放入局部变量Test6 t6中.  8:  return 






0 0
原创粉丝点击