Как я могу использовать отражение для создания общих подтипов? - PullRequest
0 голосов
/ 01 апреля 2011

Я использую шаблон Factory, чтобы скрыть некоторую сложность создания экземпляра.У меня есть это:

class FooInt extends Foo<int>;

Я хочу сделать:

class<Foo<?>> fooType = FooInt.class;

Все производные типы Foo имеют один конструктор, принимающий 2 аргумента.Поэтому мне нужно использовать отражение для создания экземпляров подтипов:

Constructor<Foo<?>> ctor = fooType.getContructor(Blah.class, Blahblah.class);
return ctor.newInstance(blah, blahblah);

Но Джавак говорит:

"Type mismatch: cannot convert from Class<FooInt> to Class<Foo<?>>"

Что я делаю не так?Можно ли использовать отражение таким образом?

Ответы [ 3 ]

2 голосов
/ 01 апреля 2011

попробуй: Class<? extends Foo<?>> fooType = FooInt.class;

Еще один момент:

  • Тип класса Class не class (верхний регистр C);
  • вы не можете использовать примитивы в дженериках (используйте Integer вместо int)

Добавлено: и вот как это работает:

public class Foo<T> {

    private T value;

    public Foo(T value) {    
        this.value = value;
    }      
}

public class FooInt extends Foo<Integer>{
    public FooInt(Integer value) {
        super(value);
    }
}

public class FooDouble extends Foo<Double>{
    public FooDouble(Double value) {
        super(value);
    }
}

Фабрика (хотя бы одна строка, но много исключений ;-)):

import java.lang.reflect.InvocationTargetException;

public class Factory {

    <P, T extends Foo<P>> T build(Class<T> clazz, P param)
            throws IllegalArgumentException, SecurityException,
               InstantiationException, IllegalAccessException,
               InvocationTargetException, NoSuchMethodException {
        return clazz.getConstructor(param.getClass()).newInstance(param);
    }

    public static void main(String[] args)
            throws IllegalArgumentException, SecurityException,
                InstantiationException, IllegalAccessException,
                InvocationTargetException, NoSuchMethodException {

        Factory f = new Factory();

        System.out.println(f.build(FooInt.class, Integer.valueOf(1)));
        System.out.println(f.build(FooDouble.class, Double.valueOf(1.1)));
    }
}
1 голос
/ 01 апреля 2011

Я думаю, что Ральф имел в виду это.Лично я не чувствую, что вы должны сыграть

 Class<? extends Foo> fooType = FooInt.class;
0 голосов
/ 01 апреля 2011

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

...