views:

295

answers:

3

I'd like to avoid (most of the) warnings of Netbeans 6.9.1, and I have a problem with the 'Leaking this in constructor' warning.

I understand the problem, calling a method in the constructor and passing "this" is dangerous, since "this" may not have been fully initialized.

It was easy to fix the warning in my singleton classes, because the constructor is private and only called from the same class.

Old code (simplified):

private Singleton() {
  ...
  addWindowFocusListener(this);
}

public static Singleton getInstance() {

  ...
  instance = new Singleton();
  ...
}

New code (simplified):

private Singleton() {
  ...
}

public static Singleton getInstance() {

  ...
  instance = new Singleton();
  addWindowFocusListener( instance );
  ...
}

This fix is not working if the constructor is public and can be called from other classes. How is it possible to fix the following code:

public class MyClass {

  ...
  List<MyClass> instances = new ArrayList<MyClass>();
  ...

  public MyClass() {
    ...
    instances.add(this);
  }

}

Of course I want a fix which does not require to modify all my codes using this class ( by calling an init method for instance).

+2  A: 

Since you make sure to put your instances.add(this) at the end of the constructor you should IMHO be save to tell the compiler to simply suppress the warning. A warning, by its nature, doesn't necessarily mean that there's something wrong, it just requires your attention.

If you know what you're doing you can use a

@SuppressWarnings(...)

annotation. However I googled for the string to use to denote this kind of warnings and unfortunately didn't find any, e.g. in http://www.thebuzzmedia.com/supported-values-for-suppresswarnings/.

You could still do a

@SuppressWarning("all")

But that's quite unsafe then of course, because it'll also suppress warnings that would actually need your attention/correction and don't relate to the use of "this" at all.

chiccodoro
This is not a standard java warning, this is a Netbeans-warning. So adding @SuppressWarnings does not help.
asalamon74
@asalamon: I see. Tant pis. And netbeans in turn, doesn't it provide any option to turn off specific warnings? Eclipse does.
chiccodoro
I can turn off all the 'leaking this in constructors' warnings. I don't know how to turn it off only in a single class.
asalamon74
@asalamon: Got it. And would netbeans even ignore the @SuppressWarning("all")? For depending on the interpretation "all" could include the netbeans warnings as well. Sorry for not being more precise, I never worked with netbeans...
chiccodoro
+3  A: 

The best options you have :

  • Extract your WindowFocusListener part in another class (could also be inner or anonymous) . The best solution, this way each class has a specific purpose.
  • Ignore the warning message.

Using a singleton as a workaround for a leaky constructor is not really efficient.

Colin Hebert
The class in the first example was already a Singleton.
asalamon74
@asalamon74, but I suppose that the second wasn't. Wanting a singleton with a public constructor is a non-sense, so I guessed you tried to apply the singleton pattern as a workaround.
Colin Hebert
Of course I don't want a Singleton with a public constructor. I just wanted to show an example where I was able to fix the problem (this was the Singleton) and a different example where I was unable to fix it (this is the non-Singleton example).
asalamon74
@asalamon74, Ho, then I didn't understood how you got to the singleton solution. Anyway, as I said in my answer, you should extract your listener, that's the best way.
Colin Hebert
+3  A: 

This is a good case of where a Factory that created instances of your class would helpful. If a Factory was responsible for creating instances your class, then you would have a centralized location where the constructor is called, and it would be trivial to add a required init() method to your code.

Regarding your immediate solution, I would suggest that you move any calls that leak this to the last line of your constructor, and then suppress them with an annotation once you've "proved" that it is safe to do so.

In IntelliJ IDEA, you can suppress this warning with the following comment right above the line:
//noinspection ThisEscapedInObjectConstruction

Shakedown