Ref - See Guideline 6-5: Do not trust identity equality when overridable on input reference objects
http://jroller.com/tackline/entry/user_supplied_objects_may_not
Noncompliant Code Example
How many items are there in layouts in the end?
public class Widget { private int noOfComponents; public Widget(int noOfComponents) { this.noOfComponents = noOfComponents; } public int getNoOfComponents() { return noOfComponents; } public void setNoOfComponents(int noOfComponents) { this.noOfComponents = noOfComponents; } // Also overrides hashCode() (code is omitted) ... public boolean equals(Object o) { if (o == null || !(o instanceof Widget)) { return false; } // check for negative components if (noOfComponents < 0) { return false; } Widget widget = (Widget) o; return this.noOfComponents == ((Widget) o).getNoOfComponents(); } } public class Navigator extends Widget { public Navigator(int noOfComponents) { super(noOfComponents); } @Override public boolean equals(Object o) { if (o == null) { return false; } return true; } } public class LayoutManager { private Set<Widget> layouts = new HashSet<Widget>(); public void addWidget(Widget widget) { if (!layouts.contains(widget)) { layouts.add(widget); } } public int getLayoutSize() { return layouts.size(); } }
Client code
Widget nav = new Navigator(-1); Widget widget = new Widget(10); LayoutManager manager = new LayoutManager(); manager.addWidget(nav); manager.addWidget(widget); System.out.println(manager.getLayoutSize()); // prints 2
Noncompliant Code Example
What gets printed - main or child / both / either ?
public class Trusted implements Runnable { Trusted() { } public void startThread(String name) { new Thread(this, name).start(); } @Override public void run() { System.out.println("Child"); } } public class Untrusted extends Trusted { // Note untrusted code may start a new thread even during construction Untrusted(String name) { super.startThread(name); } @Override public void run() { System.out.println("Main"); } }
Client code:
Trusted a = new Untrusted("Main"); a.run();