java Object-等于在运行时强制相同类型

kkbh8khc  于 2022-12-10  发布在  Java
关注(0)|答案(2)|浏览(93)

我想知道是否有可能添加一些像Objects.equals()这样的东西来允许运行时类型检查。
注:我知道,这不是你一直想做的,但我认为它有它的用例。至少对我来说。
问题示例:我有一个类,比如说,一个整数类型的id。我有一个实体Foo,它的foo.getId()返回一个整数类型。出于某些原因,我检查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没有任何关系,我正在寻找一个编译时的解决方案。

mpgws1up

mpgws1up1#

我认为没有一个快速的解决方案,除非写一堆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));
    }
}
bfnvny8b

bfnvny8b2#

正如托马斯已经提到的,我也想不出一个快速的解决办法。
您有几个选项,其中一些您可能已经尝试过:

  • 你可以使用你自己的equals方法,强制你传递两个相同类型的参数(要么都是Integer,要么都是Long),这就是the solution Thomas proposed
  • 您可以通过类型转换强制使用特定类型:
Objects.equals((Integer) someId, (Integer) foo.getId())

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

  • 应用封装。创建一个类Id,在其中存储实际值,可以是LongInteger。然后,如果在任何地方返回 id,请使用Id类。直接使用LongInteger的问题是,您会公开内部实现。当您更改实现时,您可以更改接口。

此选项是否可行,取决于您的用例。
如果你不想使用Id类,那么我建议你改用Long,并希望你永远不需要一个大于9,223,372,036,854,775,807的id。

相关问题