用ClassLoader,可以通过defineClass方法来获得该类的classObj,但是调用该类对象的方法就只能使用反射了吧?看看这个: K.java package pkg; public class K { public K() { } } UseK.java public class UseK { public void newK() { new K(); } } 先把K放到classpath中,这样可以编译完成后把K从classpath中去掉,ok,怎们才能使用UseK的newK()方法呢?通过MyClassLoader可以findClass来找到K类,但即使获得了K的classObj,也无法调用newK方法啊,怎样才能调用newK呢?
假定UseK.java如下,newK()是带参数的package pkg;public class UseK { public void newK(String input) { new K(); } }调用如下, Class[] paramTypes = new Class[] {Class.forName("java.lang.String")}; Object[] args = new Object[] {"aTest"}; Class mClass = Class.forName("pkg.UseK"); Object mObject = mClass.newInstance(); Method mMethod = mObject.getMethod("newK", paramTypes); mMethod.invoke(cmdInstance, args); ......
修正一下最后一行, mMethod.invoke(mObject, args);
已经解决了,但是不知道好不好前提: UseK 和 K 已经被编译了,其中UseK 对 K 有依赖,在使用时 K UseK 被上传到另一台计算机c1上了,其中UseK可以在c1的classpath上,但 K 没有在 c1的classpath上,因此如何让 K 注册到c1的classpath上是UseK 能运行的关键代码: K.java package pkg; public class K { public K() { System.out.println("K() is initialized"); } } UseK.java import pkg.*; public class UseK { public UseK() { new K(); System.out.println("UseK() is called, and create a K instance"); } }public class Demo { public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException { ClassLoader loader = ClassLoader.getSystemClassLoader(); Class loaderCls = loader.getClass(); // jvm的ClassLoader继承了URLClassLoaderCls,URLClassLoader继承了 // SecureClassLoader,SecureClassLoader继承了ClassLoader Class urlClassLoaderCls = loaderCls.getSuperclass(); Class secureClassLoaderCls = urlClassLoaderCls.getSuperclass(); Class classLoaderCls = secureClassLoaderCls.getSuperclass(); // 也可以使用urlClassLoader的addURL,那就不用secureClassLoaderCls // 和classLoaderCls了 Method findClass1Arg = classLoaderCls.getDeclaredMethod("findClass", new Class[]{ String.class} ); findClass1Arg.setAccessible(true); try { Object o = findClass1Arg.invoke(loader,new Object[] { "pkg.K" }); System.out.println("pkg.K is loaded into memory."); new UseK(); return ; } catch(Exception e) { System.out.println("load pkg.K"); } // d:/pkg/K.class并没有放在classpath中 InputStream is = new FileInputStream("d:/pkg/K.class"); byte[] clsBytes = new byte[is.available()]; is.read(clsBytes, 0, clsBytes.length); // 把pkg.K注册到jvm的ClassLoader中 Method defineClass4Args = classLoaderCls.getDeclaredMethod("defineClass", new Class[]{ String.class, byte[].class, int.class, int.class }); defineClass4Args.setAccessible(true); defineClass4Args.invoke(loader, new Object[] {"pkg.K", clsBytes, new Integer(0), new Integer(clsBytes.length), } ); new UseK(); }
楼上的这种做法是可以的[菜鸟1/2提供],如果UseK也不在c1的classpath中,可以把UseK象 K 那样把UseK注册到jvm的ClassLoader中to orchisliu() 可能我说的不太清楚,K和 UseK都不在classpath中楼上的这种做法是可以的,有没有比楼上的办法更好的方法
写个批处理文件a.bat set classpath=要什么自己写然后在你的java程序里调用这个bat 文件。
首先感谢大家的热心帮助,看来是我说的不太明白
看一下tomocat吧,不论那一个webapp,都有一个lib,你可以吧.jar放到lib中,只用在jsp/servlet中使用lib下的jar就可以了,这个jar也并没有在classpath中设置,为什么tomcat能找到这个.jar中的类呢?这样的程序怎么写 谢谢
一般这样的程序都是自己实现ClassLoader的,
有一种ClassLoader是URLClassLoader,他可以到指定路径去寻找class文件或者jar文件。
K.java
package pkg;
public class K {
public K() { }
}
UseK.java
public class UseK {
public void newK() {
new K();
}
}
先把K放到classpath中,这样可以编译完成后把K从classpath中去掉,ok,怎们才能使用UseK的newK()方法呢?通过MyClassLoader可以findClass来找到K类,但即使获得了K的classObj,也无法调用newK方法啊,怎样才能调用newK呢?
public void newK(String input) {
new K();
}
}调用如下,
Class[] paramTypes = new Class[] {Class.forName("java.lang.String")};
Object[] args = new Object[] {"aTest"}; Class mClass = Class.forName("pkg.UseK");
Object mObject = mClass.newInstance(); Method mMethod = mObject.getMethod("newK", paramTypes);
mMethod.invoke(cmdInstance, args); ......
mMethod.invoke(mObject, args);
K.java
package pkg;
public class K {
public K() {
System.out.println("K() is initialized");
}
} UseK.java
import pkg.*;
public class UseK {
public UseK() {
new K();
System.out.println("UseK() is called, and create a K instance");
}
}public class Demo { public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class loaderCls = loader.getClass();
// jvm的ClassLoader继承了URLClassLoaderCls,URLClassLoader继承了
// SecureClassLoader,SecureClassLoader继承了ClassLoader
Class urlClassLoaderCls = loaderCls.getSuperclass();
Class secureClassLoaderCls = urlClassLoaderCls.getSuperclass();
Class classLoaderCls = secureClassLoaderCls.getSuperclass();
// 也可以使用urlClassLoader的addURL,那就不用secureClassLoaderCls
// 和classLoaderCls了
Method findClass1Arg =
classLoaderCls.getDeclaredMethod("findClass", new Class[]{ String.class} );
findClass1Arg.setAccessible(true);
try {
Object o = findClass1Arg.invoke(loader,new Object[] { "pkg.K" });
System.out.println("pkg.K is loaded into memory.");
new UseK();
return ;
} catch(Exception e) { System.out.println("load pkg.K"); }
// d:/pkg/K.class并没有放在classpath中
InputStream is = new FileInputStream("d:/pkg/K.class");
byte[] clsBytes = new byte[is.available()];
is.read(clsBytes, 0, clsBytes.length);
// 把pkg.K注册到jvm的ClassLoader中
Method defineClass4Args =
classLoaderCls.getDeclaredMethod("defineClass", new Class[]{ String.class,
byte[].class, int.class, int.class });
defineClass4Args.setAccessible(true);
defineClass4Args.invoke(loader, new Object[] {"pkg.K", clsBytes,
new Integer(0), new Integer(clsBytes.length), } );
new UseK();
}
set classpath=要什么自己写然后在你的java程序里调用这个bat 文件。
@set classpath=%classpath%;你的路径;