开发者

Java: equals check on interface instead of class

开发者 https://www.devze.com 2023-02-05 18:18 出处:网络
I have a case, where I have a Java-Interface representing an entity. This interface is implemented in 2 different classes.

I have a case, where I have a Java-Interface representing an entity. This interface is implemented in 2 different classes. As a consequence, I need a method that tests - if 2 classes have a common interface - i开发者_如何学JAVAf all Getter-Values of these 2 classes are the same

if both is true, then they pass as equal, in the case I need. (note, that I do not know which interface they implement, there are a few possible)

Is that somehow possible, or do I need to give the interface and then check if the two classes implement it?

Thanks for your help, Michael


Attention: if you have different interfaces for one class, then this could break constraints:

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

@see: java doc for Object.equals

If you have three Classes A, B, C tree Itnerfaces I1, I2, I3:

  • A implments Interface I1 and I2,
  • B implments I2 and I3
  • C implments I1 and I3.

Then you could have this situation:

  • A equals B because of I2
  • B equals C because of I3
  • but: A not equals C because of I3

This would violate the transitive constraint! This could cause in hard to find bugs!

This is only a warning, to think twice before you start to declare this as a major architecture style.

Added:

Instead I recommend to implement something that is similar to the Comparator, but not to compare but to check for "equals", its meaning would be something like "equals in respect to X" (where X is for example one of your interface)


java.lang.Class has a method called getInterfaces which will allow you to get the interfaces an object implements. You can get the list of interfaces for the objects you are comparing, and then compare them.

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

Then for the common ones, list the getters using reflection and compare the values of the getters.

In general though, it isn't a good assumption to make that you will only have X number of implementations of an interface, since the idea behind an interface is that you don't really care about the underlying implementation.


 if ( oneClass instanceof Interface1 && secondClass instanceof Interface2)

There is a method called isAssignableFrom

Class.isAssignableFrom(interface);


You'll need to write this yourself, but it shouldn't be too bad. You'll need to use reflection.

First, you need the Class of each object. Use Object#getClass() to get the Class.

Second, use Class[] Class#getInterfaces() to get the interfaces for the two classes and look for matches.

Then, if you find a match, use Method[] Class#getMethods() to find all of the methods of the interface they have in common.

For each of these methods, use Method#getName() to see if they start with "get" and Method#getParameterTypes() to get the parameter types of the methods. For a typical "getter", it will have 0 parameters.

Then, to execute the methods, call Method#invoke(Object) for each of your objects. This will call the method and return the value of that getter. You can then compare these values and make sure they match.


If you have no way of knowing which interface an object might be implementing I would suggest you make an umbrella interface.

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

Then as Jigar said, use instanceof.

if(myobj instanceof MyGeneralInterface) {}
0

精彩评论

暂无评论...
验证码 换一张
取 消