小弟在使用Java的反射机制时遇到了一些问题。希望得到大家的帮助。有两个类一个叫
SymbolBase里面有doPaser方法。
一个SymbolC1继承SymbolBase类,实现自己的一些方法。而在另一个执行类中。Base类中我在定义的时候定义SymbolBase但是在实例的时候采用SymbolC1。由于有很多个SymbolCX所以需要使用反射根据名称进行实例。
package co.com.comm;public class Base { private SymbolBase symbol = null;
public Base(){
symbol = new SymbolC1("String");
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();
}
public static void main(String[] args){
Base base = new Base();
}
}package co.com.comm;public class SymbolC1 extends SymbolBase{ public SymbolC1(String strVal) {
super(strVal);
// TODO 自動生成されたコンストラクター・スタブ
} public void getSymbolStr(){
System.out.print("SymbolC1 getString!");
}
}package co.com.comm;public class SymbolBase {
private String strname = "";
public SymbolBase(String strVal){
this.strname = strVal;
}
public void doPaser(){
System.out.println("Base Paser!");
}
}我的问题是,我想在Base中通过Class.forName来自动根据一个字符串实例化相应的SymbolCX。即SymbolC1,SymbolC2,而且像上面那样使用。
我能想到的是使用Java的反射机制但是具体应该如何实现。看了很多反射实例也没找到方法。
希望高手给予解决,小弟在此谢过。
SymbolBase里面有doPaser方法。
一个SymbolC1继承SymbolBase类,实现自己的一些方法。而在另一个执行类中。Base类中我在定义的时候定义SymbolBase但是在实例的时候采用SymbolC1。由于有很多个SymbolCX所以需要使用反射根据名称进行实例。
package co.com.comm;public class Base { private SymbolBase symbol = null;
public Base(){
symbol = new SymbolC1("String");
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();
}
public static void main(String[] args){
Base base = new Base();
}
}package co.com.comm;public class SymbolC1 extends SymbolBase{ public SymbolC1(String strVal) {
super(strVal);
// TODO 自動生成されたコンストラクター・スタブ
} public void getSymbolStr(){
System.out.print("SymbolC1 getString!");
}
}package co.com.comm;public class SymbolBase {
private String strname = "";
public SymbolBase(String strVal){
this.strname = strVal;
}
public void doPaser(){
System.out.println("Base Paser!");
}
}我的问题是,我想在Base中通过Class.forName来自动根据一个字符串实例化相应的SymbolCX。即SymbolC1,SymbolC2,而且像上面那样使用。
我能想到的是使用Java的反射机制但是具体应该如何实现。看了很多反射实例也没找到方法。
希望高手给予解决,小弟在此谢过。
c.getDeclaredConstructor(Class... parameterTypes).newInstance(Object... parameterTypes) 得到带参的c 一个实例; 相当于:new className(参数列表);c.getDeclaredFields() 得到所有字段。
c.getDeclaredMethods() 得到所有方法。
Method m = c.getDeclaredMethod(String name, Class... parameterTypes) 得到指定方法名的方法。 第二个参数是参数列表。得到方法后:m.invoke(Object obj, Object... args) ; 执行方法, 第一个参数是指定的对象, 第二个是参数列表。自己总结了一下, 这是常用的。 你看看吧, API上说的很清楚。
public Base(String type){
try
{
symbol = (SymbolBase)Class.forName(type).newInstance();
}
catch(Exception e)
{
e.printStackTrace();
}
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();
}
public static void main(String[] args){
SymbolC1 c1 = new SymbolC1("c1");
Base b = new Base(c1.getClass().getName());
}
}
至于我想如何使用,在我给出的代码中Base类里有一个main方法,已经进行了调用。
前面部分没什么问题。但是在下面执行
symbol.doPaser();((SymbolC1) symbol).getSymbolStr();
部分,即然我都要知道SymbolC1了,我认为我没有必要就使用反射了。我是想所括这部分也是可以使用反射过来的。
private Object obj = null;
public Base(){
/*symbol = new SymbolC1("String");
symbol.doPaser();
((SymbolC1) symbol).getSymbolStr();*/
try {
symbol = Class.forName("co.com.comm.SymbolC1");
Class[] params = {Class.forName("java.lang.String")};
String[] val = {"Test"};
obj = symbol.getConstructor(params).newInstance(val);
Method method = symbol.getMethod("doPaser", null);
method.invoke(obj, null);
method = symbol.getMethod("getSymbolStr", null);
method.invoke(obj, null);
} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}
public static void main(String[] args){
Base base = new Base();
}
}
try {
symbol = Class.forName("co.com.comm.SymbolC1");
//Class[] params = {Class.forName("java.lang.String")};
//String[] val = {"Test"};
// obj = symbol.getConstructor(params).newInstance(val);
obj = symbol.getConstructor(new Class[]{String.class}).newInstance(new Object[]{"test"});
//这不用Class.forName("java.lang.String")
Method method = symbol.getMethod("doPaser", null);
method.invoke(obj, null);
method = symbol.getMethod("getSymbolStr", null);
method.invoke(obj, null);
} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}还有一点就是:getMethod是有作用域的。