Pregunta

Assuming the constructor runs in the client part of the code (the one that gets translated to javascript). The callback method onSuccess does modify the instance variables of the class. The callback is implemented as an anonymous class so the instance of the outer class can be accessed by using OuterClass.this.

Normally in plain Java we should not do something like this because by doing so, 'this' reference can escape before the object construction is finished.

But does it also hold for the case when Java code is translated to Javascript? I assume that javascript code is executed by a single thread in a web browser so this should not be an issue (single thread => no visibility problems)?

¿Fue útil?

Solución 2

AsyncCallback, by itself, is just a class. When you send an RPC request in production mode, you are guaranteed that the result will come in asynchronously through XmlHttpRequest; in compiled javascript it is 100% impossible to leak the reference before construction is finished, as the callback will get called in a separate javascript execution stack.

In gwt-dev mode, however, things that should be asynchronous aren't always so. Personally, I abandoned gwt-dev over super-dev-mode, and only use gwt-dev when I really need java debugger, so I can't tell you for sure if it will be immune to construction problems or not (test it and find out!).

If you are not sending any requests in the constructor, you will be 100% safe. Just creating the async callback will only lead to problems if you are subsequently accessing OuterClass.this in unsafe ways, regardless of the classes involved.

Otros consejos

On the one hand, you're right - the problem cannot be triggered by a separate thread, because JavaScript is single threaded.

Callback events will definitely be handled by an event handler that starts after the current event handler (the one which constructs the current object) has finished. So they will only ever see the fully constructed object.

On the other hand, you generally don't need threads to exploit the basic problem. Here's a simple example:

final A a = new A();
final B b = new B(a);
public class A {

  private B b;

  public void setB(final B b) {
    this.b = b;
  }

  public void letBSaySomething() {
    b.saySomething();
  }
}
public class B {

  private A a;
  private final int some;

  public B(final A a) {
    this.a = a;
    a.setB(this);

    a.letBSaySomething();
    some = 55;
    a.letBSaySomething();
  }

  public void saySomething() {
    RootPanel.get().add(new Label("Hello " + some));
  }
}

This results in the output

Hello 0
Hello 55

(although 'some' is final). This happens both in GWT (compiled/uncompiled) and plain Java programs.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top