I don't understand the "this-escape" warning under this context

Archie Cobbs archie.cobbs at gmail.com
Sat Sep 30 14:04:55 UTC 2023


On Sat, Sep 30, 2023 at 12:55 AM David Alayachew <davidalayachew at gmail.com>
wrote:

> package Paint;
>
> import javax.swing.*;
>
> public class GUI
> {
>
>    private final JFrame frame;
>
>    public GUI()
>    {
>
>       this.frame = new JFrame();
>
>       this.frame.add(this.createBottomPanel());
>
>    }
>
>    private final JPanel createBottomPanel()
>    {
>
>       final JButton save = new JButton();
>
>       save
>          .addActionListener
>          (
>             actionEvent ->
>             {
>
>                this.toString();
>
>             }
>
>          )
>          ;
>
>       return null;
>
>    }
>
> }
> ```
> Can someone help me understand the what, why, and how of this warning? I
> don't understand it at all.
>

First note there is really only one warning, even though the compiler says
"2 warnings". It's just trying to show you the full "stack trace" where the
leak occurs.

Here's the sequence of events that the compiler is fretting about:

   1. GUI constructor invokes this.createBottomPanel()
   2. createBottomPanel() creates a lambda that, if/when it ever gets
   invoked, could invoke this.toString()
   3. createBottomPanel() passes this lambda to save.addActionListener()
   4. save.addActionListener() (which the compiler does NOT inspect) might
   possibly invoke the lambda
   5. the lambda invokes GUI.toString()

Since your class GUI is public and non-final, it could be subclassed, and
since GUI.toString() is not final, that subclass could override toString().

So in summary the compiler is deducing that it's *possible* (in theory)
that a subclass could unwittingly operate on an incompletely initialized
object - i.e., a 'this' escape.

Note that the compiler only looks at the one file you are compiling. It
does not try to inspect JButton to see what addActionListener() actually
does. So for step 4 it just assumes the worst case, which is that
addActionListener() immediately invokes the lamba. Of course you and I know
this is not actually how it behaves.

So is this a "false positive"?

Yes in the sense that we "know" JButton.addActionListener() doesn't
immediately invoke the lambda. But in general the compiler can't make
assumptions about the behavior of other classes, even those that are part
of the current compilation, because you could swap out class files at
runtime and change that behavior.

So all inferences are made based only on what can be deduced from the one
file you are currently compiling. In that sense, this warning is not a
false positive.

-Archie

-- 
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230930/f24b0599/attachment.htm>


More information about the compiler-dev mailing list