как тип переменной допускает неправильный тип?

package org.my.java;

public class TestTypeVariable {

    static <T,A extends T> void typeVarType(T t, A a){
        System.out.println(a.getClass());
        System.out.println(t.getClass());
    }

    public static void main(String[] s){
        int i= 1;
        typeVarType("string", i);
    }
}

при запуске выводится следующее:

class java.lang.Integer
class java.lang.String

Как A может иметь тип Integer, если он уже ограничен сверху до String?

Пожалуйста, объясните мне это.


person Atul    schedule 25.09.2017    source источник
comment
Я не могу скомпилировать ваш пример: Несоответствие привязки: универсальный метод typeVarType(T, A) типа TestTypeVariable неприменим для аргументов (String, Integer). Выведенный тип Integer не является допустимой заменой ограниченного параметра ‹A extends T› Чего я и ожидал. Вы успешно скомпилировали исходный код?   -  person SilverNak    schedule 25.09.2017
comment
Если компилятор преобразует T в Object и A в Integer, проблем не возникает.   -  person daniu    schedule 25.09.2017
comment
@SilverNak Проходит компиляцию в Java 8, но не в Java 7.   -  person Eran    schedule 25.09.2017
comment
На этот вопрос уже дан ответ в этом сообщении разрешено, но выдает предупреждение"> stackoverflow.com/questions/12475050/   -  person thedevd    schedule 25.09.2017
comment
Добро пожаловать в место, где разработчики учатся, делятся и строят карьеру! Я заметил, что ваш вопрос все еще открыт, так как вы не приняли ответ. Посмотрите и решите, хотите ли вы принять ответ. Или дайте мне знать, если я могу что-то сделать, чтобы улучшить мой вклад, чтобы сделать его достойным. Принятие помогает будущим читателям определить, решена ли проблема, и показывает признательность людям, которые нашли время ответить вам. Спасибо!   -  person GhostCat    schedule 26.09.2017


Ответы (1)


Две вещи здесь:

  • есть простое решение "плохой" типизации: T не String, а Object. И Integer расширяет Object. Но обратите внимание: это работает только с «расширенными» возможностями вывода типов Java8. С Java7 ваш ввод не будет компилироваться!
  • неправильное представление с вашей стороны: getClass() происходит во время времени выполнения и, следовательно, возвращает определенный класс переданных объектов - независимо от того, что компилятор думает о дженериках во время компиляции.
person GhostCat    schedule 25.09.2017
comment
Он компилируется нормально. typeVarType("string", i); есть T=Object, A=Integer . - person khelwood; 25.09.2017
comment
он компилируется и запускается. getClass() я просто использовал для печати типа объекта во время выполнения. Но это не проблема. главное, как java разрешает целочисленный тип для строкового верхнего ограниченного типа - person Atul; 25.09.2017
comment
@khelwood Это происходит, когда кто-то верит другим комментариям без дополнительной проверки. Я думал, что T сам должен быть Object ... спасибо, и обновлено. - person GhostCat; 25.09.2017
comment
Он отлично компилируется в Java 8, но не проходит компиляцию в Java 7. В этом случае я думаю, что имеет смысл не проходить компиляцию, поскольку <T,A extends T> не имеет смысла (из-за стирания типа). - person Eran; 25.09.2017
comment
Конечно, предполагаемый тип для T также может быть Object & Serializable & Comparable<?> - person Holger; 25.09.2017
comment
Я хотел бы, чтобы вы могли процитировать JLS здесь, клянусь, учитывая это в интервью, я бы сказал, что это не удается - person Eugene; 25.09.2017