最近在用网络编程做一个小型服务器,在做映射这一块时遇到一个小问题:获得handler后如何跳到对应的类中执行,即如何根据类名创建实例。
这里有两种形式:带参数和不带参数,下面是我的理解,是否完全正确有待考证:
1.对于不带参数的情况,首先得到该类的Class对象,再调用newInstance方法即可得到空参数列表的实例,即:
Class c = Class.forName(className);//注意传进来的是完全限定名,即带上包名等
c.newInstance();
2.若要创建带参数的实例,则需要在得到该类的Class对象后,获得一个构造器,方法为Class.getConstructor(Class...parameterTypes),例如Class.getConstructor(String.class,OutputStream.class),表示一个参数列表类型为(String,OutputStream)的构造方法,返回值为java.lang.reflect.Constructor,此类中有方法newInstance(Object...parameters),即对此构造器传参数,得到对应的实例,下面是创建handler包中的一个类IndexHandler实例的例子,其中在IndexHandler类中有一构造方法为public IndexHandler(OutputStream outputStream,String request):
Class c = Class.forName("handler."+handler);
java.lang.reflect.Constructor constructor = c.getConstructor(OutputStream.class,String.class);//顺序不可变
constructor.newInstance(outputStream,str);
由于返回值属于泛型,所以若不知道类的具体类名,是不能直接用其调用类中的方法的,如上例中不能用constructor.newInstance(outputStream,str).function();若要调用类中方法,可以用Class.getMethod或getMethods方法,其返回值类型为Method,也是java.lang.reflect中的类,再调用方法invoke即可,具体例子如下:
Class<?> c = Class.forName(className);
Constructor<?> constructor = c.getConstructor(String.class); //假设类有一构造器className(String name)
Object o = constructor.newInstance("zhengjunyan"); //相当于new className("zhengjunyan")
Method method = c.getMethod("test",String.class); //假设类中有一个方法test(String s)
method.invoke(o,"zheng"); //即调用已创建的实例的方法test("zheng")