class A { public static final A a=null; static{System.out.println("A");} } public class Test { public static void main(String[] args) { Object o=A.a; } } 我觉得应该什么都不输出,但运行结果输出A。 我想知道,A.a能否在编译期确定值??我认为能确定! 高手说说自己的意见
class A { public static final A a=null; static{System.out.println("A");} } public class Test { public static void main(String[] args) { //这行混淆了你的概念,去掉这行再试试Object o=A.a; } } //结果还是输出"A",也就是说根本不用生成A或者说没进入main之前就已经执行了静态块了。
public static final A a=null; //这行也能混淆你,A a,不开辟类空间也不执行类构造函数, 只有A a=new A();才真正产生这个类。
你要知道,类加载->类连接->类初始化这三步,类初始化并非一定会执行的! 例如,下面的输出就不行执行初始化操作class A { public static final int i=1; static{System.out.println("A");} } public class Test { public static void main(String[] args) { int i=A.i; } }
是啊,我现在问的就是A.a能否在编译期确定值?如果能,就不是主动调用也就不会初始化。 但程序运行结果明显执行了静态初始化。 也就是说public static final A a=null;不是静态常量,不能在编译期确定,但我觉得应该是编译期常量。 对A.a的引用应该直接换成null,既然不是主动调用也就不会初始化,自然不应该输出任何东西。
class A { //public static final int i=1; // public static final A a=null; public static int i=1; static{System.out.println("A");} } public class Test { public static void main(String[] args) { int i=A.i; //Object o=A.a; } }
class FinalTest1{ public static final int a = 5; static{ System.out.println("static code block"); } }public class FinalTest { public static void main(String[] args) { int a = FinalTest1.a; } } static没有被执行,类没有被初始化,因为a是编译时的常量。 class FinalTest1{ public static final int a = new Integer(5); static{ System.out.println("static code block"); } }public class FinalTest { public static void main(String[] args) { int a = FinalTest1.a; } } 执行了static,类被初始化,因为a是非编译时的常量。
{
public static final A a=null;
static{System.out.println("A");}
}
public class Test
{
public static void main(String[] args)
{
//这行混淆了你的概念,去掉这行再试试Object o=A.a;
}
}
//结果还是输出"A",也就是说根本不用生成A或者说没进入main之前就已经执行了静态块了。
只有A a=new A();才真正产生这个类。
例如,下面的输出就不行执行初始化操作class A
{
public static final int i=1;
static{System.out.println("A");}
}
public class Test
{
public static void main(String[] args)
{
int i=A.i;
}
}
类加载-->静态代码块运行-->静态变量初始化-->对应的构造函数运行--->
但程序运行结果明显执行了静态初始化。
也就是说public static final A a=null;不是静态常量,不能在编译期确定,但我觉得应该是编译期常量。
对A.a的引用应该直接换成null,既然不是主动调用也就不会初始化,自然不应该输出任何东西。
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field A.a:LA;
3: astore_1
4: return
使用的是getstatic,符合前面帖子中主动使用情形的第三条
我想问的是为什么A.a不是编译期常量,难道因为它是null吗??
结贴,谢了
PS:不知道是我网速原因还是CSDN的问题,新的回复老是加载不上来,每次总是有好几楼显示不了,真心耽误时间。
{
//public static final int i=1;
// public static final A a=null;
public static int i=1;
static{System.out.println("A");}
}
public class Test
{
public static void main(String[] args)
{
int i=A.i;
//Object o=A.a;
}
}
System.out.println("static code block");
}
}public class FinalTest { public static void main(String[] args) {
int a = FinalTest1.a;
}
}
static没有被执行,类没有被初始化,因为a是编译时的常量。
class FinalTest1{ public static final int a = new Integer(5); static{
System.out.println("static code block");
}
}public class FinalTest { public static void main(String[] args) {
int a = FinalTest1.a;
}
}
执行了static,类被初始化,因为a是非编译时的常量。
,加载的过程中类的初始化,会先给静态变量赋值,并且要执行那些静态代码块,所以
出现了打印AJNI中就会用到这个方式来加载一些东西。
静态块,肯定会输入,在类加载是就会输出了,
静态块只运行一次,这也是静态块的优点。
1 在创建类之前,java虚拟机会检查类是否加载,如果没有加载,就加载这个类,类加载之前,会先加载所有父类(如果有父类的话);
2 、在堆中非配对象空间,递归分配所有父类和子类的属性空间,注意是属性,属性默认初始化;
3、进行行属性赋值
4、检查父类子类是否有静态代码块,如果有,则先执行父类、然后子类静态代码块;
5、然后递归调用父类构造器(默认调用父类的无参构造器),调用本类构造器;
静态代码块只执行一次;
static final 修饰的属性,一旦赋值不能修改,也就是只能初始化,不能被修改
我想问的是为什么A.a不是编译期常量,难道因为它是null吗??高手,五体投地,太深奥了