2016-02-18 2 views
3

возможно дать аргумент типа для общего класса через переменную:Java Generics Тип Аргумент как переменная возможна?

private static final Class clazz = String.class; 

ArrayList<clazz> list = new ArrayList<>(); 

В этом примере я получаю сообщение об ошибке компилятора. Так почему это невозможно?

+4

Вы смешиваете понятия времени компиляции и времени выполнения. Дженерики предназначены для проверки типов во время компиляции. Они не полезны, если вы не знаете тип до выполнения. Вы не можете использовать значение переменной, которое вы знаете только во время выполнения, в качестве параметра типа. – Jesper

+0

Нет, поскольку аргумент type является infact 'type', а не объектом класса для каждого. –

ответ

4

Как @Jesper сказал, вы пытаетесь пересечь области времени компиляции и времени выполнения.

Прежде всего, поймите, что Java-дженерики - это функция строго компиляции - то есть когда ваш источник java компилируется в байтовый код, «дженерики», как вы видите их в своем источнике, ушли. Я бы предложил прочитать на type erasure для получения дополнительной информации по этому вопросу.

Так что же делает компилятор с дженериками? Он проверяет, что действия и операции безопасны, а затем автоматически вставляет различные операции в ваш скомпилированный код для вас. Здесь проблема заключается в том, что вы запрашиваете компилятор для выполнения операций на основе параметра, предоставленного во время выполнения. Суть в том, что, поскольку компилятор не имеет доступа к значениям времени выполнения, он не может скомпилировать генерические файлы и возникает ошибка.

Отличная дискуссия о том, почему Java Generics были разработаны без овеществления @ Neal Gafter's Blog.

0

Компилятор не может поддерживать динамическое значение для своего общего типа, потому что во время выполнения вы можете поменять String на другой тип, и вдруг он не должен компилироваться, но уже слишком поздно, потому что он работает! Правильный способ сделать это - использовать интерфейсы или абстрактные классы, чтобы указать, что данный тип должен быть подклассом этого.

Примером может быть ArrayList< ? extends Collection<?> >. Это гарантирует, что этот тип можно использовать как коллекцию, так как этот тип должен быть подклассом Collection.

See here если вы хотите прочитать эту тему.

Смежные вопросы