2015-08-17 5 views
3

Здесь у меня есть универсальный метод, который принимает параметр универсального TОбщий метод работает с различным фактическим параметром

public static <T> boolean compare(T p1, T p2) { 
     return p1.equals(p2); 
    } 

типа теперь, если я называю этот метод, как показано ниже

compare(10, ""); 

он работает, но, как я предположим, что он не должен работать, потому что он может принимать только один тип Type parameter, так как здесь работает алгоритм вывода?

+0

Не можете ли вы напечатать тип p1 и p2 внутри метода? – csmckelvey

+0

@Takendarkk it print 'java.land.Integer' для первого параметра и для второго он печатает' java.lang.String'. – eatSleepCode

+0

Интересно. Я думаю, это из 'getClass(). GetName()'. Я буду смотреть в него. – csmckelvey

ответ

0

Ваш метод будет компилировать и не вызывать каких-либо исключений во время выполнения.

Причина:

  • Type erasure предотвратит JVM от зная ваш параметризованную тип во время выполнения, и так как вы не являетесь обязательными для вашего параметризованную типа (например, T extends CharSequence и т.д.), любую Object и «boxable» примитив будет компилироваться как параметр во время вызова
  • Вызов equals по параметрам равносилен вызову Object#equals в этом случае, поэтому исключение для выполнения не будет выбрано. false будут возвращены в качестве ссылки между вашими аргументами не равна

Если вы вызываете ваш метод с объектами обмена той же ссылкой, он будет печатать true.

Если вы вызываете свой метод с объектами, использующими одно и то же значение (например, два равных String с), он вернет true.

+0

Спасибо за ответ, у меня есть сомнения, в чем разница между ' 'и' '. – eatSleepCode

+0

@eatSleepCode в этом точном контексте, ни один технически, но один функционально. '?' является подстановочным знаком для любого типа, а 'T' - это определение типа, которое вы можете использовать повторно, ограничено или не расшифровывается' extends ... '. Если вы используете '?', Вы не можете объявить 'T' в свой список аргументов метода, тело или тип возврата, который часто ограничивает вашу функциональность. – Mena

+0

Тип стирания не имеет к этому никакого отношения. Если бы мы обновили дженерики, это также сработало бы. – newacct

2

Это работает, потому что Integer и строка имеют общего предка: Object, и вы не указали каких-либо ограничений в типа T. Если вы пишете:

public static <T extends Number> boolean compare(T p1, T p2) { 
    return p1.equals(p2); 
} 

вы получите компиляции ошибки времени.

2

Метод вызова работает, потому что вы не стеснены тип T и так как String и Integer являются подтипы java.lang.Object, что тот тип, который будет определен.