Java基础二十四

1 反射

1.1 反射概述

  • java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
  • 换句话说,反射就是通过Class对象,去操作对应字节码文件中的成员变量、构造方法和成员方法。
  • 要想剖析一个类,必须先要获取到该类的字节码文件对象。而剖析使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。

1.2 获取Class对象的三种方式

  • ①通过对象.getClass()方法获取Class对象。
package com.xuweiwei;

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

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

public class ClassDemo {
    public static void main(String[] args) {
        Person p = new Person();
        Class<? extends Person> c = p.getClass();

        System.out.println(c);

    }

}
  • ②通过类名.class获取对应的Class对象。
package com.xuweiwei;

public class ClassDemo {
    public static void main(String[] args) {
        Class<Person> c = Person.class;

        System.out.println(c);

    }

}
  • ③通过Class.forName("完整类名")获取Class对象。
package com.xuweiwei;

public class ClassDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> c = Class.forName("com.xuweiwei.Person");

        System.out.println(c);

    }

}

1.3 反射获取构造方法

  • 方法:获取指定参数的公共的构造方法(构造方法的修饰符是public)
public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
  • 方法:获取所有公共的构造方法
public Constructor<?>[] getConstructors() throws SecurityException
  • 方法:获取指定参数的构造方法(构造方法的修饰符可以是public也可以是private或其它)
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
  • 方法:获取所有的构造方法
public Constructor<?>[] getDeclaredConstructors()  throws SecurityException
  • 示例:通过反射获取无参构造方法并使用
package com.xuweiwei;

public class Person {

    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ClassDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> c = Class.forName("com.xuweiwei.Person");

        Constructor<?> constructor = c.getConstructor();

        System.out.println(constructor);//public com.xuweiwei.Person()

        Object o = constructor.newInstance();//创建对象

        System.out.println(o);

    }

}
  • 示例:通过反射获取有参构造方法并使用
package com.xuweiwei;

public class Person {

    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

import java.lang.reflect.Constructor;

public class ClassDemo2 {
    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("com.xuweiwei.Person");

        Constructor<?> constructor = c.getConstructor(String.class, Integer.class);

        Object o = constructor.newInstance("许威威", 20);

        System.out.println(o);//Person{name='许威威', age=20}

    }
}
  • 示例:反射获取私有构造方法并使用
package com.xuweiwei;

public class Person {

    private String name;
    private Integer age;

    private Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

import java.lang.reflect.Constructor;

public class ClassDemo3 {
    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("com.xuweiwei.Person");

        Constructor<?> constructor = c.getDeclaredConstructor();

        //需要
        constructor.setAccessible(true);

        Object o = constructor.newInstance();//Person{name='null', age=null}
        System.out.println(o);
    }
}

1.4 反射获取属性

  • 上面的概念并不准确,在java中属性的定义不是上述的,准备的讲,应该获取Filed。
  • 方法:获取指定名称的Filed对象
public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException
  • 方法:获取所有的Field对象数组
public Field[] getDeclaredFields() throws SecurityException
  • 方法:获取指定名称的公共的Field对象
public Field getField(String name) throws NoSuchFieldException,SecurityException
  • 方法:获取所有的公共的Field对象
public Field[] getFields()throws SecurityException
  • 示例:获取指定的私有属性,并赋值
package com.xuweiwei;

public class Person {

    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

import java.lang.reflect.Field;

public class ClassDemo4 {
    public static void main(String[] args) throws Exception{
        Class<?> c = Class.forName("com.xuweiwei.Person");

        Object o = c.newInstance();


        Field nameField = c.getDeclaredField("name");

        nameField.setAccessible(true);
        nameField.set(o,"许威威");

        System.out.println(o);



    }
}

1.5 反射获取方法

  • 方法:获取所有公共的方法
public Method[] getMethods() throws SecurityException
  • 方法:获取指定参数和名字的公共的方法
public Method getMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
  • 方法:获取所有的方法
public Method[] getDeclaredMethods()  throws SecurityException
  • 方法:获取指定参数和名字的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
  • 示例:反射获取有参无返回值的成员方法并调用
package com.xuweiwei;

public class Person {

    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.xuweiwei;

import java.lang.reflect.Method;

public class ClassDemo4 {
    public static void main(String[] args) throws Exception{
        Class<?> c = Class.forName("com.xuweiwei.Person");

        Object o = c.newInstance();

        Method setName = c.getDeclaredMethod("setName", String.class);
        setName.setAccessible(true);

        setName.invoke(o,"许威威");

        System.out.println(o);

    }
}

2 动态代理

3 枚举

4 注解

猜你喜欢

转载自www.cnblogs.com/xuweiweiwoaini/p/9434503.html