-3

To my understanding, the following code should print true, since both elements are equal.

From java docs Array.get() will return:

Returns the value of the indexed component in the specified array object. The value is automatically wrapped in an object if it has a primitive type.

However, when I run the following code it is printing false:

  public class Test1 {

    static boolean equalTest(Object array1, Object array2) {
        return Array.get(array1, 0).equals(Array.get(array2, 0));
    }

    public static void main(String[] args) {
        int[] a = new int[1];
        byte[] b = new byte[1];
        a[0] = 3;
        b[0] = 3;
        System.out.println(equalTest(a, b));
    }
}

My question is isn't classes implementing Number are or should be directly comparable to one another.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
T-Bag
  • 10,916
  • 3
  • 54
  • 118

6 Answers6

11

This has nothing to do with arrays really. Your comparison is equivalent to:

Object x = Integer.valueOf(3);
Object y = Byte.valueOf((byte) 3);
boolean equal = x.equals(y);

That's never going to return true.

Even though your original arrays are of the primitive types, Array.get returns Object, so you're getting the boxed types - and comparing values of those different types.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

According to the documentation of Array.get(Object array,int index) method, the value returned is automatically wrapped in an object if it has a primitive type. So, if you add the following lines:

System.out.println(Array.get(array1, 0).getClass());
System.out.println(Array.get(array2, 0).getClass());

you will see the output is

class java.lang.Integer
class java.lang.Byte

The equals method of Integer class first of all checks if the object it is being compared to is also an instance of Integer, if not , then no further checks are required, they are not equal. That's the reason you see the output is false as the objects being compared for equality are Integer and Byte.

Pallavi Sonal
  • 3,661
  • 1
  • 15
  • 19
1

The Array.get invocations return Integer and Byte object instances. These are not equal according to Integer.equals because the class type differs.

discipliuned
  • 916
  • 7
  • 13
C-Otto
  • 5,615
  • 3
  • 29
  • 62
0

The array data types don't match. One is int and the other is byte. Since they're being passed to the function as Objects, they'll end up being Integer and Byte. So in order to compare them properly, you need to type-cast them to the same type. Something like:

static boolean equalTest(Object array1, Object array2) {
  int int1 = (int) Array.get(array1, 0);
  int int2 = (int) Array.get(array2, 0);
  return int1.equals(int2);
  // OR return int1 == int2;
}
sorayadragon
  • 1,087
  • 7
  • 21
  • 1
    Well, they're not `int` and `byte`, because `Array.get` returns `Object` - they'll be the wrapper types. (But yes, it's because the types aren't the same.) – Jon Skeet Jun 23 '17 at 14:01
  • Jon Skeet and I agree. Then we must both be right. :D @jonskeet – Vucko Jun 23 '17 at 14:02
  • True, but auto-boxing should take care of it. – sorayadragon Jun 23 '17 at 14:04
  • That's my point though - the types *being compared* are `Integer` and `Byte`, not `int` and `byte`. Casting directly to `int` will give a `ClassCastException`, too - you'd need to cast to `byte` and then convert that `byte` to `int` (whether implicitly or explicitly). – Jon Skeet Jun 23 '17 at 14:06
0

The problem is that the Array.get() method returns an object, so for int it'll return Integer, and for byte, it will return Byte. So .equals() method will return false because it first sees whether the type is the same, and then compares the values.

Vucko
  • 7,371
  • 2
  • 27
  • 45
0

If you look at the JavaDoc for Array.get you'll see:

The value is automatically wrapped in an object if it has a primitive type.

So your bytes become Bytes and your ints become Integers.

That means the function you're calling is Integer.equals(Object)

This is implemented like so:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

You're not passing it an Integer, you're passing it a Byte so that's why it returns false.

Michael
  • 41,989
  • 11
  • 82
  • 128