Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Почему не даёт получить class аргумента?


Автор: Dims 19.12.2007, 20:33
Хочу написать абстрактный класс "Метод", который бы реагировал на определённый тип вызова, класс Call. Сваленные в кучу методы можно было бы просматривать, проверять, какой тип вызова данный метод получает -- и вызывать для него run.

Но не даёт.

Код

public class Method<T extends Call> {
   
   public Class<T> getCallClass1() {
      return new Class<T>();
   }
   
   public Class<T> getCallClass2() {
      return T.class;
   }

}


В первом случае ругается на то, что конструктор типа Class является приватным.

Во втором случае ругается на то, что нельзя select from a type variable.

Почему это всё запрещено?

Автор: nornad 19.12.2007, 21:59
Ну, естественно. Чтобы выдать класс нужен объект этого класса.

Автор: Dims 19.12.2007, 22:25
Цитата(nornad @  19.12.2007,  21:59 Найти цитируемый пост)
Чтобы выдать класс нужен объект этого класса.

Чтобы выдать класс по объекту, нужно воспользоваться методом getClass(). А поле class позволяет выдать класс не объекта, а класса.

Автор: ivg 19.12.2007, 23:40
Цитата(Dims @  19.12.2007,  20:33 Найти цитируемый пост)
Почему это всё запрещено?

А вы почитайте про generics в Java.
Цитата(Dims @  19.12.2007,  20:33 Найти цитируемый пост)
В первом случае ругается на то, что конструктор типа Class является приватным

Всё правильно. Объект типа Class, для каждого конкретного класса не должен существовать в нескольких экземплярах. Грубо говоря, такой объект имеет особый статический контекст своего существования (Сравнение с синглтоном наверно будет не совсем корректно). Только JVM может создавать такие объекты.
Это конечно не имеет отношения к generics, а вот во втором случае все просто.
Generics в Java - это шаблоны времени компиляции. Что должен сгенерировать компилятор на эту строку:
Код

return T.class;
?
Это станет известно, когда вы в коде подставите вместо параметра шаблона нужный тип. Но класс Method<T extends Call> должен быть скомпилирован и без этих знаний, иначе никакого толку от шаблонов нет. А точнее, в таком случае они могут существовать только в виде исходников, а не скомпилированных классов. Понимаете?

Автор: Dims 20.12.2007, 17:59
Цитата(ivg @  19.12.2007,  23:40 Найти цитируемый пост)
Только JVM может создавать такие объекты.

Ну да. Собственно, первый вариант я показал просто для полноты картины, чтобы было видно, куда я рвусь.

Цитата(ivg @  19.12.2007,  23:40 Найти цитируемый пост)
Это станет известно, когда вы в коде подставите вместо параметра шаблона нужный тип.

Это неочевидно. Почему так? 

Автор: serger 21.12.2007, 06:44
Цитата(Dims @ 20.12.2007,  17:59)
Цитата(ivg @  19.12.2007,  23:40 Найти цитируемый пост)
Это станет известно, когда вы в коде подставите вместо параметра шаблона нужный тип.

Это неочевидно. Почему так?

1. Ну потомучто это что-то типа предпроцессора.
2. Это и сделано для контроля типов в момент компиляции.
3. Ну и почитайте всё-таки "generics".

Автор: Dims 21.12.2007, 17:32
Вроде бы читал, но для меня это всё равно не очевидно. Можно поточнее ткнуть меня, где это написано?

Автор: LSD 21.12.2007, 18:40
Цитата(Dims @  21.12.2007,  17:32 Найти цитируемый пост)
Вроде бы читал, но для меня это всё равно не очевидно.

То что ты хочешь требует создание нового класса на каждый параметризованный тип. В .NET именно так и происходит, в Java выбрали другой путь. Т.е. генрики всего лишь берут на себя проверку типов во время компиляции, и все.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)