关于静态变量的定义和使用问题,求解

lc545126483 2018-04-13 02:13:11

public class Question1 {
//static int a = 1;
static {
a = 3; //此处永不报错
System.out.println(a); //当静态变量定义在下面时报错:Cannot reference a field before it is defined
}
static int a = 1;

public static void main(String[] args) {

}
}


第5行报错,说不能引用未定义的a,把第七行换到第二行去就没事了。
我知道静态代码块和静态变量会在类加载是被加载到内存,执行顺序是按照代码顺序。
我静态变量定义语句在下面的时候报错我能理解,我疑惑的是a未定义时,为啥a=3这个赋值语句不会报错呢? 它与输出a的本质区别在哪?
...全文
751 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
tzk009 2018-04-14
  • 打赏
  • 举报
回复
方法区加载该类时,虽然a开始没定义,不过JVM会先标记,等执行到下面代码时,如果有static代码声明了a那么就会把之前的a=3赋值给它
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 19 楼 qq_24947841 的回复:
[quote=引用 17 楼 lc545126483 的回复:] [quote=引用 13 楼 考拉一枚的回复:][quote=引用 9 楼 lc545126483 的回复:] [quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] 1.java支持向前引用,所以你 先 a=3; static int a = 1就不会错 具体可参考http://blog.51cto.com/androidguy/1230298 2.为啥 a =3可以,而System.out.println(a);不行,参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3[/quote] 大神,向前引用还是有一点不明白,为什么我把赋值和定义放到一个地方就不行呢?比如说我全放到静态代码块里static{a=3,int a=1} 或者全放初始化代码块里{a=3,int a=1}就不行呢? 另外第二个链接全英文看不懂,能否帮忙概括下[/quote] static{a=3,int a=1} {a=3,int a=1} 因为这两种表示方式里 两个a不是同一个变量, int a =1 的a是一个作用范围受限的局部变量,而你的a=3中的a是一个类的成员变量,所以你改成 static{a=3,int a=1}; static int a = 2;就不会报错 英文自己找翻译看。。[/quote] 谢谢解答
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 8 楼 Ragin的回复:
https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 6 楼 miaoch的回复:
如果你写成 System.out.println(Question1.a); 就不会报错了
这样确实不会报错,但为什么上面的a=3不需要这么做呢?他们的使用环境都一样啊?怎么赋值没问题,输出就说我未定义?
FlyToFreedoom 2018-04-13
  • 打赏
  • 举报
回复
没毛病,,,
miaoch 2018-04-13
  • 打赏
  • 举报
回复
就后一个问题,那是因为,代码会别解析成 static int a; a=3; a=1; 最终a会变成1,就先把声明过的放到最前面。 因为 static int a = 1;其实也是两个步骤,一个是定义a,一个是初始化a的值为1。这个地方被拆解了。 然后前一个问题,我也想不明白。我觉得可能这里的定义a和平常的不一样,这里的a是没有值的,就像局部变量一样。所以java做了这样的限制。 至于为何a = 3后,还是无法使用这个a,可能只是偷懒减轻了编译压力吧 = =
miaoch 2018-04-13
  • 打赏
  • 举报
回复
如果你写成 System.out.println(Question1.a); 就不会报错了
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 3 楼 Tibersen的回复:
你把第7行的static 去掉 你看报错不,static 是重新给静态变量赋值了把 所以a=3不会报错
第七行static去掉的话,从a=3就开始报错了:不能从静态环境引用非静态变量
Tibersen 2018-04-13
  • 打赏
  • 举报
回复
你把第7行的static 去掉 你看报错不,static 是重新给静态变量赋值了把 所以a=3不会报错
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 1 楼 thifern的回复:
那个... a = 3 是什么意思?莫非你要赋值? 请在第4行前加int,声明变量类型
我就是尝试赋值啊,但我定义语句在下面,可我a=3这个语句就是不会报错,只有下面那个语句才会报错
考拉一枚 2018-04-13
  • 打赏
  • 举报
