package summer.reflection;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;


/**
 * @ClassName: reflectdemo2
 * @Description: TODO
 * @Author: Samny
 * @Date: 2020/4/22 19:02
 * @Version: v1.0.0
 * @Description:    通过放射来执行命令
 **/
public class reflectdemo2 {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Method1!");
        Method1();
        // 暂停三秒钟 效果明显
        TimeUnit.SECONDS.sleep(3);
        System.out.println("Method2!");
        Method2();
    }
    /**
     * @Author:         samny
     * @CreateDate:     2020/4/23 13:36
     * @UpdateUser:     samny
     * @UpdateDate:     2020/4/23 13:36
     * @UpdateRemark:   修改内容
     * @Version:        v1.0.0
     * @Description:    第一种反射方法调用命令
     */
    public static void Method1(){
        try {
            //获取对象
            Class cls = Class.forName("java.lang.Runtime");
            //实例化对象
            Object ob = cls.getMethod("getRuntime",null).invoke(null,null);
            // 反射调用执行命令
            cls.getMethod("exec", String.class).invoke(ob,"calc");


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    /**
     * @Author:         samny
     * @CreateDate:     2020/4/23 13:50
     * @UpdateUser:     samny
     * @UpdateDate:     2020/4/23 13:50
     * @UpdateRemark:   修改内容
     * @Version:        v1.0.0
     * @Description:    Runtime中无参构造方法是private权限，但可以通过反射修改方法的访问权限
     */
    public static void Method2(){
        try {
            // 获取对象
            Class cls = Class.forName("java.lang.Runtime");
            // 获取构造方法
            Constructor constructor = cls.getDeclaredConstructor();
            // java.lang.Runtime类无参构造方法是private权限无法直接调用
            // setAccessible通过反射修改方法的访问权限，强制可以访问
            constructor.setAccessible(true);
            // 实例化对象
            Object ob = constructor.newInstance();
            Method mt = cls.getMethod("exec", String.class);

            mt.invoke(ob,"calc");


        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
