Object-Equals 在运行时强制相同类型

问题描述 投票:0回答:2

我想知道是否可以添加类似 Objects.equals() 之类的东西来允许运行时检查类型。
注意:我知道,这不是您一直想做的事情,但我认为它有它的用例。至少对我来说。

示例问题:我有一些类,比如说,一个 Integer 类型的 id。我有一个实体 Foo ,其中

foo.getId()
返回 Integer 类型。由于某些原因,我检查是否与
Objects.equals(someId, foo.getId())
相等。
现在我重构了我的实体,
foo.getId()
将不再返回 Integer,而是返回 Long。不幸的是,根本不会有编译时提示
Objects.equals(someId, foo.getId())
永远不会返回 true。 (是的,像 sonarqube 这样的东西对你有一点帮助)。

为了解决这个问题,我想我写了类似的东西

private static <T> boolean equals(T object1, T object2) {
    return Objects.equals(object1, object2);
}

这......只是行不通。它仍然接受任何任意对象。 Java 有没有可能解决这个问题?

编辑:请注意,这个问题与对象的 equals 和 hashCode 或一般对象的重写 equals 无关,我正在寻找编译时解决方案。

java generics
2个回答
0
投票

我认为除了编写一堆

equals()
方法之外,没有快速的解决方案。如果您只想使用一组有限的类型,这可能是可行的:

public class Equals {

    public static boolean equals(Integer a, Integer b) {
        return Objects.equals(a, b);
    }

    public static boolean equals(Long a, Long b) {
        return Objects.equals(a, b);
    }

    public static void main(String[] args) {
        // System.out.println(equals(1, 1L)); doesn't compile
        System.out.println(equals(1, 1));
        System.out.println(equals(1L, 1L));
    }
}

0
投票

正如托马斯已经提到的,我也想不出快速的解决方案。

您有多种选择,其中一些您可能已经尝试过:

  • 您可以使用自己的

    equals
    方法,强制您传递两个相同类型的参数(要么都是
    Integer
    要么都是
    Long
    )。这就是Thomas提出的解决方案

  • 您可以通过类型转换强制某种类型:

    Objects.equals((Integer) someId, (Integer) foo.getId())
    

    如果您更改任一参数的类型,编译器就会开始抱怨。

  • 您也可以尝试使用泛型。如果您的方法如下所示:

    public static <T> boolean equals(T a, T b) {
        return Objects.equals(a, b);
    }
    

    那么至少编译器会抱怨不同类型的

    a
    b

  • 应用封装。创建一个类

    Id
    ,在其中存储实际值,可以是
    Long
    Integer
    。然后,如果您在任何地方返回 id,请使用
    Id
    类。直接使用
    Long
    Integer
    的问题是暴露了内部实现。当你改变实现时,你就改变了接口。

    此选项是否可行,取决于您的用例。

如果你不想使用类

Id
,那么我建议你切换到
Long
,并希望你永远不需要大于9,223,372,036,854,775,807的id。

© www.soinside.com 2019 - 2024. All rights reserved.