JVM参数

-XX:+<option>   表示开启option选项
-XX:-<option>   表示关闭option选项
-XX:<option>=<value>  表示将option选项的值设置为value

类中静态变量如果用final修饰(常量),那么在编译阶段,这个常量会被存入调用这个常量的方法所在的类的常量池当中,再去调用这个常量时,所以没有直接引用到该类,所以不会对该类初始化,甚至把Myparent2.class删掉结果也没有变化

public class MyTest2 {
    public static void main(String[] args) {
        System.out.println(Myparent2.str);
    }
}
class Myparent2{
    public static final String str ="hello";
    static {
        System.out.println("Myparent2 static block");
    }
}

输出结果:
image.png
//助记符:ldc 表示将int,float,String类的常量值从常量池推送至栈顶
//bipush 表示将单字节(-128-127的常量值推送到栈顶)
//sipush 表示将一个短整型常量值(-32768-32767)推送到栈顶
//iconst_n n是0-5(m1代表-1) 表示将int类型的n推送至栈顶
反编译MyTest.class结果(javap -c):

public static void main(java.lang.String[]);
Code:
   0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
   3: ldc           #4                  // String hello
   5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8: return

如果类中的常量在编译时无法确定值,那么该类还是会被初始化

public class MyTest3 {

public static void main(String[] args) {
    System.out.println(Myparent3.str);
}

class Myparent3{

public static final String str= UUID.randomUUID().toString();
static {
    System.out.println("MyParent3 static block");
}

输出结果:
image.png

下面这个例子比较直观的说明了类加载和初始化的顺序,初始化是按照代码顺序:

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

    public static Singleton getInstance(){
        return singleton;
    }
}

输出结果:
image.png


KKCarrot
1 声望0 粉丝