一个关于Java静态代码块和静态变量的问题

lawren18 2017-07-12 09:26:16
今天遇到一个奇怪的问题,代码如下:
public class Test {
static {
name="bsd";
}
static String name="asd";

public static void main(String[] args) {
new Test();
}
}

代码可以正常编译通过。但如果变成如下所示:
public class Test {
static {
name="bsd";
System.out.println(name);

}
static String name="asd";

public static void main(String[] args) {
new Test();
}
}

程序就编译不通过了,在name打印处报错,如果把静态变量和静态代码块调换顺序,如下所示:
public class Test {
static String name="asd";
static {
name="bsd";
System.out.println(name);

}
public static void main(String[] args) {
new Test();
}
}

程序就可以编译通过了。想了好久,搞不清这里面的门道,求大牛解释!
...全文
877 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
maradona1984 2020-01-10
  • 打赏
  • 举报
回复
没必要争这么多,直接看字节码吧,编译器会帮你调整顺序的,但能做到的有限
qq_39936465 2020-01-09
  • 打赏
  • 举报
回复
引用 楼主 lawren18 的回复:
程序就可以编译通过了。想了好久,搞不清这里面的门道,求大牛解释!
首先,语句块和变量申明同等级下是按顺序运行的。只是java放宽了赋值语句要求,先赋值再申明不会报错,但是println语句则不行,必须是申明过的实例。 如果变量申明是static,程序快是普通的又可以通过编译了。

public class Test {
	 {
		name = 111;
		System.out.println(name);
	}
       static int name;
	public static void main(String[] args) {
		new Test();
	}
}

  • 打赏
  • 举报
回复
代码的编译过程也是有顺序的,都是静态代码块,肯定按顺序编译
Pilosity 2020-01-05
  • 打赏
  • 举报
回复
静态代码块里面只能引用静态资源,所以7楼说的是有问题的,虚拟机在执行name = "bsd";时就已经知道name是静态资源,静态资源的加载顺序是严格按照静态资源的加载顺序执行的,所以静态成员变量放在后面,name还没有实例化,println需要实例化对象
qq_39936465 2018-11-28
  • 打赏
  • 举报
回复
因为静态块 在初始化时不会创建对象,所以 在静态块中 name="bsd"; 可以通过编译,而如果加入System.out.println(name);语句后,println是需要实例化对象的,但是name变量还没创建所以报错了。
隐语者 2018-11-28
  • 打赏
  • 举报
回复
全局变量和静态代码块的执行是按顺序执行的,但是你没有申明变量就打印出来肯定报错了哈
CJ95YD 2018-11-28
  • 打赏
  • 举报
回复
引用 11 楼 cxdn_czj 的回复:
最近也有这样的疑惑,楼主得到满意的答案了吗
这个其实你在类的最后面定义变量,你依然可以在前面引用,因为类加载时会将成员变量先加载进去的,所以赋值当然是没问题的。 至于静态代码块里打印出错也很好理解,因为编译器将它当成是局部变量了,没有进行类型定义当然是不能引用的,用Test.name就行了。
lawren18 2017-07-13
  • 打赏
  • 举报
回复
引用 8 楼 三仙半的回复:
我支持7楼的解释。 敬佩楼主对技术的钻研,我用了好多年Java,几乎从不考虑这样的东西,都是遇到了再说。。。。。
我也只是遇到了而已
lawren18 2017-07-13
  • 打赏
  • 举报
回复
引用 7 楼 weixin_39494923的回复:
个人认为两者都是静态的前提下,都是按顺序执行,显然代码块放前面,引用时不知道name是不是静态的,所以报错
如果是这样的话,在打印语句上面的赋值语句处就应该报错了,然而赋值并不会报错,打印才报错
三仙半 2017-07-13
  • 打赏
  • 举报
回复
我支持7楼的解释。 敬佩楼主对技术的钻研,我用了好多年Java,几乎从不考虑这样的东西,都是遇到了再说。。。。。
M义薄云天 2017-07-12
  • 打赏
  • 举报
回复
个人认为两者都是静态的前提下,都是按顺序执行,显然代码块放前面,引用时不知道name是不是静态的,所以报错
lawren18 2017-07-12
  • 打赏
  • 举报
回复
引用 5 楼 soton_dolphin的回复:
[quote=引用 2 楼 lawren18 的回复:] [quote=引用 1 楼 soton_dolphin的回复:]解释说的很清楚啊,不能在变量被定义前引用
变量未定义,却能在代码块中赋值如何解释[/quote] 可以赋值,但不能被引用啊。[/quote] 这正是我要问的,为什么呢?
soton_dolphin 2017-07-12
  • 打赏
  • 举报
回复
引用 2 楼 lawren18 的回复:
[quote=引用 1 楼 soton_dolphin的回复:]解释说的很清楚啊,不能在变量被定义前引用
变量未定义,却能在代码块中赋值如何解释[/quote] 可以赋值,但不能被引用啊。
lawren18 2017-07-12
  • 打赏
  • 举报
回复
引用 3 楼 与自己作战的回复:
变量未定义你使用了不是报错了吗??静态变量更换了位置,你name已经在前面定义了,后面肯定可以直接使用了
看最上面的代码,变量并没有先定义,同样可以在静态代码块中给它赋值(ps:静态代码块在前面,静态变量在后面)
  • 打赏
  • 举报
回复
变量未定义你使用了不是报错了吗??静态变量更换了位置,你name已经在前面定义了,后面肯定可以直接使用了
lawren18 2017-07-12
  • 打赏
  • 举报
回复
引用 1 楼 soton_dolphin的回复:
解释说的很清楚啊,不能在变量被定义前引用
变量未定义,却能在代码块中赋值如何解释
soton_dolphin 2017-07-12
  • 打赏
  • 举报
回复
解释说的很清楚啊,不能在变量被定义前引用

62,614

社区成员

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

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