1.public class Main {
public static void main(String[] args){
System.out.println(Sta.test);
}
}
class Sta{
public final static String test="abc"; 
static{
System.out.println("111");//不会显示“111”

}2.public class Main {
public static void main(String[] args) {
System.out.println(Sta.test);
}
}
class Sta{
public final static String test=new String("abc");
static{
System.out.println("111");//显示111

}3.public class Main {
public static void main(String[] args) {
System.out.println(Sta.test);
}
}class Sta{
public final static String test; 
static{
test="abc";
System.out.println("111");//显示111

}
这是为什么?????

解决方案 »

  1.   

    首先要静态初始化块是在类被加载的时候执行的1不会显示“111”是因为,public final static String test="abc"; test是静态初始化常量并且是用子面量;进行初始化,java编译器在优化的时候是直接把test替换成”abc“的。所以不会加载Sta类。2因为要执行NEW操作进行初始化所以必须加Sta载类。
    3这个和1很相似区别是test="abc";是赋值而不是初始化,这样java系统是先建立test应用,让后把”abc“零时对象赋值给test,所以也要加载Sta
      

  2.   

    谢谢楼上的兄弟,
    class xxxx{    public final static String test="abc"; 
        static{
            System.out.println("111");
        } 
       
    }public class tt extends ClassLoader{
     
    public static void main(String[] args)throws Exception {new xxxx();
    tt t=new tt();
    System.out.println(t.findLoadedClass("xxxx"));//为什么总是返回null???
        }
    }
      

  3.   

    楼主所看到的不同结果完全是因为编译器优化的结果.
    对于第一种情况,编译器把Sta.test直接替换成"abc".而对于2,3种情况,编译器并没有进行优化.这里要说的是虚拟机要用到一个类,首先要对类进行装载,连接,初始化.
    这里指的是对类进行的,和new没关系.只不过通过new能主动触发类的初始化
    对于第二种情况和new一个String对象是没关系的,如果说要通过new触发类初始化,
    也要new Sta()对于第三种情况,类初始化是通过一个<clinit>的类初始化方法完成的.
    对于 
    public final static String test; 
    static{ test="abc";} 

    public final static String test = "abc";
    这两种写法是没什么本质区别的,它们都会在<clinit>方法种对类进行初始化,执行顺序有出现的先后顺序决定.所以我要说的是,这3个问题完全是由编译器决定的,和虚拟机没关系.如果可以,完全也可以让编译器对第2,3种情况进行优化
      

  4.   

    常量池是不是在jvm范围内共享?
      

  5.   

    每个.class文件都有一个常量池,当.class文件被jvm加载时,jvm通过对其二进制数据解析收集信息,并将.class文件中的常量池映射到方法区.
    由于每个jvm实例只有一个方法区,所以每个类对应只有一个常量池,jvm在方法区为每一个被加载的类都设置一个常量池.
      

  6.   

    1.运行一个程序,你至少要开辟一块静态内存 
    2.不需要创建对象,就要访问某个方法 而static就是这样一个关键字,声明了static后就表示上述两个目的
      

  7.   

    概而言之,原因便在于java编译器的优化问题,只有在定义成final static的时候才被优化直接进行了替换导致没有加载sta类,简单的去掉final就可以让jvm的类加载器对sta类进行加载