2013-06-21 2 views
2

У меня есть этот 2 классПолучение экземпляра параметризованного класса в Java

abstract class A 
{ 
//some abstract methods and variables 
} 

class B<E extends A> 
{ 
} 

Теперь в методе B, я хочу, чтобы получить фиктивный экземпляр Е. Как сделать это? Это нормально -

E temp = (E)(new Object()); 

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

ответ

3

Вам необходимо будет передать объект-конструктор (или экземпляр) в конструктор для B. Нет способа указать, что параметр generic type имеет конкретный конструктор, а статический тип недоступен во время выполнения.

(. Вы могли бы подделать выделенное значение с E temp = (E)new A() { };, но это хорошо хитроумный Некоторые из кода коллекции делает нечто подобное только с массивами.)

3

У вас есть 2 решения:

  • If E имеет конструктор no-arg, вы можете использовать отражение для его построения.
  • Вы можете сделать абстрактный метод abstract E buildE();

Для первого решения, вам придется пройти класс в качестве параметра своего конструктора:

class B<E extends A>{ 

    public B(Class<E> clazz){ 
    //Create instance of E: 
    E e=clazz.newInstance(); 
    } 
} 

Для второго решения , это означает, что класс B имеет абстрактный метод построения объекта (он более или менее эквивалентен прохождению фабрики):

public class B<E extends A>{ 

    public abstract E buildE(); 

    private void foo(){ 
    E e = buildE(); 
    //Do generic stuff with E 
    } 

} 

Таким образом, если вы создаете подкласс класса B, вы должны реализовать этот метод

public class B1 extends B<Bar>{ 

    //You are required to implement this method as it is abstract. 
    public Bar buildE(){ 
    .. 
    } 

    private void anyMethod(){ 
    //call B.foo() which will use B1.buildE() to build a Bar 
    super.foo(); 
    } 

} 

ИМХО, второе решение гораздо чище.

+0

Можете ли вы представить подробную информацию о вашем втором предлагаемом решении? – ksb

+0

Я отредактировал ответ. –

-1

Вы можете использовать отражение в B, чтобы получить Class<E>, а затем получить нужный конструктор и вызвать newInstance

(Class<E>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0] 
+0

-1 Это предполагает, что 'this' является экземпляром класса, расширяющего' B' и разрешающего его параметр типа с конкретным типом, например. 'class C extends B '. –

+0

@Paul Bellora Вопрос спрашивает «в методе B, я хочу получить фиктивный экземпляр E», поэтому «это», конечно, конкретный класс. – Alan