Java 使用自定义类加载器加载静态方法
我有一个自定义类加载器,如下所示Java 使用自定义类加载器加载静态方法,java,classloader,static-methods,Java,Classloader,Static Methods,我有一个自定义类加载器,如下所示 import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class MyClassLoader extends ClassLoader { public String invoke(final String className, final String methodName, final String someString) {
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MyClassLoader extends ClassLoader
{
public String invoke(final String className, final String methodName, final String someString)
{
try {
final ClassLoader classLoader = getClass().getClassLoader();
final Class loadedClass = classLoader.loadClass(className);
final Constructor constructor = loadedClass.getConstructor();
final Object myClassObject = constructor.newInstance();
final Method method = loadedClass.getMethod(methodName, String.class);
final Object testStr = method.invoke(myClassObject, someString);
System.out.println(loadedClass.getClassLoader());
return (String) testStr;
}
catch (final ClassNotFoundException e) {
e.printStackTrace();
}
catch (final Exception e) {
e.printStackTrace();
}
return null;
}
}
和一个名为Bus的类
public class Bus
{
public static String connection(final String incoming)
{
return "Bus " + incoming;
}
}
和一个Tester类来测试代码
public class Tester
{
public static void main(final String[] args) throws InterruptedException
{
for (int i = 0; i < 3; i++) {
final MyClassLoader mcl = new MyClassLoader();
final String s = mcl.invoke("Bus", "connection", "awesome");
System.out.println("Tester: " + s);
Thread.sleep(300);
}
}
}
公共类测试器
{
公共静态void main(最终字符串[]args)引发InterruptedException
{
对于(int i=0;i<3;i++){
最终MyClassLoader mcl=新MyClassLoader();
最后一个字符串s=mcl.invoke(“总线”、“连接”、“很棒”);
System.out.println(“测试仪:+s”);
睡眠(300);
}
}
}
问题:为什么MyClassLoader中的sysout总是打印相同的对象(也称为类加载器)?我做错了什么
我想要实现的是,对于Tester类中的每个迭代,我希望将Bus类加载到一个新的类加载器中您的自定义类加载器
MyClassLoader
使用loadClass(String className)java.lang.ClassLoader的方法
。loadClass的方法
根据委托的原则工作,唯一性和可视性。首先,自定义的MyClassLoader
检查父类加载器是否已加载该类。由于尚未定义MyClassLoader的父类加载器,因此需要使用getSystemClassLoader()执行SystemClassLoader
因此,实际上,您的类是由SystemClassLoader加载的,所有对象都是由单个ClassLoader加载的。根据唯一性原则,每个类只由其父类或自身加载一次
MyClassLoader当前的工作方式:-
public class MyClassLoader extends ClassLoader
{
//supplied by compiler
public MyClassLoader(){
super();
}
}
使用SystemClassLoader
加载类的java.lang.ClassLoader
的默认构造函数
protected ClassLoader() {
this.parent = getSystemClassLoader();
initialized = true;
}
loadClass
java.lang.ClassLoader的方法-
308 protected synchronized Class<?> More ...loadClass(String name, boolean resolve)
309 throws ClassNotFoundException
310 {
311 // First, check if the class has already been loaded
312 Class c = findLoadedClass(name);
313 if (c == null) {
314 try {
315 if (parent != null) {
316 c = parent.loadClass(name, false);
308受保护的同步类更多…loadClass(字符串名称,布尔解析)
309抛出ClassNotFoundException
310 {
311//首先,检查类是否已加载
312 c类=findLoadedClass(名称);
313如果(c==null){
314试试看{
315如果(父级!=null){
316 c=parent.loadClass(名称,false);
您需要实现自己的类加载器,而不仅仅是使用系统类加载器。以下是一种非常简单的方法,仅当类文件位于预期目录中时才有效
public class MyClassLoader extends ClassLoader
{
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
byte b[] = Files.readAllBytes(Paths.get("target/classes/"+name+".class"));
ByteBuffer bb = ByteBuffer.wrap(b);
return super.defineClass(name, bb,null);
} catch (IOException ex) {
return super.loadClass(name);
}
}
public String invoke(final String className, final String methodName, final String someString)
{
try {
final ClassLoader classLoader = this;
公共类MyClassLoader扩展了ClassLoader
{
@凌驾
公共类loadClass(字符串名称)引发ClassNotFoundException{
试一试{
字节b[]=Files.readAllBytes(path.get(“target/classes/”+name+“.class”));
ByteBuffer bb=ByteBuffer.wrap(b);
返回super.defineClass(name,bb,null);
}捕获(IOEX异常){
返回super.loadClass(名称);
}
}
公共字符串调用(最终字符串类名称、最终字符串方法名称、最终字符串someString)
{
试一试{
最终类加载器类加载器=此;
…由于委托原则,您的类由SystemClassLoader而不是MyClassLoader加载。