类加载以及类初始化问题

沙子 2012-09-07 12:37:20
正确代码如下:

public class StaticClass{
static{
a = 1;
System.out.println("-----------------");
}
public static int a = 10;

}

错误代码如下:

public class StaticClass{
static{
a = 1;
System.out.println("-----------------"+a);
}
public static int a = 10;

}

问什么静态块里可以赋值不可以引用?
...全文
116 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
foxty 2012-09-11
  • 打赏
  • 举报
回复
ls正解,当你访问一个static的变量的时候,在class文件中其实就是一个getstatic的操作。依次类推putstatic。
iGoodLoser 2012-09-08
  • 打赏
  • 举报
回复
是jvm字节码指令,一个是为静态变量赋值-压栈,一个是获取静态变量值-出栈
沙子 2012-09-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
那为什么可以赋值,却不能在输出中出现呢? 赋值是putstatic操作,引用是getstatic操作
[/Quote]
“赋值是putstatic操作,引用是getstatic操作”是什么操作,有什么特性?
foxty 2012-09-07
  • 打赏
  • 举报
回复
这个限制是为了在编译器抓住那些怪异的初始化过程。就是这个例子提到的。
-------------------------------------------------------------------
这里的“编译器”应该为“编译期”,打错了。但是也没法修改了。
foxty 2012-09-07
  • 打赏
  • 举报
回复
根据JVM的spec的一部分定义“The static initializers and class variable initializers are executed in textual order. They may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope. This restriction is designed to catch, at compile time, most circular or otherwise malformed initializations.”可以看出

类变量的初始化顺序是按照它们出现在代码中的顺序来的,而且是不可以在它们定义之前来引用。 这个限制是为了在编译器抓住那些怪异的初始化过程。就是这个例子提到的。

那为什么可以赋值,却不能在输出中出现呢? 赋值是putstatic操作,引用是getstatic操作,我个人理解是编译器只会认为getstatic操作是一个引用,所以就编译错。而且如果去掉编译器的这个限制的话,我认为这种写法也是可以执行的。

你可以把a=1的赋值语句替换成a++就可以看到a++这一句是编译错的,因为a=1是一个简单的putstatic操作,但是a++则包含了一个getstatic的操作。
  • 打赏
  • 举报
回复
静态变量就是先定义再使用。
龙四 2012-09-07
  • 打赏
  • 举报
回复
是这样的,不过需要注意的是静态变量的内存分配在这之前就做掉了

[Quote=引用 3 楼 的回复:]

请问是不是说静态变量和静态代码块谁在前面就先加载谁??引用 1 楼 的回复:

public static int a = 10;
放到静态代码块前面。先定义,再使用。
[/Quote]
lost_guy_in_scut 2012-09-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

请问是不是说静态变量和静态代码块谁在前面就先加载谁??引用 1 楼 的回复:

public static int a = 10;
放到静态代码块前面。先定义,再使用。
[/Quote]
是的。
dsb_csdn 2012-09-07
  • 打赏
  • 举报
回复
请问是不是说静态变量和静态代码块谁在前面就先加载谁??[Quote=引用 1 楼 的回复:]

public static int a = 10;
放到静态代码块前面。先定义,再使用。
[/Quote]
龙四 2012-09-07
  • 打赏
  • 举报
回复
本质上是可以的,只不过javac这个编译器做出了限制

假设编译可以通过,类初始化做了什么?

先为a分配内存,赋默认值0

然后将a赋值为1

再将a赋值为10

javac或许是因为觉得这个赋值顺序会导致混乱,干脆禁止通过编译
brightyq 2012-09-07
  • 打赏
  • 举报
回复
public static int a = 10;
放到静态代码块前面。先定义,再使用。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