1700441180
1700441181
}
1700441182
1700441183
//父类
1700441184
1700441185
class Father{
1700441186
1700441187
Father(){
1700441188
1700441189
new Other();
1700441190
1700441191
}
1700441192
1700441193
}//子类
1700441194
1700441195
class Son extends Father{
1700441196
1700441197
public void doSomething(){
1700441198
1700441199
System.out.println(“Hi, show me something”);
1700441200
1700441201
}
1700441202
1700441203
}
1700441204
1700441205
//相关类
1700441206
1700441207
class Other{
1700441208
1700441209
public Other(){
1700441210
1700441211
new Son();
1700441212
1700441213
}
1700441214
1700441215
}
1700441216
1700441217
这段代码并不复杂,只是在构造函数中初始化了其他类,想想看这段代码的运行结果是什么?是打印“Hi, show me something”吗?
1700441218
1700441219
答案是这段代码不能运行,报StackOverflowError异常,栈(Stack)内存溢出。这是因为声明s变量时,调用了Son的无参构造函数,JVM又默认调用了父类Father的无参构造函数,接着Father类又初始化了Other类,而Other类又调用了Son类,于是一个死循环就诞生了,直到栈内存被消耗完毕为止。
1700441220
1700441221
可能有读者会觉得这样的场景不可能在开发中出现,那我们来思考这样的场景:Father是由框架提供的,Son类是我们自己编写的扩展代码,而Other类则是框架要求的拦截类(Interceptor类或者Handle类或者Hook方法),再来看看该问题,这种场景不可能出现吗?
1700441222
1700441223
那有读者可能要说了,这种问题只要系统一运行就会发现,不可能对项目产生影响。
1700441224
1700441225
那是因为我们在这里展示的代码比较简单,很容易一眼洞穿,一个项目中的构造函数可不止一两个,类之间的关系也不会这么简单的,要想瞥一眼就能明白是否有缺陷这对所有人员来说都是不可能完成的任务,解决此类问题的最好办法就是:不要在构造函数中声明初始化其他类,养成良好的习惯。
1700441226
1700441227
1700441228
1700441229
[
上一页 ]
[ :1.70044118e+09 ]
[
下一页 ]