Java反射检查是否传递对象是同一类型

时间:2015-08-04 20:11:16

标签: java reflection

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

这对我个人有好处。我知道我想要做什么,所以我只是比较两个相同类型的对象。

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

所以...我不知道的东西..我应该使用反射列出所有字段的大小,然后检查所有字段是否具有相同的名称? 或者有更好的解决方案吗?想写一些类似于fieldsOfA.size与fieldOfB.size相同的东西......然后为了它的循环,如果它们是相同的,检查名称看起来有点奇怪..

另一个问题。 那些对象有一些其他对象的列表 - 例如Car有一个车轮列表.. 而你正在将车轮与其他车进行比较。 他们有像轮1,轮2,轮3,轮4的列表.. 第二辆车有Wheel1,Wheel 2,WHeel 4和WHeel 3 ..

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

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

4 个答案:

答案 0 :(得分:4)

要比较课程,只需使用if(object1.getClass() == object2.getClass())

答案 1 :(得分:2)

公平地说,它可能是Pattern\n Pattern \n Pattern \n 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.

你可能需要第一个。

答案 2 :(得分:1)

您可以使用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"
}

答案 3 :(得分:1)

这听起来像你正在尝试编写通用等于方法。如果你是:请注意,在一般情况下这将失败,因为对象相等并不一定意味着所有字段都相等,或者甚至所有公共字段都相等。即使某些字段不同,也可能有意地使两个Java对象相等。程序员在设计该类时定义给定类的两个实例之间的相等性,任何对其进行子类化的人都会遵循它们的平等契约。

考虑到这一点,尝试挖掘一个物体的超类通常是一个坏主意。私人领域。一个更好的主意:super.equals()

因此,假设您编写了一个扩展Vehicle的类Truck,而Truck定义了两个私有字段maxLoadhasTrailerHitch。您可以定义两辆卡车是否相同;假设您需要这两个字段相等。实际上,您可能还希望它们满足车辆定义的任何相等条件。因此,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")) // ...

然后卡车的子类正确检查这些私有字段。例如,DumpTruck的两个实例永远不会是平等的 - 可能不是你想要的。