J. Kevin Robbins wrote:That did it! No warnings, the code works the same, and I feel better about having more robust code in the project.
Depending on exact circumstances, that might not actually fix the issue. If you call an overridable method from your private method (edit: I assume you do; you need to call AddItem
inherited from the parent class), you don't get the warning, but still can get the wrong behavior. Consider:
This code produces the following output:
We can see the value of a final attribute has changed. This is one of the ways this problem manifests itself.
Note: in my IDE, I don't get any warning on this code, but I don't get any even when I call method directly in the constructor - don't know why. Static code checkers, such as FindBugs, should be able to identify this issue in both forms, though.
In my opinion, there are a few options of handling this case:
1) Do nothing. Just document methods that are called from constructors, so that developers are aware what's happening. That's obviously risky, especially if some developers on the team aren't well acquainted with the ramifications of this arrangement.
2) Make the method final in the class that calls the method in its constructor. That is a good solution if the child classes of the problematic class do not need to override the method. It might work for you, if I understand your case well. The code would look like this:
3) Make your entire Child class final. This obviously fixes the issue, but you can't create subclasses.
4) If you don't override the method in your class, you can call the super version of the method in constructor:
Caveat: in your case, someone might want to create a child from your class and override AddItem
to do some additional action. He or she will wonder why his/her overriden method wasn't called when you were adding the items in your constructor calls.
5) Move the logic from your constructor elsewhere. You could create a static method that will create the instance and then call the overridable methods from the outside of the constructor. You don't introduce unwanted side effects, the class is still inheritable and the method isn't final. Applied to your case it might look like this:
This is probably the cleanest solution, if you can't make your class final. The only downside is that the logic that was originally in the constructor isn't inheritable now.
Note: this code mixes JDBC code and UI creation, and I think it isn't a good idea. I'd suggest separating these two pieces of code, having a DAO class that would read from the database into some data class (perhaps just a list of POJO items) and use that list to construct the GUI controls. But this is unrelated to the issue you've asked about.