Очень простое Java Dynamic Casting - PullRequest
       19

Очень простое Java Dynamic Casting

5 голосов
/ 12 декабря 2011

Простой вопрос, но я потратил на это больше часа.Мой код ниже.Мне нужно сделать SomeClass sc динамическим.Таким образом, вы передаете имя класса в виде строки в функции и используете этот класс вместо статического someClass.Как это сделать?

SomeClass sc;
if (someOtherClassObject instanceof SomeClass){
    sc=(SomeClass) someOtherClassObject;

То, что я хочу, это

public void castDynamic (String strClassName){
  //cast the classname referred by strClassName to SomeClass 
  //if it is the  instance of SomeClass
}

РЕДАКТИРОВАТЬ: Выше было упрощение.Фактический код такой:

public void X(String className, RequestInterface request)
{
    //My current code is this, I need to change so that "XRequest"
    //can be any   class referred by "className", 
    //and "request.getRequest" the object belonging to "className" class
    //I don't want static XRequest xvr, it should be fetched dynamically

    XRequest xvr;
    if (request.getRequest() instanceof XRequest){
        xvr=(XRequest) request.getRequest();
        client.setRequest(xvr); 
    }
}

Еще одна простая перефразировка: я получаю объект с помощью request.getRequest ().Я понятия не имею, что это за объект.Поэтому мне нужно привести его к указанному имени класса.Как это сделать?Это все.- SQC 13 минут назад

Ответы [ 3 ]

7 голосов
/ 13 декабря 2011

Вы хотите создать экземпляр класса по его имени?

Прежде всего, вам необходимо создать Class<?> объект:

Class<?> cls = Class.forName(strClassName);

Затем создать экземплярэто (обратите внимание, это может привести к различным исключениям - нарушение доступа, ClassNotFound, нет public конструктор без аргументов и т. д.)

Object instance = cls.newInstance();

Затем вы можете привести его:

return (SomeClass) instance;

Пожалуйста, убедитесь, что вы понимаете разницу между:

  1. Класс имя (приблизительно имя файла)
  2. Класс объект (по сути тип информация)
  3. Класс экземпляр (фактический объект этого типа)

Вы также можетеприведите объект cls к типу Class<? extends SomeClass>, если хотите.Это не дает вам много, хотя.И вы можете встроить его в:

return (SomeClass)(Class.forName(strClassName).newInstance());

О, но вы можете выполнить проверку типа с помощью объекта cls, прежде чем создавать его.Таким образом, вы создаете его только в том случае, если он удовлетворяет вашему API (реализует интерфейс, который вы хотите получить).

РЕДАКТИРОВАТЬ: добавить дополнительный пример кода к отражению .

Дляпример:

if (cls.isInstance(request)) {
  // ...
}

Для вызова методов вам либо нужно знать интерфейс, который вы можете привести, либо использовать reflections (методы getMethod объекта cls):

Method getRequest = cls.getMethod("getRequest");
getRequest.invoke(request);
7 голосов
/ 13 декабря 2011

Проблема, которую вы описываете, недостаточно четко определенаПриведение - это операция, которая берет объект и класс, а затем проверяет, является ли этот объект экземпляром данного класса.

Однако вы говорите, что вам нужно что-то, что cast(s) the classname referred by strClassName to SomeClass if it is the instance of SomeClass.Другими словами, вы ищете что-то, что работает с двумя классами (а не с классом и объектом).

Итак, нам нужно переформулировать проблему.Вот три возможных проблемы (+ решения) Я надеюсь, что одна из них - это то, что вам нужно

// Problem 1: check whether "object" can be casted to the class 
// whose name is "className"
public void castDynamic(Object object, String className) {
  Class cls = Class.forName(className);
  cls.cast(object);
}

// Problem 2: check whether the class whose name is "className" 
// is a subclass of SomeClass (A is a subclass of B if A (transitively) 
// extends or implements B).
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  SomeClass.class.asSubclass(cls);
}


// Problem 3: check whether SomeClass is a sublcass the class 
// whose name is "className"
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  cls.asSubclass(SomeClass.class);
}

Полная информация: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class)

1 голос
/ 12 декабря 2011

Вы имеете в виду?

 Class clazz = Class.forName(strClassName);
...