public class Fruit extends Food {
private Season ripe;
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (Fruit.class == obj.getClass()) { // Noncompliant [[sc=9;ec=20]] {{Compare to "this.getClass()" instead.}}
return ripe.equals(((Fruit) obj).getRipe());
}
if (obj instanceof Fruit) { // Noncompliant [[sc=9;ec=29]] {{Compare to "this.getClass()" instead.}}
return ripe.equals(((Fruit) obj).getRipe());
} else if (obj instanceof Season) { // Noncompliant [[sc=16;ec=37]] {{Remove this comparison to an unrelated class.}}
// ...
}
if (Fruit.class != obj.getClass()) { // Noncompliant broken for child classes
}
}
}
public class Fruit2 extends Food {
private Season ripe;
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (this.getClass()==obj.getClass()){
return ripe.equals(((Fruit2) obj).getRipe());
}
return false;
}
}
public class Fruit3 extends Food {
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (this.getClass()==obj.getClass()){
return ripe.equals(((Fruit2) obj).getRipe());
}
class Foo {
public boolean equals(Object j) {
if (Foo.class==obj.getClass()){ // Noncompliant
}
if (obj instanceof Season) { // Noncompliant [[sc=13;ec=34]] symmetry broken for Season class
// ...
}
return false;
}
}
return false;
}
}
public class BaseClass {
@Override
public final boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof BaseClass)) return false; // Compliant; equals is final
return true;
}
}
public interface I {
public abstract boolean equals(Object anObject);
}
public final class Fruit4 extends Food {
private Season ripe;
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (Fruit4.class == obj.getClass()) { // Compliant; class is final
return ripe.equals(((Fruit4) obj).getRipe());
}
if (obj instanceof Fruit4) { // Compliant; class is final
return ripe.equals(((Fruit4) obj).getRipe());
}
if (Fruit4.class != obj.getClass()) { // Compliant; class is final
}
}
}