如何在Java中重写数组的等于?

时间:2012-09-06 03:21:45

标签: java

我希望覆盖int []数组的equals。这样以下就是真的

int[] a = {1,2,3};
int[] b = {1,2,3};
System.out.println(a.equals(b));

有办法吗?

4 个答案:

答案 0 :(得分:5)

覆盖equals的{​​{1}}方法既不可能也不必要。您可以使用Arrays.equals(int[], int[])来实现所需的功能。

int[]

答案 1 :(得分:2)

数组是Java的低级构造,因此您无法创建子类,因此您无法覆盖方法。但是您可以使用java.util.List而不是数组。现代JRE显示了阵列和列表的相同性能。

答案 2 :(得分:0)

你不能直接覆盖数组上的equals - 数组是Java中的原始结构,你不能覆盖作用于它们的方法或运算符。

您应该考虑使用ArrayList而不是数组 - ArrayLists提供了一个equals()实现,它可以正常工作(以及数组没有的许多其他有用功能,例如能够将新元素添加到列表等。)

答案 3 :(得分:0)

此处的其他答案是正确的,您应该只使用Arrays.equals()或切换为使用List<Integer>而不是int[]

但是,您想要做的是几乎可能使用反射和javassist.util.proxy.ProxyFactory。下面是一些示例代码,可以或多或少地执行此操作:

public static void main(String[] args) throws Exception {
    int[] test = {0, 1, 2, 3};
    int[] empty1 = {};
    int[] empty2 = {};

    Class clss = int[].class;
    ProxyFactory factory = new ProxyFactory();
    factory.setSuperclass(clss);
    factory.setFilter(new MethodFilter() {
         public boolean isHandled(Method m) {
             // ignore finalize()
             return !m.getName().equals("finalize");
         }
     });
    factory.setHandler(new IntArrayEqualsHandler());

    Class newArrayClass = factory.createClass();

    int[] specialArray = (int[])newArrayClass.newInstance();
    System.out.println(empty1.equals(empty2));
    System.out.println(specialArray.equals(empty1));
    System.out.println(specialArray.equals(empty2));
    System.out.println(specialArray.equals(test));
}

private static class IntArrayEqualsHandler implements MethodHandler {
    @Override
    public Object invoke(Object thisObj, Method method, Method original, Object[] params) throws Throwable {
        if (method.getName().equals("equals")) {
            int[] left = (int[])thisObj;
            int[] right = (int[])params[0];
            return Arrays.equals(left, right);
        }
        return original.invoke(thisObj, params);
    }

}

不幸的是,这不起作用,因为int[].class在语言中被声明为final,所以即使使用反射它也无法扩展。至少据我所知。有一些技巧可以提取到remove the 'final' modifier from a field,但似乎没有可用于从整个类中删除final修饰符的等效黑客。

如果有这样的事情,您可以使用上面的代码或类似的代码在运行时生成int[]的自定义子类,以实现您期望的equals()行为。

真的,这比它的价值更麻烦,特别是当你开始考虑如何在项目的其余部分实际使用自定义子类时。所以,只要使用Arrays.equals()List<Integer>,所有事情都会被认为是