回复
引用 17 楼 lc545126483 的回复:
[quote=引用 13 楼 考拉一枚的回复:][quote=引用 9 楼 lc545126483 的回复:] [quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] 1.java支持向前引用,所以你 先 a=3; static int a = 1就不会错 具体可参考http://blog.51cto.com/androidguy/1230298 2.为啥 a =3可以,而System.out.println(a);不行,参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3[/quote] 大神,向前引用还是有一点不明白,为什么我把赋值和定义放到一个地方就不行呢?比如说我全放到静态代码块里static{a=3,int a=1} 或者全放初始化代码块里{a=3,int a=1}就不行呢? 另外第二个链接全英文看不懂,能否帮忙概括下[/quote] static{a=3,int a=1} {a=3,int a=1} 因为这两种表示方式里 两个a不是同一个变量, int a =1 的a是一个作用范围受限的局部变量,而你的a=3中的a是一个类的成员变量,所以你改成 static{a=3,int a=1}; static int a = 2;就不会报错 英文自己找翻译看。。
thifern 2018-04-13
  • 打赏
  • 举报
回复
那个... a = 3 是什么意思?莫非你要赋值? 请在第4行前加int,声明变量类型
刘正权 2018-04-13
  • 打赏
  • 举报
回复
类在初始化之前,会完成静态变量、静态代码块的初始化和赋值。String默认是null,int默认是0.
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 13 楼 考拉一枚的回复:
[quote=引用 9 楼 lc545126483 的回复:] [quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] 1.java支持向前引用,所以你 先 a=3; static int a = 1就不会错 具体可参考http://blog.51cto.com/androidguy/1230298 2.为啥 a =3可以,而System.out.println(a);不行,参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3[/quote] 大神,向前引用还是有一点不明白,为什么我把赋值和定义放到一个地方就不行呢?比如说我全放到静态代码块里static{a=3,int a=1} 或者全放初始化代码块里{a=3,int a=1}就不行呢? 另外第二个链接全英文看不懂,能否帮忙概括下
smtsuan 2018-04-13
  • 打赏
  • 举报
回复
先 a=3; static int a = 1,按对的来就好了
引用 13 楼 qq_24947841 的回复:
[quote=引用 9 楼 lc545126483 的回复:] [quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] 1.java支持向前引用,所以你 先 a=3; static int a = 1就不会错 具体可参考http://blog.51cto.com/androidguy/1230298 2.为啥 a =3可以,而System.out.println(a);不行,参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3[/quote]
tracy1talent 2018-04-13
  • 打赏
  • 举报
回复
声明和定义是两个过程,编译阶段就完成了声明的工作,而定义要等到运行才完成包括内存的分配。
考拉一枚 2018-04-13
  • 打赏
  • 举报
回复
引用 9 楼 lc545126483 的回复:
[quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] 1.java支持向前引用,所以你 先 a=3; static int a = 1就不会错 具体可参考http://blog.51cto.com/androidguy/1230298 2.为啥 a =3可以,而System.out.println(a);不行,参考https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3
lc545126483 2018-04-13
  • 打赏
  • 举报
回复
引用 11 楼 Ragin的回复:
[quote=引用 9 楼 lc545126483 的回复:] [quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] a=3是初始化阶段。。。[/quote] 没声明不能使用我知道,难道没声明就能初始化?
Braska 2018-04-13
  • 打赏
  • 举报
回复
引用 9 楼 lc545126483 的回复:
[quote=引用 8 楼 Ragin的回复:]https://stackoverflow.com/questions/14587910/why-can-you-access-static-field-before-it-is-defined-through-a-method-in-java 如果要使用静态变量的话要先声明。
难道我a=3没有使用a么,它怎么不报错?[/quote] a=3是初始化阶段。。。
加载更多回复(1)

62,628

社区成员

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

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