Java SE之反射回顾

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Kevin 2018-2-8
 * 
 * 
 * 
 * 看 tomcat源码发现,很多地方用到了反射,回顾一下Method的用法,及其参数的意义。
 * 
 * 反射的基本操作流程是:
 * 1.获取一个类加载器ClassLoader;
 * 2.获取Class的类信息,调用类加载器的loadClass方法,参数为String类型(全限定名);
 * 3.获取类实例;
 * 4.进行相关属性或者方法的操作。
 * 
 * Method对象,是对类方法的封装,调用用invoke方法
 *
 * Class.getMethod(String name, Class<?>... parameterTypes)
 *      --name:方法名称
 *      --参数列表,参数类型的class,如果没有参数的话就传null
 * 
 * Method.invoke(Object obj, Object... args) 
 *      --obj:调用方法的类的实例对象
 *      --args:n个参数,对应方法,如果没有参数传null
 */
public class MethodDemo {

    public static void main(String[] args)  {

        try {
            ClassLoader cl = new MethodDemo().getClass().getClassLoader();
            Class<?> carclass = cl.loadClass("com.reflect.demo.Car");

            Object o = carclass.getConstructor().newInstance();
            Class<?>[] p = new Class<?>[1];
            p[0] = String.class;
            Method m = o.getClass().getMethod("setColor",p);
            m.invoke(o, "红色");


            Method m2 = o.getClass().getMethod("driver",null);
            m2.invoke(o, null);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }

}
public class Car {

    private String color;


    public String getColor() {
        return color;
    }


    public void setColor(String color) {
        this.color = color;
        System.out.println(color);
    }


    public void driver() {
        System.out.println("直行中......");
    }
}

下面来看一个Tomcat中随处可见的反射使用,如Bootstrap启动类的init方法中就反射生成了
Catalina类,调用它的setParentClassLoader方法设置父类加载器:

public void init() throws Exception {

        initClassLoaders();

        Thread.currentThread().setContextClassLoader(catalinaLoader);

        SecurityClassLoad.securityClassLoad(catalinaLoader);

        // Load our startup class and call its process() method
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
        Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.getConstructor().newInstance();

        // Set the shared extensions class loader
        if (log.isDebugEnabled())
            log.debug("Setting startup class properties");
        String methodName = "setParentClassLoader";
        Class<?> paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);

        catalinaDaemon = startupInstance;

    }
原文地址:https://www.cnblogs.com/Kevin-1992/p/12608385.html