欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

javase review day35 reflection

最编程 2024-10-01 18:43:16
...

反射

获取class对象的方法 

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取反射的三种方式


        //第一种 Class.forName(全类名)
        //用法:最为常用
        Class<?> clazz1 = Class.forName("Reflection.Student");
//        System.out.println(clazz1);// class Reflection.Student
        //第二种
        //一般是当做 参数进行传递
        Class<Student> clazz2 = Student.class;
        System.out.println(clazz2==clazz1);//true

        //第三种
        //在有这个对象时使用
        Student s = new Student();
        Class<? extends Student> clazz3 = s.getClass();
        System.out.println(clazz3==clazz2);//true

    }
}

通过class获取构造方法,成员方法,成员变量

利用反射获取构造方法

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取class对象
        Class<?> clazz = Class.forName("Reflection.Demo2.Student");
        //通过class对象获取构造方法对象
        //获取非私用的构造方法集合
//        Constructor<?>[] cons1 = clazz.getConstructors();
//        /**
//         * public Reflection.Demo2.Student()
//         * public Reflection.Demo2.Student(java.lang.String)
//         */
//        for (Constructor<?> constructor : cons1) {
//            System.out.println(constructor);
//        }
        
        
        //获取全部构造方法集合(包括私有构造)
//        Constructor<?>[] cons2 = clazz.getDeclaredConstructors();
//        /**
//         * public Reflection.Demo2.Student()
//         * public Reflection.Demo2.Student(java.lang.String)
//         * protected Reflection.Demo2.Student(int)
//         * private Reflection.Demo2.Student(java.lang.String,int)
//         */
//        for (Constructor<?> constructor : cons2) {
//            System.out.println(constructor);
//        }
        
        
//        //获取单个非私有构造方法(通过形参确定哪个构造方法)
//        Constructor<?> con3 = clazz.getConstructor(String.class);
//        //public Reflection.Demo2.Student(java.lang.String)
//        System.out.println(con3);
        
        
//        //使用公开权限获取非公开会报错
//        Constructor<?> con4 = clazz.getConstructor(int.class);
//        /**
//         * Exception in thread "main" java.lang.NoSuchMethodException: Reflection.Demo2.Student.<init>(int)
//         * 	at java.base/java.lang.Class.getConstructor0(Class.java:3585)
//         * 	at java.base/java.lang.Class.getConstructor(Class.java:2271)
//         * 	at Reflection.Demo2.Demo.main(Demo.java:35)
//         */
//        System.out.println(con4);
        
        
//        Constructor<?> con5 = clazz.getDeclaredConstructor(int.class);
//        //protected Reflection.Demo2.Student(int)
//        System.out.println(con5);
        
        
        Constructor<?> con6 = clazz.getDeclaredConstructor(String.class,int.class);
        //private Reflection.Demo2.Student(java.lang.String,int)
//        System.out.println(con6);
        
        
//        //通过构造方法获取修饰符,修饰符使用Int类型的数据进行指代,私有使用2表述
//        int modifiers = con6.getModifiers();
//        System.out.println(modifiers);// 2
        
        
//        //通过构造方法获取形参
//        //获取这个构造方法所有的参数
//        Parameter[] parameters = con6.getParameters();
//        //java.lang.String arg0
//        //int arg1
//        for (Parameter parameter : parameters) {
//            System.out.println(parameter);
//        }
        
        
//        //获取这个构造方法所有参数的个数
//        System.out.println(con6.getParameterCount());//2
        
        
//        //获取这个构造方法所有参数的类型
//        Class<?>[] parameterTypes = con6.getParameterTypes();
//        /**
//         * class java.lang.String
//         * int
//         */
//        for (Class<?> parameterType : parameterTypes) {
//            System.out.println(parameterType);
//        }

//        //通过构造方法获取名字
//        System.out.println(con6.getName());//Reflection.Demo2.Student


        //通过构造方法获取对象
        //表述临时取消权限校验
        con6.setAccessible(true);
        //由于获取的构造方法为私有所以无法创建对象,但是使用上面的临时取消权限校验,可以使这个构造方法创建对象
        //这种方法叫暴力反射
        Student s = (Student) con6.newInstance("zhangsan", 18);
        System.out.println(s.toString());// Student{name = zhangsan, age = 18}

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

    public Student() {
    }

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

利用反射获取成员变量

public class Demo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //获取class对象
        Class<?> clazz = Class.forName("Reflection.Demo3.Student");

//        Field[] fields = clazz.getFields();
//        //由于不是获取全部只获取到了公开的
//        //public java.lang.String Reflection.Demo3.Student.gender
//        for (Field f : fields) {
//            System.out.println(f);
//        }

        //获取全部成员变量
