Java 解决容易出错的构造函数泄漏此警告针对调用其他构造函数的构造函数

Java 解决容易出错的构造函数泄漏此警告针对调用其他构造函数的构造函数,java,constructor,errorprone,Java,Constructor,Errorprone,我们有几个类具有共享构造函数逻辑的常见模式: public X(E... processors) { this(ImmutableList.copyOf(processors)); } public X(Collection<E> processors) { this.processors = ImmutableList.copyOf(processors); } 如果这个实现模式实际上是不安全的,我相信它可以相当容易地重构为静态方法,但我想问题是,它是不安全的吗

我们有几个类具有共享构造函数逻辑的常见模式:

public X(E... processors)
{
    this(ImmutableList.copyOf(processors));
}

public X(Collection<E> processors)
{
    this.processors = ImmutableList.copyOf(processors);
}
如果这个实现模式实际上是不安全的,我相信它可以相当容易地重构为静态方法,但我想问题是,它是不安全的吗?也许这不是编译器检查想要检测的?

定义问题:

在构造函数的执行过程中,创建新的 实例可供其他代码访问。实例的字段,包括 最终字段,可能尚未初始化,正在执行实例 方法可能会产生意外的结果

…从您的代码来看,您没有违反规则,Java文档也提到过,这是一个误报,报告了相同的问题

顺便说一句,您可以在构造函数中添加
@SuppressWarnings(“ConstructorLeaksThis”)
以抑制错误,或者在不使用
@SuppressWarnings
的情况下重构代码以防止隐藏的错误。

定义问题:

在构造函数的执行过程中,创建新的 实例可供其他代码访问。实例的字段,包括 最终字段,可能尚未初始化,正在执行实例 方法可能会产生意外的结果

…从您的代码来看,您没有违反规则,Java文档也提到过,这是一个误报,报告了相同的问题


顺便说一句,您可以在构造函数中添加
@SuppressWarnings(“ConstructorLeaksThis”)
以抑制错误,或者在不使用
@SuppressWarnings
的情况下重构代码以防止隐藏的bug。

我很确定这是个bug

通常,此错误意味着您传递了对当前未构造对象的引用,即
someList.add(this)


然而,构造函数链接是非常好的,而且通常是一种很好的做法。

我很确定这是一个bug

通常,此错误意味着您传递了对当前未构造对象的引用,即
someList.add(this)


但是,构造函数链接非常好,而且通常是一种很好的做法。

我看到的唯一问题是,不需要创建两个
ImmutableList
@tsolakp copyOf实例,如果它已经是
ImmutableList
,则返回相同的实例,但这实际上只是一个示例,你也可以有一个构造函数,它用一个以上的参数调用重载,你会得到同样的警告。我在javadoc中没有看到任何地方提到它。@tsolakp我相信它属于它所说的位“尽管有方法名,但此方法试图在安全的情况下避免实际复制数据。在何种情况下将执行或不执行副本,均未记录在案,可能会发生变化。“我现在看到的版本中的实现细节是,如果ImmutableList作为另一个列表的部分视图返回,我看到的唯一问题是,如果
不可变列表
@tsolakp copyOf已经是一个
不可变列表
,那么创建两个实例就没有必要了@tsolakp copyOf会返回同一个实例,但这实际上只是一个示例,你也可以有一个构造函数,它用一个以上的参数调用重载,你会得到同样的警告。我在javadoc中没有看到任何地方提到它。@tsolakp我相信它属于它所说的位“尽管有方法名,但此方法试图在安全的情况下避免实际复制数据。在何种情况下将执行或不执行副本,均未记录在案,可能会发生变化。“我现在看到的版本中的实现细节是,如果ImmutableList作为另一个列表的部分视图返回,它仍然会进行复制。我可能会直接将其归档,并将其真正修复。总的来说,我不喜欢
@SuppressWarnings
,因为后来,有人添加了实际上违反警告的代码,而你永远也不会发现,因为它被抑制了。几乎每次我发现一些真正的WTF bug,如果有人发出警告,就会发现有人在该区域设置了一个抑制。是的,你可能会报告一个bug,我在我的回答中添加了一个类似问题的链接。这似乎是完全相同的问题,所以我只想订阅它。我想知道为什么我一开始找不到关于它的罚单…(还有,如果有人在我抑制警告后在同一个构造函数中添加了实际泄漏
this
的代码会怎么样?这就是为什么我说我不喜欢抑制…)我可能会直接向他们提交并得到真正的修复。总的来说,我不喜欢
@SuppressWarnings
,因为后来,有人添加了实际上违反警告的代码,而你永远也不会发现,因为它被抑制了。几乎每次我发现一些真正的WTF bug,如果有人发出警告,就会发现有人在该区域设置了一个抑制。是的,你可能会报告一个bug,我在我的回答中添加了一个类似问题的链接。这似乎是完全相同的问题,所以我只想订阅它。我想知道为什么我一开始找不到关于它的票证…(还有,如果有人在我抑制警告后在同一个构造函数中添加了实际上泄漏了
这个
的代码会怎么样?这就是为什么我说我不喜欢抑制…)
.../X.java:61: error: [ConstructorLeaksThis] Constructors should not pass the 'this' reference out in method invocations, since the object may not be fully constructed.
        this(ImmutableList.copyOf(processors));
        ^
    (see http://errorprone.info/bugpattern/ConstructorLeaksThis)