2013-06-26 2 views
1

У меня есть следующие классы.Кастинг класса с использованием отражения в java

abstract class A{} 

class B extends A{} 

class C extends A{} 

Мне нужно создать объект, как этот

A a = new B(); 

я получаю имя класса подкласса во время выполнения. Итак, мне нужно использовать отражение для создания объекта.

Я сделал это.

Class<?> klass = Class.forName(className); 

Теперь я не могу отнести этот класс к подклассу.

Я хочу добиться

A a = klass.newInstance(); // returns Object 

Я хочу, чтобы объект быть отлиты в подкласс (или B или C, решил на время выполнения)

Как это сделать?

+3

Что случилось с 'A a = (A) klass.newInstance();'? –

+0

@AleksG Мне нужно получить доступ к функциям в подклассе. – rgksugan

+0

Что не так с 'switch (name) {case" B ": return new B(); case «C»: вернуть новый C(); default: throw new SomeException(); } '?/Что случилось с 'Class.newInstance'? Много. Если вы проходите через 'Constructor.newInstance', лучше использовать' asSubclass' спереди. –

ответ

3

Вы можете использовать дженерики объявить

Class<? extends A> klass; 

тогда вы будет разрешено писать

A a = klass.newInstance(); 

Однако, поскольку Class.forName не имеет информации о типе вашего класса и не имеет объявлений о типе, вы получите предупреждения «непроверенного броска». Этот подход не более типичен, чем просто опускание результата второй линии до A.

+0

Несовместимые типы. найдено: Класс > – rgksugan

+0

Да. Для правой части вам нужен явный перевод. Во всяком случае, это не дает вам много пробега: вы не можете создать безопасный тип кода, безопасный для кода. –

+0

'A a = Class.forName (...) .asSubclass (A.class) .newInstance();' даже работает без слепых типов и является безопасным. – Holger

2

Я хочу, чтобы объект быть отлит в подкласс (или B или C, решил на время выполнения)

Это не имеет никакого смысла. Кастинг - это что-то, что является прежде всего операцией с компиляцией, чтобы получить выражение соответствующего типа. Затем он проверяется во время выполнения.

Если вы действительно пытаетесь достичь переменной типа A, то вам нужно только бросить в A:

A a = (A) klass.newInstance(); 
1

Имея klass объект типа Class<T> можно назвать Class.cast() метод преобразованными к типу T использования

klass.cast(object) 

Например, у Вас есть a типа B, разыгрывание a к типу B загружаются во время выполнения.

Class<?> klass = Class.forName("B"); 
klass.cast(a); 
0

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

Class klass = Class.forName(className); 
A a = (A)klass.newInstance(); 

или

Class<? extends A> klass = Class.forName(className); 
A a = klass.newInstance(); 

Затем вы можете вызвать метод на него:

klass.getMethod(methodName, null).invoke(); 

Или, если метод принимает аргументы (например, int и String)

int param1 = ...; 
String param2 = ...; 
klass.getMethod(a, new Class[] { Integer.class, String.class }).invoke(param1, param2); 

Конечно, вы должны быть поймать соответствующие исключения.