package pack0402static;public class MyTestStaticCon {
//请切换1、2处代码
public static final int a = 0;//1、没有进入静态代码块
// public static int a = 0; //2、进入静态代码块
static {
System.out.println("11111111111");
}
}
package pack0402static;public class Test { public static void main(String[] args) {
System.out.println(MyTestStaticCon.a);
}
}
请问代码切换到1处为什么没有执行静态代码块,而代码切换到第二处却执行了静态代码块?java j2se final 初始化
//请切换1、2处代码
public static final int a = 0;//1、没有进入静态代码块
// public static int a = 0; //2、进入静态代码块
static {
System.out.println("11111111111");
}
}
package pack0402static;public class Test { public static void main(String[] args) {
System.out.println(MyTestStaticCon.a);
}
}
请问代码切换到1处为什么没有执行静态代码块,而代码切换到第二处却执行了静态代码块?java j2se final 初始化
public class Test {
public static void main(String[] args) {
System.out.println(0);//直接使用了常量值
}
}
PS:“静态代码块,静态变量都是在类加载的时候执行”可以理解,不过public static final int a = 0;是静态常量,可能根本不需要类的参与。
多谢楼上指出
static final是常量,数据存储在常量池中。
static 变量存放在堆内存,需要初始化类的时候处理。
的确这样:
1=System.out.println(0);
2=System.out.println(MyTestStaticCon.a);的确这样,可是我们不能模棱两可不求甚解吧?
编译器编译的时候直接将MyTestStaticCon.a替换成0了,也就是说Test类与MyTestStaticCon没有任何关系了,执行Test当然不会去加载MyTestStaticCon了
我的源码:public class Test {
// public static final int a = 0;
public static int a = 0;
static {
System.out.println("111111");
}
public static void main(String[] args) {
System.out.println(Test.a);
}
}
public class CopyOfTest { public static void main(String[] args) {
System.out.println(Test.a);
}
}
反编译后的代码:public class Test
{ public Test()
{
} public static void main(String args[])
{
System.out.println(a);
} public static int a = 0; static
{
System.out.println("111111");
}
}public class CopyOfTest
{ public CopyOfTest()
{
} public static void main(String args[])
{
System.out.println(Test.a);
}
}
我的反编译怎么和源码差不多??
没看出来静态的问题。。请教下
还有我的是jad进行反编译的。jadclipse。
==============================
public static int a = 0;
public static final int a = 0;
这两个是有区别的, public static final int a = 0; 这个是常量,编译时会直接采用常量的字面值。再举例:
public static final boolean isCode = true;============== 代码中存在这样一段:
if (isCode) {
// CODE
} else {
// CODE
}编译器编译后,只会保留
if (isCode) {
// CODE
}
而else中的代码是不会被编译的,因为JVM已经知道他的结果是什么。
嘿,不知道这样解释你能否理解一点。
或者二者都有(参见深入java虚拟机),使用不会引起类的初始化 所以引用静态变量的确和他本身没有任何关系了,就如12楼所说的一样!
============================
JAD
我用的就是JADclipse的。。上面那个就是我反编译的。
但是没你说的那个。
我试了一下 确实是这样 楼主把main中的System.out.println(MyTestStaticCon.a);换成System.out.println(new MyTestStaticCon().a);试一下呢
=================
private static final
private static
这两种定义的结果是不一样的。OK。
你把两种情况都反编译一下。
在main中的System.out.println(MyTestStaticCon.a); 等价于System.out.println(0); 根本没有类什么屁事
1. 加载类:如果调用load()方法时,其实内部调用的find()来查找到对应的类;
2. 解析类:即解析加载的class文件,这时会将类本身的信息和final的信息都放到方法区,也就是有人讲的常量区;此时,final变量本身已经赋值了;相当于调用Class.forName()方法;
3. 初始化类:调用类初始化方法,默认先调用静态的;
故,当你执行main时,1,2已经完成,故不会执行;
但初始化类则是需要调用的;如果想了解得更多更透彻,建议看一下<<深入JVM>>这本书
你确定你玩过这个?就来瞎回复?
我的源码。public class Test {
private static final int b = 0;
private static int a = 0;
static {
System.out.println("111111");
}
public static void main(String[] args) {
System.out.println(Test.a);
System.out.println(Test.a);
}
}
JAD反编译完:
public class Test
{ public Test()
{
} public static void main(String args[])
{
System.out.println(a);
System.out.println(a);
} private static final int b = 0;
private static int a = 0; static
{
System.out.println("111111");
}
}
public class TestCandidate {
private static final int b = 0;
private static int a = 0;
static {
System.out.println("111111");
}
public static void main(String[] args) {
System.out.println(TestCandidate.a);
System.out.println(TestCandidate.b);
}
}JAD的反编译结果:
public class TestCandidate
{ public TestCandidate()
{
} public static void main(String args[])
{
System.out.println(a);
System.out.println(0);
} private static final int b = 0;
private static int a = 0; static
{
System.out.println("111111");
}
}================================
private static final int b = 0;
private static int a = 0; System.out.println(a);
System.out.println(0);
看清楚区别,
System.out.println(Test.a);
System.out.println(Test.a);
本人是非常不愿意贴代码与调试的,我给你们的只是我的思路与经验,正确与否要靠你们自己在错误中成长。