问题是这样的,由于两个项目要分开开发,第一个项目要调用另一个项目中的函数,我使用了反射调用,但是返回的数据类型需要自定义,这样我就自定义了class A,然后编译打包了A,构成一个A.jar包,然后发布给另一个项目来直接使用这个数据类型,第一个项目反射调用了第二个项目的某个方法,要返回数据类型A,来供第一个项目使用,第一个项目也包含了A这个jar包;但是结果有问题,反射调用了第二个项目的方法返回的数据Object不能cast 到A;抛出异常,A 无法cast to A;请问下,这个需要怎么处理呢?是因为A.jar的问题,还是java不支持这样的操作?谢谢各位~!Java应用类
解决方案 »
- reflection in action适合刚入行的java程序员么
- swing如何使用窗口的还原按钮?
- The project: Test which is referenced by the classpath, does not exist.
- 关于static的问题
- Could SSL be used to SMTP???
- 请问如何在一个java类里调用生成另外一个java类的批处理文件?
- jdk1.3中关于corba的问题?
- 希望回答!!!
- 各位大虾,推荐一个集成开发环境
- 怎样创建同名外部类的对象?
- java如何使用函数返回多个函数值?求高手知道啊
- java 实现串口助手发送十六进制命令
你有项目A和项目B,还有一个项目里包含了class Type,先叫它项目T
B包含了一个方法:public T method();
A和B都有到T的引用,也就是T分别包含在A和B的classpath里,然后A反射调用B的method,反射API返回一个Object,但是不能被cast到T?
package不相同的话,应该是存在两个类了。
ProjectA:
public class ClassA {
public static void main(final String[] args)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException,
MalformedURLException, InstantiationException {
URLClassLoader urlClassLoader = new URLClassLoader(
new URL[]{new File("/Users/xxx/testJavaProject/projectB/ClassB.jar").toURI().toURL()},
new ClassA().getClass().getClassLoader());
Class<?> classB = Class.forName("ClassB", true, urlClassLoader);
Object objectB = classB.newInstance();
Method method = classB.getDeclaredMethod("method");
Object result = method.invoke(objectB);
Type t = (Type) result;
System.out.println(t.toString());
}
}ProjectB:
public class ClassB {
public final Type method() {
return new Type();
}
}ProjectT:
public class Type {
}编译过程:
1. javac Type.java; jar -cf Type.jar Type.class
2. javac -classpath ../Type/Type.jar ClassB.java; jar -cf ClassB.jar ClassB.class运行:
java -cp .:../Type/Type.jar ClassA输出:Type@75da931b目录切换我就省略了不知道楼主的过程是不是一样
那么,无法强制类型转换,一定是因为,他们(强制转换的类型类和当前对象)不是同一个类加载器对象加载的。解决这个问题,可以从几个方面去入手:
1. 如果两个项目,没有涉及到多线程或者异步处理的框架结构,那么,可以在反射的时候,都使用当前线程上下文环境的类加载器对象,来加载所用到的类,和创建对象。
2. 如果涉及到多线程,那么,两个项目在反射调用之前,都应当用系统加载器将公共的类(本例中A这个类)加载进来,注意,要预先加载,这个预先加载的代码,不要出现在反射代码的那个类,要在这个类之前就预先加载进来。
3. 一般处理这类情况的方式,是这样的:
A:需求所要完成的应该是一个功能接口的开发,所以,涉及到两种类型的类,
一种类定义操作的方法列表,另一种定义方法的参数和返回值;
B:定义操作的类,我们要抽象出接口类,接口类的加载都用系统类加载器进行加载,而接口类的实现类,可以用系统类加载器的下属类加载器加载。(下属类不是子类,不是继承关系,一般是应用程序自定义的类加载器)
C:定义参数和返回值的类,通常也和接口类所使用的加载器对象相同;
D:类加载器的加载顺序是,先判断父级加载器是否加载,如已加载就用已加载的,未加载再由当前对象加载。
public interface MethodList {
Return4Method1 method1(Param4Method1 params);
void method2(Param4Method2 params);
}
public class Return4Method1 { private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public class Param4Method1 { private Object args; public Object getArgs() {
return args;
}
public void setArgs(Object args) {
this.args = args;
}
}
public class Param4Method2 { private Object args; public Object getArgs() {
return args;
}
public void setArgs(Object args) {
this.args = args;
}
}
public interface MethodListFactory { MethodList createInstance();
}
接下来,对方要创建如下两个实现类。
public class DefaultMethodList implements MethodList { public Return4Method1 method1(Param4Method1 params) {
Return4Method1 value = new Return4Method1();
//do something ...
return value;
} public void method2(Param4Method2 params) {
// do some other things ...
}}
public class DefaultMethodListFactory implements MethodListFactory { public MethodList createInstance() {
// 创建接口的实现类对象。
return null;
}}
具体的代码,你不用管。
你只要关心,怎么拿到那个DefaultMethodListFactory类的对象即可。
如果两个项目都集成在spring下,可以使用spring来获得对象;
如果对方提供DefaultMethodListFactory的public的构造器,可以直接new一个出来。
之后的使用,不用我废话了吧,以前不都吵吵着什么面向接口编程么,接下来的代码就是这样的了。