Вы можете загрузить новый код в новый класс погрузчиков относительно легко:
Случай 1: Если ваши классы имеют общий родительский интерфейс (или класс) в текущем контексте, например, Runnable, вы можете использовать этот код:
public void doMyClassLogicVersion1() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL1 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();
}
public void doMyClassLogicVersion2() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL2 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();
}
Случай 2: Если классы не разделяют общий предок:
public void doMyClassLogicVersion1() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL1 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
// Avoid Class.newInstance, for it is evil.
Constructor<?> ctor = runClass.getConstructor();
Object obj = ctor.newInstance();
String methodName = "getName";
java.lang.reflect.Method method;
try {
method = clazz.getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
// ...
} catch (IllegalAccessException e) {
// ...
} catch (InvocationTargetException e) {
// ...
}
}
public void doMyClassLogicVersion2() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL2 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
// Avoid Class.newInstance, for it is evil.
Constructor<?> ctor = runClass.getConstructor();
Object obj = ctor.newInstance();
String methodName = "getName";
java.lang.reflect.Method method;
try {
method = clazz.getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
// ...
} catch (IllegalAccessException e) {
// ...
} catch (InvocationTargetException e) {
// ...
}
}
ответа на удаляемый вопрос: почему URLClassLoader.newInstance? URLClassLoader.newInstance создает новый экземпляр URLClassLoader для указанных URL-адресов и загрузчика родительского класса по умолчанию. Если установлен диспетчер безопасности, метод loadClass для URLClassLoader, возвращаемый этим методом, вызывается SecurityManager.checkPackageAccess перед загрузкой класса. Источник: http://download.java.net/jdk8/docs/api/java/net/URLClassLoader.html#newInstance%28java.net.URL[]%29 –
Спасибо mohammad, но мне все еще нужно ссылаться на конкретный метод содержит загруженный класс. так что придет с ур кодом. и есть два пата, которые содержат конструктор myClass. – Salah
Имеют ли эти два класса один и тот же родительский класс? Если они есть, то вы можете заменить этот родительский класс Runnable в моем коде. –