有以下简单java代码:public class Test {
static Test test = new Test("3");
// Test test2 = new Test("5"); static {
System.out.println("1");
} // static Test test = new Test("3"); {
System.out.println("2");
} Test(String s) {
System.out.println(s);
} public static void staticFunction() {
System.out.println("4");
} public static void main(String[] args) {
staticFunction();
}
}运行后打印结果:2
3
1
4当把上边代码的第9行注释去掉,第2行注释起来时,打印结果如下:1
2
3
4最后打印4没问题,问题在于为什么静态当前类的对象与静态块的顺序不同时,首先执行的代码顺序不同,导致结果不同呢???
希望大神可以详细讲解下,谢谢!还有一个额外的问题,当取消上边代码第 3 行的注释时,也就是创建两个当前类对象,一个静态一个非静态,运行后报栈溢出,应该是发生了递归调用,且递归没有出口,具体怎么一个顺序呢?望解答
static Test test = new Test("3");
// Test test2 = new Test("5"); static {
System.out.println("1");
} // static Test test = new Test("3"); {
System.out.println("2");
} Test(String s) {
System.out.println(s);
} public static void staticFunction() {
System.out.println("4");
} public static void main(String[] args) {
staticFunction();
}
}运行后打印结果:2
3
1
4当把上边代码的第9行注释去掉,第2行注释起来时,打印结果如下:1
2
3
4最后打印4没问题,问题在于为什么静态当前类的对象与静态块的顺序不同时,首先执行的代码顺序不同,导致结果不同呢???
希望大神可以详细讲解下,谢谢!还有一个额外的问题,当取消上边代码第 3 行的注释时,也就是创建两个当前类对象,一个静态一个非静态,运行后报栈溢出,应该是发生了递归调用,且递归没有出口,具体怎么一个顺序呢?望解答
解决方案 »
- j2se程序 内存占用情况
- JCheckBox 上下左对齐问题
- JTable----想做个更改选中项后回车后数据后台输出
- JTextArea是否有删除文本的方法?
- 文件操作的难题?
- N个不同整数相加之和为10000的组合个数。
- 如何在JButton或JLabel中设置图标的大小(源图是大图)想设置成工具条按钮大小的?
- 怎样在一个方法里访问另一个方法里的局部变量的数值?急……
- 请问下面代码发生了什么错误?
- char[]型用什么方法可以转换成String型?
- int code = conn.getResponseCode(); 程序貌似卡这里了,怎么解决??谢谢
- 怎么设计利用socket读取PLC信息
1.先执行static Test test = new Test("3");
2.执行new 时,先执行代码快{} 此时为2
3.在执行new Test(“3”),此时打印 3
4.第一句静态部分执行完了,顺序执行静态代码块 打印1
5.最后执行方法staticFunction(),打印4
所以是2 3 1 4 。
=======================================
同理 ,注释第2行 ,还是顺序执行
具体和上方一样
========================================
关于你的报错 还未知,正在研究中
在你所列举的例子中, {} 优先于 static{}执行。注意如果是默认构造函数,static{}优先于{}执行。
第二个问题:出错的原因
(1)执行static Test test = new Test("3");时,会调用构造函数Test(String s) {}
(2)调用构造函数Test(String s) {}时,会调用Test test2 = new Test("5");。 因为new对象,就得将对象的默认属性全部new好,除百把第三行改为 Test test2 = null就不会有这个问题了;
(3)当调用Test test2 = new Test("5");。又会调用构造函数Test(String s) {}, 即程序又跳转到第(1)步。于是进入了死循环,直到StackOverflow
报错问题。
1.由于test 是静态的变量 只是初始化一次,(因为静态变量 只在类加载的时候初始化一次) test 初始化时 会把test2(属于成员变量) 给实例化一次
2.test2 再次实例化 又会实例化 test2 ,,,,此时由于test是静态的,只初始化一次,所以,此时test2进入循环
3.最终导致 进入循环一直循环,引起栈溢出
其实归根结底就是--实例变量是在实例化的时候进行声明初始化
后面的一个问题看了前面两位的答案说实话我也没有搞懂,希望哪位可以解释的清楚点
2.Exception是因为无限初始化Test2造成的
首先把代码简化下,找到报错的真正原因:
public class Test {
Test test2 = new Test("5");
Test(String s) {
System.out.println(s);
}
public static void main(String[] args) {
new Test("1");
}
}
运行上面的代码,你会发现报错依然存在,所以这个报错和什么静态代码的无关,关键在于你陷入初始化的死循环了。
当Test实例化时,会执行【Test test2 = new Test("5");】,这句话本身又要实例化一个Test,然后又要执行【Test test2 = new Test("5");】,然后你懂的。个人建议不要搞这些乌七八糟的代码,除非是程序实际遇到问题,否则劳民伤财未必能有成效。