反射

反射

1、反射的定义

什么是反射?
反射允许对成员变量,成员方法和构造方法的信息进行编程访问

2、反射的操作

2.1 获取class对象

获取class对象的三种方式
1、Class.forName("全类名");
2、类名.class
3、对象.getClass();
public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Demo02_1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1、Class.forName("全类名")
        //单独的T 代表一个类型 ,而 Class<T>代表这个类型所对应的类, Class<?>表示类型不确定的类
        Class<?> clazz = Class.forName("com.hu.demo02.Person");
        System.out.println(clazz);

        //2、类名.class
        Class<Person> classTwo = Person.class;
        System.out.println(classTwo);

        //3、对象.getClass();
        Class<? extends Person> classThree = new Person().getClass();
        System.out.println(classThree);

    }
}

2.2 获取类的构造方法

public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

    protected Person(int age) {
        this.age = age;
    }

    private Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Demo02_1 {
    public static void main(String[] args) throws ClassNotFoundException, 
            NoSuchMethodException, InvocationTargetException, 
            InstantiationException, IllegalAccessException {
        //1、获取class字节码文件对象
        Class<?> clazz = Class.forName("com.hu.demo02.Person");

        //2、获取public修饰的构造方法
        Constructor<?>[] cons1 = clazz.getConstructors();
       /* for (Constructor con : cons1) {
            System.out.println(con);
        }*/

        //3、获取所有的构造方法
        Constructor<?>[] cons2 = clazz.getDeclaredConstructors();
        /*for (Constructor con : cons2) {
            System.out.println(con);
        }*/

        //获取单个构造方法
        Constructor<?> con3 = clazz.getDeclaredConstructor(String.class,int.class);
        System.out.println(con3);
        con3.setAccessible(true);
        //利用有参构造生成对象
        Person person = (Person) con3.newInstance("小明", 12);
        System.out.println(person);
    }
}

2.3 获取类的成员变量

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

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
public class Demo02_1 {
    public static void main(String[] args) throws ClassNotFoundException, 
            NoSuchFieldException, IllegalAccessException {
        //1、获取class字节码文件对象
        Class<?> clazz = Class.forName("com.hu.demo02.Person");
        //2、获取成员变量
        /**
         * getFields 只能获取public修饰的
         * getDeclaredFields 获取所有的
         */
        Field[] fields = clazz.getDeclaredFields();
        /*for (Field field : fields) {
            System.out.println(field);
        }*/
        //3、获取单个成员变量
        /**
         * getField 只能获取public修饰的
         * getDeclaredField 都能获取
         */
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
        //4、获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //5、获取成员变量的值
        Person person = new Person("小白", 20, "男");
        name.setAccessible(true);
        String name1 = (String) name.get(person);
        System.out.println(name1);

        //6、修改成员变量的值
        name.set(person,"大白");
        System.out.println(person);
    }
}

2.4 获取类的成员方法

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

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void sleep() {
        System.out.println("在睡觉");
    }

    private void eat(String something) {
        System.out.println("在吃什么" + something);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
public class Demo02_1 {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchMethodException, InvocationTargetException,
            IllegalAccessException {
        //1、获取class字节码文件对象
        Class<?> clazz = Class.forName("com.hu.demo02.Person");
        //2、获取所有的方法对象,包括父类中所有的公共方法
        Method[] methods = clazz.getMethods();
        /*for (Method method : methods) {
            System.out.println(method);
        }*/

        //3、获取所有的方法对象,不包括父类中的方法。
        Method[] declaredMethods = clazz.getDeclaredMethods();
      /*  for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }*/

        //4、获取单个方法
        Method eat = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(eat);
        Person person = new Person();
        eat.setAccessible(true);
        eat.invoke(person,"馒头");
    }
}

3、动态代理

特点:无侵入式的给代码增加额外的功能

1.为什么需要代理?
代理可以无侵入式的给对象增强其他的功能

调用者-->代理-->对象
2.代理长什么样?
代理里面就是对象要被代理的方法
3、Java通过什么来保证代理的样子?
通过接口保证,后面的对象和代理需要实现同一个接口
接口中就是被代理的所有方法

3.1 如何为Java对象创建一个代理对象

java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法

newProxyInstance方法
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要干什么事情
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 + "正在跳舞");
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "BigStar{" +
                "name='" + name + '\'' +
                '}';
    }
}
/**
 * 想要被代理的方法写在接口里
 */
public interface Star {
    //唱歌
    public abstract String sing(String name);

    //跳舞
    public abstract void dance();
}
/**
 * 创建一个代理
 */
public class ProxyUtil {
    /**
     * @param bigStar 被代理的对象
     * @return 给明星创建的代理
     */
    public static Star createProxy(BigStar bigStar) {
        /**
         * 参数一:用于指定用哪个类加载器,去加载生成的代理类
         * 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
         * 参数三:用来指定生成的代理对象要干什么事情
         */
        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 {
                        /**
                         * 参数一: 代理对象
                         * 参数二: 要运行的方法
                         * 参数三: 调用方法是,传递的实参
                         */
                        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) {
        //获取代理对象
        BigStar bigStar = new BigStar("鸡哥");
        Star proxy = ProxyUtil.createProxy(bigStar);
        //调用代理方法
        String result = proxy.sing("鸡你太美");
        System.out.println(result);

        proxy.dance();
    }
}

时间:2023-06-26 下午

posted @ 2023-06-26 17:18  有何和不可  阅读(41)  评论(0)    收藏  举报