Leaking This in Constructor Warning

Leaking this in constructor warning

Since you make sure to put your instances.add(this) at the end of the constructor you should IMHO be safe 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. Like Terrel mentioned in his comments, the following annotation does it as of NetBeans 6.9.1:

@SuppressWarnings("LeakingThisInConstructor")

(*) Update: As Isthar and Sergey pointed out there are cases where "leaking" constructor code can look perfectly safe (as in your question) and yet it is not. Are there more readers that can approve this? I am considering deleting this answer for the mentioned reasons.

Java leaking this in constructor

Leaking the this reference in the constructor (not controller) is dangerous, especially in a multithreaded environment. This is because the object is not fully constructed until the constructor call finishes. Leaking this from the constructor thus means that the external world gets access to an object which is not yet fully constructed. This may not necessarily lead to problems in a a single-threaded program (although it is possible, but the problem is much more obvious in this case). But if this is leaked to other threads, they can actually try to do something with the object before its construction is finished, which leads to subtle and hard to find bugs.

Leaking 'this' in constructor warning should apply to final classes as well as open ones?

tl;dr: https://youtrack.jetbrains.com/issue/KT-22044 is a good fit regarding this issue.

I will cite what Intellij IDEAs inspection called "Leaking 'this' in constructor" says about this:

This inspection reports dangerous operations inside constructors including:

  • Accessing a non-final property in constructor
  • Calling a non-final function in constructor
  • Using this as a function argument in a constructor of a non-final class

These operations are dangerous because your class can be inherited, and a derived class is not yet initialized at this moment. Typical example:

abstract class Base {
val code = calculate()
abstract fun calculate(): Int
}

class Derived(private val x: Int) : Base() {
override fun calculate() = x
}

fun testIt() {
println(Derived(42).code) // Expected: 42, actual: 0
}

I think that there should be warning nonetheless as you were able to access a non-initialized variable. The reason: the compiler already disallows direct access to uninitialized variables, i.e. the following will not compile:

class Demo {
val some : Int
init {
println(some) // Variable 'some' must be initialized

but accessing it indirectly compiles and shows the default value of the variable type:

class Demo2 {
val some : Int
val someString : String
init {
fun Demo2.indirectSome() = some
fun Demo2.indirectSomeString() = someString
println(indirectSome()) // prints 0
println(indirectSomeString()) // prints null; and yes.. this can lead to NullPointerExceptions

and there we also have a "leak", basically accessing some before it should ;-)

Leaking this (in constructor) to the object itself

When you assign this to the field idPadre it is only possible to access the object if you already have a reference to the object in order to access the field. In other words you haven't leaked anything that hasn't already been leaked by the constructor caller, so to speak.

Leaking this usually means leaking a reference to the object from the constructor before the constructor has finished. The problem with leaking this from the constructor is that fields might not have been initialized properly. This is not an issue in this case since you can only access idPadre once the constructor has finished (unless you already leaked this earlier in the constructor - but then you already leaked this!)

If idPadre was a static field then this would indeed be leaking this since other threads can access static fields at any time.

java - how to fix the leaking this in constructor warning

The constructor will return a reference to the dialog. Have the panel set the variable itself once the instance is created.

public class MyJPanel extends JPanel {
private JDialog dialog;

public MyJPanel(Frame aFram) {
dialog = new MyJDialog(aFrame, true);
}
}

Also, that code will not work because getThis() is not a static method, thus requires a reference to a MyJPanel instance.

Leaking this constructor

I think there is a leak in the constructor. You are passing "this" before the complete initiallization of the object.

Using this in the constructor of a final class

Leaking this in constructor warning has a discussion of this Netbeans warning.

If pendingTasksByKey has a corresponding remove somewhere during the life cycle of these classes I'd say you are right, Netbeans is being picky.



Related Topics



Leave a reply



Submit