Может ли EventActionDispatcher опубликовать «this» до завершения работы конструктора? - PullRequest
0 голосов
/ 24 марта 2009

Рекомендованный способ использования EventActionDispatcher заключается в следующем (согласно документации API @ http://struts.apache.org/1.2.9/api/org/apache/struts/actions/EventActionDispatcher.html)

   public class MyCustomAction extends Action {

       protected ActionDispatcher dispatcher = new EventActionDispatcher(this);

       public ActionForward execute(ActionMapping mapping,
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response)
                           throws Exception {
           return dispatcher.execute(mapping, form, request, response);
       }
   }

Публикует ли эта команда ссылку на "this" до выхода из конструктора? Каковы правила, регулирующие назначения полей вне методов.

Заранее спасибо.

С уважением, LES

Ответы [ 2 ]

2 голосов
/ 24 марта 2009

Потребовалось 3 человека в неделю, чтобы разыскать один раз ... "this" может быть нулевым, если EventActionDispatcher запускает поток или делает что-либо с потоком, который вызывает использование "this".

НИКОГДА передайте "this" до завершения работы конструктора, или вы рискуете, что "this" будет нулевым в случае многопоточности.

Что я делаю, так это добавляю метод "init ()" к моим классам, который должен делать подобные вещи и вызывать его после создания объекта.

Есть и другие тонкости, такие как этот пример:

public abstract class Foo
{
    protected Foo()
    {
        car();
    }

    public abstract void car();
}

public class Bar 
    extends Foo
{
    private final String value;

    public Bar(final String str)
    {
        value = str;
    }

    public void car()
    {
        // this line will crash because value is null
        System.out.println(value.charAt(0));
    }
}

public class Main
{
    public static void main(final String[] argv)
    {
        final Foo foo;

        foo = new Bar("Hello");
    }
}

Самое безопасное, что нужно сделать:

  • никогда не используйте "this" до того, как конструктор вернул
  • никогда не вызывать какие-либо классы, собственные нестатические методы, из конструктора, если класс не является окончательным.

Вы можете вызывать финальные методы, но вы должны быть уверены, что они не вызывают переопределяемые методы ... и это может означать, что что-то сломается ... так что безопаснее этого не делать.

1 голос
/ 24 марта 2009

В этом случае (я надеюсь) this не публикуется. Он все еще доступен только через экземпляр MyCustomAction.

В Java (я считаю, что C # делает обратное), инициализация поля экземпляра и инициализаторы экземпляра вызываются непосредственно перед (неявным или явным) вызовом супер-конструктора. Поэтому вы можете использовать this при инициализации поля, хотя ваш объект может не закончить построение.

Публикация this, так что это достижимо снаружи объекта во время строительства, как правило, плохая идея.

...