Java: правильно проверенный экземпляр класса с использованием отражения - PullRequest
5 голосов
/ 12 апреля 2011

Я пытаюсь использовать одну из самых простых форм отражения для создания экземпляра класса:

package some.common.prefix;

public interface My {
    void configure(...);
    void process(...);
}

public class MyExample implements My {
    ... // proper implementation
}

String myClassName = "MyExample"; // read from an external file in reality

Class<? extends My> myClass =
    (Class<? extends My>) Class.forName("some.common.prefix." + myClassName);
My my = myClass.newInstance();

Типизируя неизвестный объект класса, который мы получили от Class.forName, выдается предупреждение:

Type safety: Unchecked cast from Class<capture#1-of ?> to Class<? extends My>

Я пытался использовать instanceof метод проверки:

Class<?> loadedClass = Class.forName("some.common.prefix." + myClassName);
if (myClass instanceof Class<? extends RST>) {
    Class<? extends My> myClass = (Class<? extends My>) loadedClass;
    My my = myClass.newInstance();
} else {
    throw ... // some awful exception
}

, но это приводит к ошибке компиляции: Cannot perform instanceof check against parameterized type Class<? extends My>. Use the form Class<?> instead since further generic type information will be erased at runtime. Так что я не могу использовать instanceof подход.

Как мне избавиться от этого и как я должен делать это правильно?Можно ли вообще использовать отражение без этих предупреждений (т.е. без их игнорирования или подавления)?

Ответы [ 3 ]

5 голосов
/ 12 апреля 2011

Вот как вы это делаете:

/**
 * Create a new instance of the given class.
 * 
 * @param <T>
 *            target type
 * @param type
 *            the target type
 * @param className
 *            the class to create an instance of
 * @return the new instance
 * @throws ClassNotFoundException
 * @throws IllegalAccessException
 * @throws InstantiationException
 */
public static <T> T newInstance(Class<? extends T> type, String className) throws
        ClassNotFoundException,
        InstantiationException,
        IllegalAccessException {
    Class<?> clazz = Class.forName(className);
    Class<? extends T> targetClass = clazz.asSubclass(type);
    T result = targetClass.newInstance();
    return result;
}


My my = newInstance(My.class, "some.common.prefix.MyClass");
4 голосов
/ 12 апреля 2011

Я думаю, вы можете сделать это следующим образом:

Class<? extends My> myClass= null;
Class<?> loadedClass = Class.forName("some.common.prefix." + myClassName);
if(My.class.isAssignableFrom(loadedClass))
{
    myClass = loadedClass.asSubclass(My.class);
}
My my = myClass.newInstance();
0 голосов
/ 12 апреля 2011

См. Этот вопрос Как мне обратиться к непроверенным предупреждениям приведения? .Я обнаружил, что в случае с отражением лучше всего ответственно использовать @SuppressWarnings("unchecked")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...