Java反射检查是否传入相同类型的对象



我有一个类比较方法。该方法接受两个对象作为参数。使用java反射,我能够获得所有私有和受保护的字段,并使用一些花哨的东西检查它们的返回类型,并对它们做我想做的事情。

这对我个人有好处。我知道我要做什么,我只是比较两个相同类型的对象,仅此而已。

但是…很多人都用这个…它们有时无法读取Javadocs和注释以及我放在那里的其他东西,所以我必须检查它们是否传递相同类型的对象。例如你有:汽车a,汽车b,卡车a,卡车b……等等......我需要检查传递的两个参数是否实际上是相同类型的比较(Car与Car, Truck与Truck ..)

所以…我不知道这些东西……我是否应该使用反射来列出所有字段的大小,然后检查所有字段是否具有相同的名称?还是有更好的解决方案?因为写一些像fieldsOfA。大小与fieldOfB相同。大小……然后for loop for this如果它们是相同的来检查名字看起来有点奇怪。

还有一个问题。这些对象有一些其他对象的列表——例如Car有一个Wheels的列表。你在和别的车比较轮子。他们有1号轮,2号轮,3号轮,4号轮…第二辆车有轮子1、轮子2、轮子4和轮子3。

所以对象是相同的,但只是交换了位置…有没有办法防止这种情况?我有一个跟踪代码,可以存储这些对象的每一个差异。所以如果他们的位置不同,我就有两个变化。3号轮不同于其他车,4号轮不同于其他车。

但他们仍然是一样的…我不知道如何用反思来解决这个问题……有什么想法吗?

使用if(object1.getClass() == object2.getClass())

进行比较

公平地说,不是a.getClass().isInstance(b)就是a.getClass().isAssignableFrom(b),但我总是忘记哪个是哪个。

boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class.

boolean isAssignableFrom(Class<?> cls)
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.

你可能需要第一个

您可以使用instanceof操作符

例如:

public boolean isCar(Vehicle x) {
    if (x instanceOf Car) {
        return true;
    } else {
        return false;
    }
    // note: you can also just do "return x instanceof Car"
}

这听起来像是在尝试编写一个通用的Equals方法。以防万一:请注意,这在一般情况下会失败,因为对象相等并不一定意味着所有字段都相等,甚至不意味着所有公共字段都相等。即使某些字段不同,也可以故意使两个Java对象相等。给定类的两个实例之间的相等性是由设计该类的程序员定义的,任何子类化该类的人都隐式地遵守它们的相等性契约。

考虑到这一点,试图挖掘对象的超类的私有字段通常是一个坏主意。一个更好的主意:super.equals() .

因此,假设您编写了一个扩展了Vehicle的类Truck,并且Truck定义了两个私有字段maxLoadhasTrailerHitch。定义两个truck是否相等;假设您需要这两个字段相等。实际上,您可能还希望它们满足Vehicle定义的任何相等条件。所以你的equals可能看起来像这样:
@Override
public boolean equals(Object obj) {
    // check for type
    if (!(obj instanceof Truck)) return false;
    // check private fields
    Truck other = (Truck)obj;
    if (this.maxLoad != other.maxLoad ||
        this.hasTrailerHitch != other.hasTrailerHitch) return false;
    // check for Vehicle equality
    if (!super.equals(obj)) return false;
    // everything checks out!
    return true;
}
出于显示的目的,我把

写得比实际情况稍微宽松一些。理想情况下,检查的顺序并不重要;我把超类检查放在最后,因为我知道两个私有字段比较运行得非常快,但我不一定知道检查车辆涉及什么。

注意instanceof是如何工作的。如果有人(包括您!)稍后编写了Truck的子类,instanceof将为真,因此,如果他们做与您相同的事情并调用super.equals(obj),您的Truck.equals将检查这两个私有字段,就像它应该做的那样。如果您没有进行instanceof检查,而是进行了更严格的检查,请说:
if (obj.getClass().getName().equals("my.pkg.Truck")) // ...

则Truck的子类将不能正确检查这些私有字段。例如,DumpTruck的两个实例永远不会相等——可能不是您想要的。

相关内容

  • 没有找到相关文章

最新更新