Тип несоответствия для генеральных классов -- java поле с участием generics пол Связанный проблема

Type mismatch for Class Generics


21
vote

проблема

русский

У меня есть следующий код, который не скомпировался, и хотя есть способ сделать его компиляцией, я хочу понять, почему он не компилирует. Может ли кто-нибудь просвещать меня как конкретно, почему я получаю сообщение об ошибке, я опубликую в конце, пожалуйста?

 <код> public class Test {     public static void main(String args[]) {         Test t = new Test();         t.testT(null);     }      public <T extends Test> void testT(Class<T> type) {         Class<T> testType = type == null ? Test.class : type; //Error here         System.out.println(testType);     } }   

<Код> Type mismatch: cannot convert from Class<capture#1-of ? extends Test> to Class<T>

путем литья <код> Test.class Class<T> Это компилирует с <код> Unchecked cast предупреждение и работает отлично.

Английский оригинал

I have the following code that won't compile and although there is a way to make it compile I want to understand why it isn't compiling. Can someone enlighten me as to specifically why I get the error message I will post at the end please?

public class Test {     public static void main(String args[]) {         Test t = new Test();         t.testT(null);     }      public <T extends Test> void testT(Class<T> type) {         Class<T> testType = type == null ? Test.class : type; //Error here         System.out.println(testType);     } } 

Type mismatch: cannot convert from Class<capture#1-of ? extends Test> to Class<T>

By casting Test.class to Class<T> this compiles with an Unchecked cast warning and runs perfectly.

</div
     

Список ответов

24
 
vote
vote
Лучший ответ
 

Причина в том, что Test.Class имеет тип класса типа; тест и GT; Вы не можете назначить ссылку на тип класса типа; Test & GT; к переменной типа класса типа LT; T & GT; Как они не то же самое. Это, однако, работает:

 <код> Class<? extends Test> testType = type == null ? Test.class : type;   

Подстановочный знак позволяет обоим классом & lt; t & gt; и класс & lt; тест & gt; ссылки должны быть назначены для testtype.

Есть тонна информации о поведении Java Generics в Angelika Langer Java Generics FAQ . Я предоставлю пример на основе какой-то информации, который использует <код> Number CARE API класса Heirarchy Java.

Рассмотрим следующий метод:

 <код> public <T extends Number> void testNumber(final Class<T> type)   

Это должно разрешить успешно компилировать следующие утверждения:

 <код> testNumber(Integer.class); testNumber(Number.class);   

Но следующее не скомпировано:

 <код> testNumber(String.class);   

Теперь рассмотрим эти утверждения:

 <код> Class<Number> numberClass = Number.class; Class<Integer> integerClass = numberClass;   

Вторая строка не скомпилируется и производит эту ошибку <код> Type mismatch: cannot convert from Class<Number> to Class<Integer> . Но <код> Integer расширяет <код> Number , так почему же это не удается? Посмотрите на эти следующие два утверждения, чтобы увидеть, почему:

 <код> Number anumber = new Long(0); Integer another = anumber;   

Довольно легко понять, почему 2-я строка здесь не скомпилируется. Вы не можете назначить экземпляр <код> Number0 на переменную тип <код> Number1 потому что нет способа гарантировать, что <код> Number2 экземпляр Совместимый тип. В этом примере <код> Number3 на самом деле является <код> Number4 , который, безусловно, не может быть назначен <код> Number5 . На самом деле ошибка также является несоответствием типа: <код> Number6 .

Правило заключается в том, что экземпляр не может быть назначен переменной, который представляет собой подкласс типа экземпляра, так как нет гарантии, который является совместимым.

Джезы ведут себя аналогично. В генерическом методе подпись, <код> Number7 - это просто заполнитель, чтобы указать, что метод позволяет компилятору. Когда компилятор встречается <код> Number8 это по существу заменяет <код> Number9 с <код> public <T extends Number> void testNumber(final Class<T> type) 0 .

Подстановочные знаки Добавьте дополнительную гибкость, поскольку следующее будет компилировать:

 <код> public <T extends Number> void testNumber(final Class<T> type) 1  

С public <T extends Number> void testNumber(final Class<T> type) 2 указывает любой тип, который является <Код> public <T extends Number> void testNumber(final Class<T> type) 3 или подкласс <код> public <T extends Number> void testNumber(final Class<T> type) 4 Это совершенно законно и потенциально полезно во многих обстоятельствах. < / P >.

 

The reason is that Test.class is of the type Class<Test>. You cannot assign a reference of type Class<Test> to a variable of type Class<T> as they are not the same thing. This, however, works:

Class<? extends Test> testType = type == null ? Test.class : type; 

The wildcard allows both Class<T> and Class<Test> references to be assigned to testType.

There is a ton of information about Java generics behavior at Angelika Langer Java Generics FAQ. I'll provide an example based on some of the information there that uses the Number class heirarchy Java's core API.

Consider the following method:

public <T extends Number> void testNumber(final Class<T> type) 

This is to allow for the following statements to be successfully compile:

testNumber(Integer.class); testNumber(Number.class); 

But the following won't compile:

testNumber(String.class); 

Now consider these statements:

Class<Number> numberClass = Number.class; Class<Integer> integerClass = numberClass; 

The second line fails to compile and produces this error Type mismatch: cannot convert from Class<Number> to Class<Integer>. But Integer extends Number, so why does it fail? Look at these next two statements to see why:

Number anumber = new Long(0); Integer another = anumber; 

It is pretty easy to see why the 2nd line doesn't compile here. You can't assign an instance of Number to a variable of type Integer because there is no way to guarantee that the Number instance is of a compatible type. In this example the Number is actually a Long, which certainly can't be assigned to an Integer. In fact, the error is also a type mismatch: Type mismatch: cannot convert from Number to Integer.

The rule is that an instance cannot be assigned to a variable that is a subclass of the type of the instance as there is no guarantee that is is compatible.

Generics behave in a similar manner. In the generic method signature, T is just a placeholder to indicate what the method allows to the compiler. When the compiler encounters testNumber(Integer.class) it essentially replaces T with Integer.

Wildcards add additional flexibility, as the following will compile:

Class<? extends Number> wildcard = numberClass; 

Since Class<? extends Number> indicates any type that is a Number or a subclass of Number this is perfectly legal and potentially useful in many circumstances.

</div
 
 
       
       
4
 
vote

Предположим, что я расширяю тест:

 <код> public <T extends Number> void testNumber(final Class<T> type) 5  

Теперь, когда я вызывал <код> public <T extends Number> void testNumber(final Class<T> type) 6 , тип типа <код> public <T extends Number> void testNumber(final Class<T> type) 7 <код> public <T extends Number> void testNumber(final Class<T> type) 8 , что означает переменную <код> public <T extends Number> void testNumber(final Class<T> type) 9 это <код> testNumber(Integer.class); testNumber(Number.class); 0 . <Код> testNumber(Integer.class); testNumber(Number.class); 1 имеет тип <код> testNumber(Integer.class); testNumber(Number.class); 2 , который не является назначенным переменной типа <код> testNumber(Integer.class); testNumber(Number.class); 3 .

Объявление переменной <код> testNumber(Integer.class); testNumber(Number.class); 4 как <код> testNumber(Integer.class); testNumber(Number.class); 5 - это правильное решение; Отказ от <Код> testNumber(Integer.class); testNumber(Number.class); 6 скрывает реальную проблему.

 

Suppose I extend Test:

public class SubTest extends Test {   public static void main(String args[]) {     Test t = new Test();     t.testT(new SubTest());   } } 

Now, when I invoked testT, the type parameter <T> is SubTest, which means the variable testType is a Class<SubTest>. Test.class is of type Class<Test>, which is not assignable to a variable of type Class<SubTest>.

Declaring the variable testType as a Class<? extends Test> is the right solution; casting to Class<T> is hiding a real problem.

</div
 
 
1
 
vote

Удалить условный и ошибка немного приятнее ...

 <код> testNumber(Integer.class); testNumber(Number.class); 7  
 

Remove the conditional and the error is a little nicer...

public class Test {     public static void main(String args[]) {         Test t = new Test();         t.testT(null);     }      public <T extends Test> void testT(Class<T> type) {     Class<T> testClass = Test.class;         System.out.println(testClass);     } }   Test.java:10: incompatible types found   : java.lang.Class<Test> required: java.lang.Class<T>         Class<T> testClass = Test.class; 
</div
 
 

Связанный проблема

40  Можете ли вы сказать во время выполнения, если вы запускаете Java из банки?  ( Can you tell on runtime if youre running java from within a jar ) 
У меня есть приложение, которое некоторые из моих пользователей работают от Eclipse, и другие запускают его, используя файл JAR. Я хочу, чтобы некоторые дей...

1  Содержание XML преобразования передается с POST на объект Java, атрибут внутри элемента: REST  ( Rest convert xml content passed with post to a java object attribute inside th ) 
<Р> Я работаю с REST сервисов и я хочу передать XML-текст запроса POST. Мой сервер реализован в JAVA. Давайте предположим, что я посылаю этот XML: <код> <ran...

2  Изменить формат дата в DTO JSON на возвращении через @Responsebode  ( Change date format in dto json on returning through responsebody ) 
Я просто хочу изменить формат даты в моем DTO, возвращенный @Responseboodbody Мой вопрос не Этот вопрос как мой выход Список JSON и я печатаю его по почте...

0  Случайные 7-значные номера на andich android  ( Random 7 digit numbers on click android ) 
Я хотел бы, чтобы вы помогли мне в этом коде. Я могу генерировать случайные числа, но не в точном количестве. Вопрос: Как я могу генерировать 7 случайных ци...

1  Как вызвать мой метод reзов API, интегрированный с Redis на Windows?  ( How to invoke my restful api method integrated with redis on windows ) 
Я пытаюсь запустить образец весеннего загрузочного приложения с Redis. Я использую завод соединения JEDIS и установив его на заводе подключения шаблона Redis....

-1  Нужно упростить логическое выражение (байт, короткое, целое число) Java  ( Need to simplify logical expression byte short integer java ) 
Мне нужно упростить выражение Первое выражение <код> (byte)( (short)((short)( (byte)((theInt >> 8) & 0xFF) & 0xFF) + 128) & 0xFF); второе выражение ...

0  карта JSON на провал строки в Java  ( Json map to string failure in java ) 
В Java я пытаюсь преобразовать карту в JSon строку. используя код ниже <код> private void sendResponse(Map<String, String> responseMap) throws IOException {...

17  Перегрузка Java VS переопределения  ( Java overloading vs overriding ) 
Привет, я просто хочу убедиться, что у меня есть эти понятия правильно. Перегрузка в Java означает, что у вас может быть конструктор или метод с различным кол...

0  Прямоугольник и круг Collision Java, используя .Наиград  ( Rectangle and circle collision java using intersection ) 
Я делаю игру на прорыв для школьного проекта. Единственная проблема, которую я бегу в, это мяч, подпрыгивая, когда мяч и кирпичи сталкиваются. Я использовал B...

-1  Как добавить JTable для JPanel  ( How to add a jtable to a jpanel ) 
Мой вопрос может показаться немного глупо, но каждый раз, когда я использую качели, у меня проблемы с таблицами. Таким образом, я работаю над школьным проекто...

1  Установка поля _ID с использованием SQLite & ContentProvider в Android  ( Setting the id field using sqlite contentprovider in android ) 
Я пытаюсь настроить ContentProvider в приложении Android, чтобы держать информацию о домах. Я хотел бы иметь возможность установить поле _id, чтобы быть таким...

0  Должен ли я использовать Mac для разработки Javafx для iOS  ( Do i have to use a mac to develop javafx for ios ) 
Документация http://docs.gluonhq.com/charm/4.0.1 / # _ iOS говорит, что мне нужно «Mac с MacOS X 10.9 или превосходящим» для разработки для iOS. Но я не пон...

3  Как мне изменить ответ на запрос на параметры http в приложении Spring MVC 2.5?  ( How do i change the response for a http options request in a spring mvc 2 5 appl ) 
Это звучит как тривиальный вопрос, но каким-то образом я не могу понять это. У меня есть приложение Spring MVC. Я не поддерживаю никаких HTTP-методов, кроме...

5  Конвенции о ведении регистрации [Закрыто]  ( Logging conventions ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> <Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 ...

1  Apache Vamel: Как проверить, например, набор набора <customObject>  ( Apache camel how to test for instance of setcustomobject ) 
Кто-нибудь знает, как тестировать для различных типов коллекции в маршруте? <код> // This processor returns a Collection of 2 Sets // 1. Set<GoodMessage> //...

Связанный проблема

40  Можете ли вы сказать во время выполнения, если вы запускаете Java из банки? 
1  Содержание XML преобразования передается с POST на объект Java, атрибут внутри элемента: REST 
2  Изменить формат дата в DTO JSON на возвращении через @Responsebode 
0  Случайные 7-значные номера на andich android 
1  Как вызвать мой метод reзов API, интегрированный с Redis на Windows? 
-1  Нужно упростить логическое выражение (байт, короткое, целое число) Java 
0  карта JSON на провал строки в Java 
17  Перегрузка Java VS переопределения 
0  Прямоугольник и круг Collision Java, используя .Наиград 
-1  Как добавить JTable для JPanel 
1  Установка поля _ID с использованием SQLite & ContentProvider в Android 
0  Должен ли я использовать Mac для разработки Javafx для iOS 
3  Как мне изменить ответ на запрос на параметры http в приложении Spring MVC 2.5? 
5  Конвенции о ведении регистрации [Закрыто] 
1  Apache Vamel: Как проверить, например, набор набора <customObject> 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.