2015-07-08 4 views
-1

Почему нельзя сравнивать Byte и Number/Integer? Я прикрепил свой исходный код. См. Комментарии. Кроме того, почему я должен накладывать 88 байтов, не так ли автоматически с автоматическим боксированием и автоматической распаковкой?Java Generics Compare Number with Byte

package com.practice; 

public class Generics<T extends Number> 
{ 
    T ob; 

public Generics(T i) 
{ 
    ob = i; 
} 

T getObj() 
{ 
    return ob; 
} 

boolean compare(Generics<?> o) 
{ 

    if (this.ob == o.ob) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

public static void main(String[] args) 
{ 

    Generics<Number> num = new Generics<>(88); 

    // Generics<Byte> Byte = new Generics<>(88); //why this does not 
    // compile? 

    Generics<Byte> Byte = new Generics<>((byte) 88); 

    Generics<Integer> integer = new Generics<>(88); 

    System.out.println(num.compare(integer)); // this is true!! 
    System.out.println(num.compare(Byte)); // why False? 
    System.out.println(integer.compare(Byte)); // Why false? 

} 

} 
+1

Это действительно неясно, чего вы хотите достичь, но факт заключается в том, что 'Number' не реализует' Comparable'; так что это ожидается – fge

+0

Это не нормальная функция compareTo(). Я создал свой собственный. Мой вопрос указан в комментариях в нижней части кода. –

ответ

1

Почему я должен бросить 88 в байты, это не делается автоматически с автоматическим боксом и авто-распаковкой?

По умолчанию числовой литерал (например, 88) является int. Авто-бокс происходит, но компилятор помещает его в Integer, а не Byte, потому что, как я только что сказал, это int.

Generics<Number> num = new Generics<>(88); 
Generics<Integer> integer = new Generics<>(88); 

Так, IntegerIS-АNumber оба из вышеуказанной работы просто отлично.

Generics<Byte> Byte = new Generics<>(88); // why this does not compile? 

Теперь, в случае Generics<Byte>, то конструктор становится Generics(Byte i), который терпит неудачу, потому что Integer не может быть отнесен к Byte, как нет наследования между ними. Они оба распространяются на Number и являются классами братьев и сестер.

Generics<Byte> Byte = new Generics<>((byte) 88); 

Таким образом, чтобы пройти в Byte и удовлетворить компилятор, требуется (byte) бросок. Теперь авто-бокс происходит снова, но с byte до Byte на этот раз.


Что касается равенства, ваша compare() реализация метода является некорректной, поскольку он сравнивает только ссылки this.ob == o.ob и не их значения.

System.out.println(num.compare(integer)); // this is true!! 
System.out.println(num.compare(Byte)); // why False? 
System.out.println(integer.compare(Byte)); // Why false? 

Это, однако, работал целочисленного сравнения num.compare(integer), потому что вы выбрали небольшую величину 88, которая попадает в область значений (-128 до +127) кэшированных и разделяют на JVM среди авто-боксировалInteger экземпляров. Если вы снова запустите свою программу с большим значением, например 888, оно будет печатать false для такого же сравнения.

Итак, чтобы исправить ваш метод compare(), вам нужно будет отсортировать их числовые значения.

return (this.ob.floatValue() == o.ob.floatValue()); 

PS: равно() метод не поможет здесь. Проверьте исходный код, чтобы узнать почему :)

+0

Вау! Подробное объяснение. Спасибо, особенно очистка запроса compare(). –