提问人:davidalayachew 提问时间:9/28/2023 最后编辑:Mark Rotteveeldavidalayachew 更新时间:10/4/2023 访问量:361
什么是“逃逸”警告,我该如何处理?
What is a "this-escape" warning, and how do I deal with it?
问:
我很难找到这方面的资源,然而,当我在最新的 Java (21) 上编译代码时,我的许多类都遇到了这个错误。
下面是一个代码示例。
public class ThisEscapeExample
{
public Object o;
public ThisEscapeExample()
{
this.overridableMethod();
}
public void overridableMethod()
{
this.o = new Object();
}
}
这是我的编译命令。
javac -Xlint:all ThisEscapeExample.java
ThisEscapeExample.java:9: warning: [this-escape] possible 'this' escape before subclass is fully initialized
this.overridableMethod();
^
1 warning
答:
5赞
davidalayachew
9/28/2023
#1
以下是引入此新警告的 JDK Bug System 条目 - https://bugs.openjdk.org/browse/JDK-8299995
长话短说,警告是警告你,当一个子类可能能够使用一个在超类的构造函数中也被调用的方法时。this-escape
@Override
这很危险,因为重写构造函数中使用的方法允许子类在子类初始化期间无意中引入错误。如果该方法依赖于尚未创建的状态,因为我们仍在超级构造函数中怎么办?毕竟,在调用超级构造函数之前,您不能在子类的构造函数中执行任何操作(目前)。
有几种方法可以解决这个问题。
在构造函数中仅使用无法重写的方法。
static
方法。final
方法。private
方法。
使类本身 .
final
不要一开始就传入/使用,而是传入你需要的特定组件。
this
this
- 基本上,停止懒惰,明确自己的需求。不要只传入你的上帝对象——只传入你需要的特定属性。
请注意 - 这些规则以递归方式应用。这意味着,当您在构造函数中调用方法时,该方法不仅必须“不可重写”,而且该方法传递到的方法也必须与上述规则之一匹配。如果顶级方法不可重写,但其中某个方法可重写,并且该方法在其作用域内,则编译时将收到错误。下面是一个示例。this
this
this-escape
import javax.swing.*;
public class GUI
{
private final JFrame frame;
public GUI()
{
this.frame = new JFrame();
this.frame.add(this.createBottomPanel());
}
//final! Does that mean we are safe?
final JPanel createBottomPanel()
{
final JButton save = new JButton();
save
.addActionListener
(
/*
* No. We get the warning here at the start of this lambda.
* The reason is because we have given this lambda the
* ability to call this.toString(), and we don't know when
* it will do that. Maybe now, maybe later. But if it does
* it now, then we could end up doing things before the
* object is fully created. And if that were to happen, then
* that would be a this-escape. So, the warning occurs here,
* to let you know that it is possible.
*/
actionEvent ->
{
this.toString();
}
)
;
return null;
}
}
评论