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
}
}
这是为什么?????
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
}
}
这是为什么?????
3这个和1很相似区别是test="abc";是赋值而不是初始化,这样java系统是先建立test应用,让后把”abc“零时对象赋值给test,所以也要加载Sta
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???
}
}
对于第一种情况,编译器把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种情况进行优化
由于每个jvm实例只有一个方法区,所以每个类对应只有一个常量池,jvm在方法区为每一个被加载的类都设置一个常量池.
2.不需要创建对象,就要访问某个方法 而static就是这样一个关键字,声明了static后就表示上述两个目的