2015-07-07 2 views
3

Я понимаю из других вопросов здесь, в SO, как утечка this может быть опасным, если другой объект когда-либо получит возможность использовать объект, который все еще находится в строительстве (тот, который мы просочились) как в однопоточных, так и в многопоточных средах.Утечка этого (в конструкторе) самого объекта

Мой вопрос: что, если бы я просачивал объект себе?

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

Обратите внимание, что в последней строке конструктора я просачиваю объект. Обычно это будет небезопасно, поскольку конструктор может быть унаследован и использован с вызовом super() с большим количеством кода, следующего за исполнением конструктора родительского класса (это я написал), тем самым делая просачивающуюся линию не последней строкой процесс строительства.

Однако, если класс наследования по-прежнему находится в его конструкторе, то даже если он просачивается создаваемый объект, и больше строк кода следует за протекающей линией, будет ли оно по-прежнему небезопасным, учитывая, что единственный контекст, который может получить доступ просочившийся объект - это конструктор объекта (который еще не закончил выполнение)?

Вопрос также относится к многопоточным средам. Я вполне уверен, что он будет потокобезопасным, поскольку объект просачивается сам по себе (одно из его полей), и поля не могут быть доступны до завершения конструктора. Поскольку конструктор может получить доступ к просочимому объекту, конструктор работает только в одном потоке, поэтому он должен быть потокобезопасным (если он также безопасен в аспекте, к которому относится первая часть этих вопросов).

Я хочу задать этот вопрос в общем виде. Но вот контекст, в котором я нашел это событие. Класс - это класс сущностей, который я сохраняю в реляционной базе данных с использованием ORMLite. В таблице базы данных есть столбец, значение которого указывает на родительский элемент этой категории. Если в категории нет родителя, он сам является родительским (значение столбца idPadre совпадает с значением идентификатора столбца). При написании класса сущности с аннотациями ORMLite это означает, что объект имеет ссылку на себя. Использование ORMLite и мое желание максимально упростить все классы сущностей являются причинами, по которым я не склонен сначала решать этот вопрос с помощью заводского метода.

+4

Это не утечка; вы не помещаете его туда, где любой другой код или поток могут получить от него. –

+0

Да, слушайте архитектора java-языка при оракуле, p –

+0

«Небезопасно» просто означает «более вероятно, чтобы кто-то допустил ошибку». Если вы не пропустите «это» вне конструктора, то никто не может совершить определенный тип ошибки. Если вы установите поле «this», то люди, которые пишут подклассы, могут ошибаться, но никто другой. Если вы полностью протекаете «это» вне объекта, то любой, кто использует ваш класс, может сделать msitake. – immibis

ответ

2

При назначении this в поле idPadre можно получить доступ к объекту, если у вас уже есть ссылка на объект, чтобы получить доступ к полю. Другими словами, вы не пропустили ничего, что еще не было пропущено вызывающим конструктором, так сказать.

Утечка this обычно означает утечку ссылки на объект от конструктора до завершения конструктора. Проблема с утечкой this от конструктора состоит в том, что поля, возможно, не были правильно инициализированы. Это не является проблемой в этом случае, так как вы можете получить доступ только idPadre после того, как конструктор закончил (если вы уже не просочилась this ранее в конструкторе - но тогда вы уже просочилась this)

Если idPadre было статическое поле, то это действительно будет утечка this, поскольку другие потоки могут получить доступ к статическим полям в любое время.

+0

Я вижу. Спасибо вам за разъяснение! – Blueriver

4

Это совершенно безопасно, так как вы не «утечка» чего-либо. Небезопасно передавать «это» где-то внешнее во время строительства. До тех пор, пока вы этого не сделаете, или передайте this.idPadre где-то еще, нет «утечки», и нет другого способа получить доступ к вашему частично инициализированному экземпляру.

Смежные вопросы