<div dir="ltr"><div class="gmail_default" style="font-family:monospace">Hello Rémi and Archie,<br><br>Thank you both for your response!<br><br>> Rémi:<br>> The first error seems to be a false positive because as<br>> you said the method createBottomPanel() is private<br><br>Thank you for acknowledging this -- this is the part that threw me off and prompted me to make this post. It appeared to me to be a false positive as well, but I figured that I was missing info.<br><br>> Rémi:<br>> (BTW, all private methods can not be overriden so<br>> declaring a private method final is not really useful).<br><br>Fair. I did that out of desperation, since I truly did not understand what was happening.<br><br>> Rémi:<br>> The second error is due to the fact that the lambda can<br>> be called before the end of the constructor, the compiler<br>> is not smart enough to know if this is the case or not.<br>> <br>> Archie:<br>> Note that the compiler only looks at the one file you are<br>> compiling. It does not try to inspect JButton to see what<br>> addActionListener() actually does. So for step 4 it just<br>> assumes the worst case, which is that addActionListener()<br>> immediately invokes the lamba. Of course you and I know<br>> this is not actually how it behaves.<br><br>I see what you both are saying. At first glance, this feels like it cheapens the warning, but after thinking about it more, I think that assumption is only really applicable to the small scale. Once you start designing massive applications, this "false positive" becomes a lot more plausible.<br><br>> Rémi:<br>> The usual workaround is to create the GUI inside static<br>> methods, the constructor being a static factory named by<br>> example createGUI() and createBottomPanel() being<br>> declared static.<br>> <br>> If you need objects, pass them as parameter of the static<br>> methods, so they are known to be fully initialized.<br>> <br>> Apart for the bugs with subclassing, the problem of<br>> publication in a concurrency context, having a<br>> constructor that escapes "this" also prevents a class to<br>> be a value class.<br><br>Thanks for the solutions and context.<br><br>Knowing that this is critical for value objects solidifies the warnings usefulness to me. I have several projects that are throwing this warning, but knowing what I get in return for fixing this warning makes fixing all of those projects completely worth it.<br><br>And the solutions presented are all easy refactors, so thank you for pointing me to them.<br><br>I do have a request -- documentation on this particular warning, as well as the info you both brought up here, is difficult to find. Could we get some documentation or an article by Oracle going in-depth about this warning and how to avoid it?<br><br>My anecdotal justification for why this warning deserves this more than any other warning that doesn't already have one is that over 40% of my projects are now throwing this warning. This is the first time that upgrading to a new JDK has caused this many warnings to show up in such a large percentage of my projects. Furthermore, remedying this isn't immediately obvious, not just because of lambdas, but because you must consider the "overridability" of all methods that receive a reference to this -- including library methods! That can be a difficult concept to wrap your head around with the minimal documentation I found [1][2], so some more documentation/guidance would be appreciated. Finally, if this is going to be useful to us in utilizing value classes, then that is a solid reason why this should further be documented.<br><br>I now have enough information to solve my current problem, but I'm sure others would appreciate easy access to this information too.<br><br>Thank you for both for your time and help!<br>David Alayachew<br><br>[1]=javac --help-lint<br>[2]=<a href="https://docs.oracle.com/en/java/javase/21/docs/specs/man/javac.html#examples-of-using--xlint-keys">https://docs.oracle.com/en/java/javase/21/docs/specs/man/javac.html#examples-of-using--xlint-keys</a><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Sep 30, 2023 at 10:05 AM Archie Cobbs <<a href="mailto:archie.cobbs@gmail.com">archie.cobbs@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Sat, Sep 30, 2023 at 12:55 AM David Alayachew <<a href="mailto:davidalayachew@gmail.com" target="_blank">davidalayachew@gmail.com</a>> wrote:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">package Paint;<div style="font-family:monospace"><br>import javax.swing.*;<br><br>public class GUI<br>{<br><br> private final JFrame frame;<br><br> public GUI()<br> {<br> <br> this.frame = new JFrame();<br> <br> this.frame.add(this.createBottomPanel());<br> <br> }<br><br> private final JPanel createBottomPanel()<br> {<br> <br> final JButton save = new JButton();<br> <br> save<br> .addActionListener<br> (<br> actionEvent -><br> {<br> <br> this.toString();<br> <br> }<br> <br> )<br> ;<br> <br> return null;<br> <br> }<br><br>}<br></div><div style="font-family:monospace">```</div><div style="font-family:monospace">Can someone help me understand the what, why, and how of this warning? I don't understand it at all.</div></div></blockquote><div><br></div><div>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.</div><div><br></div></div><div class="gmail_quote">Here's the sequence of events that the compiler is fretting about:</div><div class="gmail_quote"><ol><li>GUI constructor invokes this.createBottomPanel() </li><li>createBottomPanel() creates a lambda that, if/when it ever gets invoked, could invoke this.toString()</li><li>createBottomPanel() passes this lambda to save.addActionListener()</li><li>save.addActionListener() (which the compiler does NOT inspect) might possibly invoke the lambda</li><li>the lambda invokes GUI.toString()</li></ol><div>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().</div><div><br></div><div>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.<br></div><div><br></div><div>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.<br></div><div><br></div><div>So is this a "false positive"?</div><div><br></div><div>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.</div><div><br></div><div>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.<br></div><div><br></div><div>-Archie<br></div></div><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div>
</blockquote></div>