эй, я видел эту тему здесь: Могу ли я вызвать методы в конструкторе в Java?
Мой вопрос нелепый, но немного другой.
Я хочучтобы знать, что происходит, если я вызываю из конструктора из класса A что-то вне этого класса из класса B с this
из A. В моем примере ниже A - JobImpl
, а B - эта очередь в планировщике.
class JobImpl implements Job
{
public JobImpl(Scheduler s, JobHandler runJob, boolean advancedWaitOnCancel, boolean oneShot)
{
this.s = s;
this.runJob = runJob;
this.advancedWaitOnCancel = advancedWaitOnCancel;
this.oneShot = oneShot;
jobReadyPhaser = advancedWaitOnCancel ? new AdvancedCountdownImpl(this) : new AdvancedCountdownNoOp();
this.s.jobs.add(this);
}
}
В моем примере я вызываю два внешних метода / других конструкторов.
Я вызываю конструктор AdvancedCountdownImpl(this)
и добавляю this
в очередь за пределами этого класса.
Я назначаю входной параметр этого конструктора конечным полям. Я мог бы переместить это this.s.jobs.add(this)
немного выше, до назначения этих последних полей;это не проблема - со стороны компилятора.
В этой связанной теме я видел, что могут быть проблемы с наследованием.
Из моего класса JobImpl существует несколько подклассов (не толькоиз моего "интерфейса", но на самом деле из JobImpl ^^)
Интересная вещь - jobs.add(this)
. Возможно, что до завершения конструктора другой поток обращается к этому списку и что-то делает со своим содержимым. Чтобы этот поток мог получить доступ к этому Job
и что-то с этим сделать.
Если я переместлю в этот конструктор эту строку с jobs.add(this)
немного выше, после this.s = s
, то может случиться так, чтодругие заключительные поля не создаются. Это правильно?
В таком случае, что бы сделала моя программа - тогда?
Хорошо, теперь я поместил this.s.jobs.add(this)
в конец этого конструктора. Так что я думаю, что последние поля будут созданы
Или нет? Может быть, компилятор меняет строки в целях оптимизации?
Хорошо, если компилятор этого не сделает, тогда мой JobImpl
в ЛЮБОМ! время, когда другой поток получит доступ через очередь, к которой полностью задан мой Job?
Или у меня все еще будут проблемы с наследованием ?, если этот другой поток получит доступ к некоторым методам, которые будут перезаписаны?
Разве я не должен помещать эти задания в очередь в конструкторе, но на втором шаге? Итак, вызов конструктора после этого вызова инициализации?
Есть ли лучшее решение?
Когда я могу это сделать, что я сделал? - нажать this
от конструктора наружу? Может быть, если нет другого потока?
My jobReadyPhaser
также является последним полем. Так что я должен сконструировать это AdvancedCountdownImpl(this)
в конструкторе.
Но я думаю, что здесь я на 100% безопасен, потому что AdvancedCountdownImpl
не делает с этим this
что-то еще, но сохраняет его в своем собственномполе, для последующего использования.