小弟在使用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的反射机制但是具体应该如何实现。看了很多反射实例也没找到方法。
希望高手给予解决,小弟在此谢过。

解决方案 »

  1.   

    给个例子, 说说方法怎么用吧。Class c = Class.forName('className') 得到对就类的Class (带包名 记住了)c.newInstance() 得到无参的c 一个实例 相当于:new className();
    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上说的很清楚。
      

  2.   

    newInstance()的那个类必须要有无参数的构造函数,否则实例化失败package co.com.comm;public class Base {    private SymbolBase symbol = null;
        
        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());
        }
        
    }
      

  3.   

    说得很正确,API中也确实有,而且,网上这些资料也不少,但是能不能根据我给出的代码进行使用?
    至于我想如何使用,在我给出的代码中Base类里有一个main方法,已经进行了调用。
      

  4.   


    前面部分没什么问题。但是在下面执行
    symbol.doPaser();((SymbolC1) symbol).getSymbolStr();
    部分,即然我都要知道SymbolC1了,我认为我没有必要就使用反射了。我是想所括这部分也是可以使用反射过来的。
      

  5.   

    自己写了一种方法但是这种方法是否可取希望大家提出意见。package co.com.comm;import java.lang.reflect.Method;public class Base { private Class<?> symbol = null;
    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();
    }
    }
      

  6.   

    看了上面的代码:反射简单的这是这样写的:public 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是有作用域的。