//        Field[] fields2 = clazz.getDeclaredFields();
//        //private java.lang.String Reflection.Demo3.Student.name
//        //private int Reflection.Demo3.Student.age
//        //public java.lang.String Reflection.Demo3.Student.gender
//        for (Field f : fields2) {
//            System.out.println(f);
//        }、
        //获取单个成员变量
        //public java.lang.String Reflection.Demo3.Student.gender
        Field gender = clazz.getDeclaredField("gender");
        System.out.println(gender);

        //通过对象获取该成员方法的值
        Student s = new Student("lisi",18,"男");
        String gender1 = (String) gender.get(s);
        System.out.println(gender1);//男
        
        //修改改成员变量的值
        gender.set(s,"女");
        System.out.println(s);//Student{name = lisi, age = 18, gender = 女}


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

    private String aaa(String name) throws IOException,NullPointerException, EOFException {
        System.out.println("aaa"+name);
        return "请问请问";
    }
    public void bbb(String name,int age){
        System.out.println("bbb"+name+age);
    }

    public Student() {
    }

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

    /**
     * 获取
     * @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 + "}";
    }
}

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


    public Student() {
    }

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

    /**
     * 获取
     * @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;
    }

    /**
     * 获取
     * @return gender
     */
    public String getGender() {
        return gender;
    }

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

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

利用反射获取成员方法

public class Demo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取class对象
        Class<?> clazz = Class.forName("Reflection.Demo4.Student");

        //获取所有公共的方法(包括父类中的公共方法)
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }、

        //获取所有方法包括私有的方法(不包括父类中的方法
//        Method[] methods = clazz.getDeclaredMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }
        /**
         * public void Reflection.Demo4.Student.setAge(int)
         * public void Reflection.Demo4.Student.bbb(java.lang.String,int)
         * private void Reflection.Demo4.Student.aaa(java.lang.String)
         * public int Reflection.Demo4.Student.getAge()
         * public java.lang.String Reflection.Demo4.Student.getName()
         * public java.lang.String Reflection.Demo4.Student.toString()
         * public void Reflection.Demo4.Student.setName(java.lang.String)
         */

        //通过方法名和形参类型获取单个方法(有方法重载不能只靠方法名获取)
        Method m = clazz.getDeclaredMethod("aaa", String.class);
        //private void Reflection.Demo4.Student.aaa(java.lang.String)
        System.out.println(m);

        //获取各种数据
        //获取修饰符
        System.out.println(m.getModifiers());//2

        //获取方法的名字
        System.out.println(m.getName());//aaa

        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        //java.lang.String arg0
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //获取方法的异常
        /**
         * class java.io.IOException
         * class java.lang.NullPointerException
         * class java.io.EOFException
         */
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        /**
         * Method 类中用于创建对象的方法
         * Object invoke(Object obj,Object...args):运行方法
         * 参数一:用Obj对象调用该方法
         * 参数二:调用方法传递的参数(如果没有就不写)
         * 返回值:方法的返回值(如果没有就不写)
         */
        Student s = new Student();

        //暴露反射
        m.setAccessible(true);
        String str = (String) m.invoke(s, "汉堡包");//aaa汉堡包
        System.out.println(str);//请问请问

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

    private String aaa(String name) throws IOException,NullPointerException, EOFException {
        System.out.println("aaa"+name);
        return "请问请问";
    }
    public void bbb(String name,int age){
        System.out.println("bbb"+name+age);
    }

    public Student() {
    }

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

    /**
     * 获取
     * @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 + "}";
    }
}

练习

练习一

public class Test {
    public static void main(String[] args) throws IOException, IllegalAccessException {
        Student s = new Student("小A",23,'女',167.5,"睡觉");
        Teacher t = new Teacher("波妞",10000);
        setdata(s);
//        setdata(t);
    }
    public static void setdata(Object obj) throws IOException, IllegalAccessException {
        //获取输出流
        FileOutputStream fos = new FileOutputStream("javaseday35\\src\\main\\java\\Reflection\\Test\\Test1\\a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        BufferedWriter bw = new BufferedWriter(osw);
        //获取输入对象的类对象
        Class<?> clazz = obj.getClass();
        //获取成员对象
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
//            //处理成员对象,将成员对象转化为String类型
//            String string = field.toString();
//            //将对象的名字使用split方法进行切割,使用转义字符按照 . 进行切割
//            String[] split = string.split("\\.");
//            //将最后赋值给key
//            String key = split[split.length - 1];
            String key = field.getName();
//            System.out.println(string1);
            //处理每个成员对象
            //授权访问私有对象
            field.setAccessible(true);
            //获取到对用的值
            Object o = field.get(obj);
            String value = o.toString();
            //将key和value 存入文件
            bw.write(key+"="+value);
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }
}
public class Student {
    private String name;
    private int age;
    private char gender;
    private double height;
    private String hobby;
public class Teacher {
    private String name;
    private double salary;
name=波妞
salary=10000.0l

练习二

public class Test {
    public static void main(String[] args) throws IOException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        //获取配置文件的信息
        Properties pro = new Properties();
        FileInputStream fis = new FileInputStream("javaseday35\\src\\main\\java\\Reflection\\Test\\Test2\\pro.properties");
        //读取配置文件的信息
        pro.load(fis);
        fis.close();

        System.out.println(pro);
        //获取全类名和方法名
        String classmane = (String) pro.get("classmane");

        String mothed = (String) pro.get("mothed");

        System.out.println(classmane);
        System.out.println(mothed);

        //通过反射获取信息
        Class<?> clazz = Class.forName(classmane);
        //获取空参构造
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        //通过空参构造获取空参对象
        Object o = constructor.newInstance();

        //通过方法名获取方法
        Method method = clazz.getDeclaredMethod(mothed);
        //调用方法
        method.invoke(o);
        
    }

}
pro.properties

classmane=Reflection.Test.Test2.Student
mothed=eat
public class Student {
    private String name;
    private int age;
    private char gender;
    private double height;
    private String hobby;

    public void eat(){
        System.out.println("正在吃饭");
    }
public class Teacher {
    private String name;
    private double salary;

    public void eat(){
        System.out.println("正在吃饭");
    }

总结

动态代理

public class BigStar implements Star{
    private String name;

    public String sing(String name){
        System.out.println(this.name+"正在唱"+name);
        return "谢谢";
    }

    public void drice(){
        System.out.println(name+"正在跳舞");
    }
    public BigStar() {
    }

    public BigStar(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

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

    public String toString() {
        return "BigStar{name = " + name + "}";
    }
}
public interface Star {
    public abstract String sing(String name);

    public abstract void drice();
}

小结

创建代理

/*
*
* 类的作用:
*       创建一个代理
*
* */
public class ProxyUtil {


