将此(在构造函数中)泄露给对象本身

时间:2015-07-07 03:29:00

标签: java

我从其他问题中了解到,如果另一个对象有机会利用仍处于构造中的对象(我们泄露的对象),如何泄漏this可能是不安全的,无论是单线程还是单线程多线程环境。

我的问题是,如果我将对象泄露给自己会怎样?

public Category(int id, String name) {
    this.id = id;
    this.name = name;
    this.idPadre = this;
}

请注意,在构造函数的最后一行中,我正在泄漏对象。这通常仍然是不安全的,因为构造函数可以继承并在执行父类的构造函数之后使用更多代码进行super()调用(这是我写过的),从而使泄漏线不是施工过程的最后一行。

但是,如果继承类仍然在其构造函数中,那么即使它正在泄漏正在构造的对象并且更多行代码跟随泄漏行,它仍然是不安全的,考虑到唯一可以访问的上下文泄露的对象是该对象的构造函数(仍然没有完成执行)?

问题也代表多线程环境。我很确定它是线程安全的,因为对象被泄露给它自己(它的一个字段),并且在构造函数完成之前无法访问字段。根据能够访问泄漏对象的构造函数,构造函数只能在一个线程中运行,因此它应该是线程安全的(如果它在这个问题的第一部分引用的方面也是安全的)。 / p>

我想以一般方式提出这个问题。但这是我发现这种情况的背景。该类是一个实体类,我使用ORMLite持久保存到关系数据库。数据库表有一列,其值指向该条目的类别的父级。如果类别没有父类,则它本身就是它的父类(列idPadre的值与列标识的值相同)。使用ORMLite注释编写实体类时,这意味着该对象具有对自身的引用。 ORMLite的使用以及我希望尽可能简化所有实体类的愿望是我不首先倾向于用工厂方法解决这个问题的原因。

2 个答案:

答案 0 :(得分:4)

这是非常安全的,因为你没有'泄漏'任何东西。在施工过程中将“此”传递到外部是不安全的。只要你不这样做,或者在其他地方传递this.idPadre,就没有“泄漏”,也无法让其他代码访问你的部分初始化实例。

答案 1 :(得分:3)

当您将this分配给字段idPadre时,如果您已经拥有对该对象的引用以访问该字段,则只能访问该对象。换句话说,你没有泄露构造函调用者已经泄露的任何东西,可以这么说。

泄漏this通常意味着在构造函数完成之前从构造函数中泄漏对象的引用。从构造函数中泄漏this的问题是字段可能尚未正确初始化。在这种情况下,这不是问题,因为一旦构造函数完成,你只能访问idPadre(除非你之前已经在构造函数中泄露了this - 但是你已经泄漏了this!)

如果idPadre是一个静态字段,那么这确实会泄漏this,因为其他线程可以随时访问静态字段。