Проблема с оператором instanceof
заключается в том, что он работает с учетом полиморфизма, если можно так выразиться.
Допустим, например, что вы делаете это:
public class AdvancedImageEntity extends ImageEntity
{
//some code here
}
и затем вы делаете это:
ImageEntity ie = new ImageEntity ();
AdvancedImageEntity advanced_ie = new AdvancedImageEntity ();
boolean this_will_be_true = ie.equals (advanced_ie);
Как следует из названия, вызов equals
вернет true из-за оператора instanceof
.
Я знаю, что это звучит как базовые вещи, и большинство людей знают это, но чертовски легко забыть это. Теперь, если вы хотите такое поведение, тогда все в порядке, вы правильно реализовали equals
. Но если вы считаете, что объект ImageEntity
не должен быть равен (гипотетическому) объекту AdvancedImageEntity
, либо объявите ImageEntity
равным final
ИЛИ забудьте о instanceof
и реализуйте свой метод equals
следующим образом :
@Override public boolean equals(final Object obj)
{
if(obj == this) return true;
if(obj == null) return false;
if (getClass ().equals (obj.getClass ()))
{
final ImageEntity otherImage = (ImageEntity) obj;
return Object.equals (getFilePath(), otherImage.getFilePath());
}
return false;
}
Это проверит истинный тип объекта, независимо от типа ссылки. Если параметр obj
является экземпляром подкласса, он будет "проскальзывать" на instanceof
. Но getClass
намного строже и не допустит этого.
PS: Я не говорю, что instanceof
это плохо и не должно использоваться. Я просто говорю, что вы должны знать об этой конкретной ситуации и решить, использовать ли ее, принимая это во внимание.