    /*
    *
    * 方法的作用:
    *       给一个明星的对象,创建一个代理
    *
    *  形参:
    *       被代理的明星对象
    *
    *  返回值:
    *       给明星创建的代理
    *
    *
    *
    * 需求:
    *   外面的人想要大明星唱一首歌
    *   1. 获取代理的对象
    *      代理对象 = ProxyUtil.createProxy(大明星的对象);
    *   2. 再调用代理的唱歌方法
    *      代理对象.唱歌的方法("只因你太美");
    * */
    public static Star createProxy(BigStar bigStar){
       /* java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:

        public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
        参数一:用于指定用哪个类加载器,去加载生成的代理类
        参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
        参数三:用来指定生成的代理对象要干什么事情*/
        Star star = (Star) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类
                new Class[]{Star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
                //参数三:用来指定生成的代理对象要干什么事情
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /*
                        * 参数一:代理的对象
                        * 参数二:要运行的方法 sing
                        * 参数三:调用sing方法时,传递的实参
                        * */
                        if("sing".equals(method.getName())){
                            System.out.println("准备话筒,收钱");
                        }else if("dance".equals(method.getName())){
                            System.out.println("准备场地,收钱");
                        }
                        //去找大明星开始唱歌或者跳舞
                        //代码的表现形式:调用大明星里面唱歌或者跳舞的方法
                        return method.invoke(bigStar,args);
                    }
                }
        );
        return star;

    }
}
public class Test {
    public static void main(String[] args) {



    /*
        需求:
            外面的人想要大明星唱一首歌
             1. 获取代理的对象
                代理对象 = ProxyUtil.createProxy(大明星的对象);
             2. 再调用代理的唱歌方法
                代理对象.唱歌的方法("只因你太美");
     */


        //1. 获取代理的对象
        BigStar bigStar = new BigStar("鸡哥");
        Star proxy = ProxyUtil.createProxy(bigStar);

        //2. 调用唱歌的方法
        String result = proxy.sing("只因你太美");
        System.out.println(result);




    }
}
public class BigStar implements Star {
    private String name;


    public BigStar() {
    }

    public BigStar(String name) {
        this.name = name;
    }

    //唱歌
    @Override
    public String sing(String name){
        System.out.println(this.name + "正在唱" + name);
        return "谢谢";
    }

    //跳舞
    @Override
    public void dance(){
        System.out.println(this.name + "正在跳舞");
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

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

    public String toString() {
        return "BigStar{name = " + name + "}";
    }
}
public interface Star {

    //我们可以把所有想要被代理的方法定义在接口当中

    //唱歌
    public abstract String sing(String name);

    //跳舞
    public abstract void dance();


}