Java: равняется проверке интерфейса вместо класса - PullRequest
1 голос
/ 19 января 2011

У меня есть случай, когда у меня есть Java-интерфейс, представляющий сущность. Этот интерфейс реализован в 2 разных классах. Как следствие, мне нужен метод, который тестирует - если 2 класса имеют общий интерфейс - если все значения Геттера этих 2 классов одинаковы

если оба истинны, то они проходят как равные, в случае необходимости. (обратите внимание, что я не знаю, какой интерфейс они реализуют, есть несколько возможных)

Это как-то возможно, или мне нужно дать интерфейс и затем проверить, реализуют ли его два класса?

Спасибо за вашу помощь, Michael

Ответы [ 5 ]

5 голосов
/ 19 января 2011

Внимание: если у вас разные интерфейсы для одного класса, это может нарушить ограничения:

Метод equals реализует отношение эквивалентности на ненулевом ссылки на объекты:

  • Это рефлексивный: для любого ненулевого опорного значения х, x.equals (х) должны верните истину.
  • Симметрично: для любых ненулевых опорных значений x и y, x.equals (y) должен возвращать истину, если и только если y.equals (x) возвращает true.
  • Это транзитивно: для любых ненулевых опорных значений x, y и z, если x.equals (y) возвращает true и y.equals (z) возвращает true, затем x.equals (z) должен вернуть true.
  • Согласовано: для любых ненулевых опорных значений x и y кратно вызовы x.equals (y) последовательно возвращать истину или последовательно возвращать false, если нет информация, используемая в сравнениях равных на объектах доработан.

@ см. Документ Java для Object.equals

Если у вас есть три класса A, B, C дерева, Inerface I1, I2, I3:

  • A implments Интерфейс I1 и I2,
  • B implments I2 и I3
  • C implments I1 и I3.

Тогда вы могли бы иметь такую ​​ситуацию:

  • A равно B из-за I2
  • B равно C из-за I3
  • но: A не равно C из-за I3

Это нарушит переходное ограничение! Это может привести к трудно найти ошибки!

Это всего лишь предупреждение, подумайте дважды, прежде чем начинать объявлять это основным стилем архитектуры.

Добавлено:

Вместо этого я рекомендую реализовать что-то похожее на Comparator, но не для сравнения, а для проверки на «равно», его значение будет что-то вроде «равно по отношению к X» (где X, например, один из ваших интерфейс)

1 голос
/ 19 января 2011

java.lang.Class имеет метод с именем getInterfaces, который позволит вам получить интерфейсы, которые реализует объект.Вы можете получить список интерфейсов для сравниваемых объектов, а затем сравнить их.

Class<?>[] interfaces1 = obj1.getClass().getInterfaces();
Class<??[] interfaces2 = obj2.getClass().getInterfaces();
// iterate through the arrays to figure out which interfaces are common across the objects

Затем для общих перечислите получатели, используя отражение, и сравните значения получателей.

В общем, не стоит полагать, что у вас будет только X реализаций интерфейса, поскольку идея интерфейса заключается в том, что вас не волнует базовая реализация.

0 голосов
/ 19 января 2011

Вам нужно написать это самостоятельно, но это не должно быть слишком плохо. Вам нужно будет использовать отражение.

Во-первых, вам нужен класс каждого объекта. Используйте Object#getClass(), чтобы получить класс.

Во-вторых, используйте Class[] Class#getInterfaces(), чтобы получить интерфейсы для двух классов и искать совпадения.

Затем, если вы найдете совпадение, используйте Method[] Class#getMethods(), чтобы найти все методы интерфейса, которые у них общие.

Для каждого из этих методов используйте Method#getName(), чтобы увидеть, начинаются ли они с «get», и Method#getParameterTypes(), чтобы получить типы параметров методов. Для типичного «геттера» он будет иметь 0 параметров.

Затем, чтобы выполнить методы, вызовите Method#invoke(Object) для каждого из ваших объектов. Это вызовет метод и вернет значение этого геттера. Затем вы можете сравнить эти значения и убедиться, что они совпадают.

0 голосов
/ 19 января 2011

Если у вас нет возможности узнать, какой интерфейс может реализовывать объект, я бы посоветовал вам создать интерфейс-зонтик.

public interface MyGeneralInterface {}
public interface SpecificInterface1 implements MyGeneralInterface {}
public interface SpecificInterface2 implements MyGeneralInterface {}
public class SpecificClass1 implements SpecificInterface1 {}
public class SpecificClass2 implements SpecificInterface2 {}

Затем, как сказал Джигар, используйте instanceof.

* 1006.*
0 голосов
/ 19 января 2011
 if ( oneClass instanceof Interface1 && secondClass instanceof Interface2)

Существует метод isAssignableFrom

Class.isAssignableFrom (интерфейс);

...