package A05;

public class Student {
    public String name;
    public int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Student(String name) {
        this.name = name;
    }
    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
-------------
package A05;

public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
        获取class文件的三种方式
        1.Class.forName("全类名")
        2.类名.class
        3.对象.getClass();
         */
        //1.第一种方式
        //全类名:包名+类名
        Class clazz1 = Class.forName("A05.Student");
        System.out.println(clazz1);

        //2.第二种方式
        Class clazz2 = Student.class;
        System.out.println(clazz2);

        //3.第三种方式
        Student s=new Student();
        Class clazz3 = s.getClass();
        System.out.println(clazz3);
    }
}
------------------------------------
package A05;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
import java.util.zip.ZipEntry;

public class MyReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        /*
        class类中获取构造方法的方法
        Constructor<>[]getConstructors()//获取所有的公共的构造方法
        Constructor<>[]getDeclaredConstructors()//获取所有的构造方法(包括私有的)
        Constructor<>getConstructor(Class<?>...parameterTypes)//获取单个的公共的构造方法
        Constructor<>getDeclaredConstructor(Class<?>...parameterTypes)//获取单个的构造方法(包括私有的)

        Constructor类中用于创建对象的方法
        T newInstance(Object...initargs)
        setAccessible(bool flag)
         */
        //1.获取class字节码文件
        Class clazz = Class.forName("A05.Student");

        //2.获取构造方法
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("------------------");
        Constructor[] dcons = clazz.getDeclaredConstructors();
        for (Constructor dcon : dcons) {
            System.out.println(dcon);
        }
        System.out.println("------------------");
        Constructor con1 = clazz.getDeclaredConstructor();
        System.out.println(con1);
        System.out.println("------------------");
        Constructor con2 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con2);
        System.out.println("------------------");
        Constructor con3 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(con3);


        //获取权限修饰符
        int mod1 = con1.getModifiers();
        System.out.println(mod1);//1表示public
        int mod2 = con2.getModifiers();
        System.out.println(mod2);//2表示private

        //获取参数
        Parameter[] pats = con3.getParameters();
        for (Parameter pat : pats) {
            System.out.println(pat);
        }
        System.out.println("------------------");
        //根据构造方法创建对象(如果是私有的构造方法需要用con.setAccessible(true)取消权限检查)

        //con3.setAccessible(true);
        Student s1 = (Student) con3.newInstance("haha", 18);
        System.out.println(s1);
    }
}
-----------------------------------------------------
package a06;

import A05.Student;

import java.lang.reflect.Field;
import java.util.zip.CheckedOutputStream;

public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        /*
        getfields()获取所有的成员变量
        getDeclaredFields()获取所有的成员变量,包括私有的
        getField()获取指定的成员变量
        getDeclaredField()获取指定的成员变量,包括私有的

        用于创建对象的方法:
        void set(Object obj,Object value) 给obj对象的成员变量赋值为value
        object get(Object obj) 获取obj对象的成员变量的值
         */

        //1.获取class文件对象
        Class clazz = Class.forName("A05.Student");
        //2.获取所有的成员变量
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-------------------");
        Field[] dFields = clazz.getDeclaredFields();
        for (Field dField : dFields) {
            System.out.println(dField);
        }
        System.out.println("-------------------");
        //3.获取指定的成员变量
        Field f1 = clazz.getField("name");
        System.out.println(f1);
        Field f2 = clazz.getDeclaredField("age");
        System.out.println(f2);

        //获取权限修饰符
        int m1 = f1.getModifiers();
        System.out.println(m1);

        //获取变量名字
        String name = f1.getName();
        System.out.println(name);

        //获取变量类型
        Class<?> type = f1.getType();
        System.out.println(type);

        //获取成员变量记录的值,如果是私有的变量需要用f1.setAccessible(true)取消权限检查
        Student s=new Student("haha",18);
        Object value = f1.get(s);
        System.out.println(value);

        //修改对象记录的值
        f1.set(s,"xixi");
        System.out.println(s);
    }
}
------------------------------------------------------
package a06;

import A05.Student;

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

public class MyReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /*
        getMethods() 获取本类及其父类的所有public修饰的方法
        getDeclaredMethods() 获取本类的所有方法
        getMethod(String name,Class...<?> parameterTypes) 获取本类及其父类的指定的public修饰的方法
        getDeclaredMethod(String name,Class...<?> parameterTypes) 获取本类的指定的方法


        创建对象的方法:
        invoke(Object obj,Object... args) 调用本类及其父类的指定的方法
        参数一:用obj对象调用方法
        参数二:调用方式时所传递的实参
        返回值:方法的返回值
         */
        //1.获取class文件对象
        Class clazz = Class.forName("A05.Student");

        //2.获取所有public修饰的方法(包括父类的所有方法)
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-----------------");
        //3.获取本类的所有方法(不能获取父类的方法,只能获取本类的方法)
        Method[] dMethods = clazz.getDeclaredMethods();
        for (Method dMethod : dMethods) {
            System.out.println(dMethod);
        }
        System.out.println("-----------------");

        //4.获取指定的public修饰的方法
        Method m1 = clazz.getMethod("drink");
        System.out.println(m1);
        Method m2 = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(m2);

        //获取方法修饰符
        int mo1 = m1.getModifiers();
        System.out.println(mo1);

        //获取方法的名字
        String name1 = m1.getName();
        System.out.println(name1);

        //获取方法形参
        Parameter[] parameters = m2.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        //获取抛出的异常
        Class<?>[] exceptionTypes = m1.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //获取返回值类型
        Student s=new Student();
        m2.setAccessible(true);
        m2.invoke(s, "xiangxiang");
    }
}