Java中的反射

Java 大约 6106 字

作用

  • 判断任意一个对象所属的类
  • 构造任意一个类的对象
  • 判断任意一个类所具有的成员变量和方法
  • 获取泛型信息
  • 调用任意一个对象的成员变量和方法
  • 处理注解
  • 动态代理

类含义

  • java.lang.Class: 代表一个类
  • java.lang.reflect.Method: 代表类的方法
  • java.lang.reflect.Field: 代表类的成员方法
  • java.lang.reflect.Constructor: 代表类的构造方法

哪些类型可以有 Class 对象

  1. class:外部类,成员类,局部内部类,匿名内部类
  2. interface:接口
  3. []:数组
  4. enum:枚举
  5. annotation:注解@interface
  6. primitive type:基本数据类型
  7. void

获取 Class 实例

方式一

Class<Person> personClass = Person.class;

方式二

Person person = new Person();
Class<? extends Person> personClass2 = person.getClass();

方式三

用的最多的方式。

Class<?> personClass3 = Class.forName("com.example.entity.Person");

方式四

ClassLoader classLoader = Person.class.getClassLoader();
Class<?> personClass4 = classLoader.loadClass("com.example.entity.Person");

获取 Field 相关属性

获取当前运行时类及其父类中的方法声明为public的字段。

Class<Person> personClass = Person.class;

Field[] fields = personClass.getFields();
for (Field field : fields) {
    System.out.println(field);
}

获取当前运行时类中声明的所有属性,不包含父类中声明的属性。

Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
    System.out.println(declaredField);
    // 获取权限修饰符,java.lang.reflect.Modifier
    int modifiers = declaredField.getModifiers();
//    System.out.println(Modifier.toString(modifiers));

    // 获取数据类型
    Class<?> type = declaredField.getType();
//    System.out.println(type.getName());

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

    // 获取注解
    Annotation[] annotations = declaredField.getAnnotations();

    System.out.println("变量修饰符#" + Modifier.toString(modifiers) + ", 类型#" + type.getName() + ", 变量名#" + name+", 字段注解#" + Arrays.toString(annotations));
}

获取 Method 相关属性

获取当前运行时类及其父类中的方法声明为public的方法。

Method[] methods = personClass.getMethods();
for (Method method : methods) {
    System.out.println(method);
}

获取当前运行时类中声明的所有方法,不包含父类中声明的方法。

Method[] declaredMethods = personClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
//    System.out.println(declaredMethod);
    // 1. 获取方法的注解
    Annotation[] annotations = declaredMethod.getAnnotations();
    System.out.print(Arrays.toString(annotations) + "\t");

    // 2. 获取权限修饰符
    System.out.print(Modifier.toString(declaredMethod.getModifiers()) + "\t");

    // 3. 获取返回值类型
    System.out.print(declaredMethod.getReturnType().getName() + "\t");

    // 4. 获取方法名
    System.out.print(declaredMethod.getName() + "\t");

    // 5. 获取参数类型
    System.out.print(Arrays.toString(declaredMethod.getParameters()) + "\t");

    // 6. 获取异常类型
    System.out.print(Arrays.toString(declaredMethod.getExceptionTypes())+"\t");

    System.out.println();
}

其他属性

获取当前运行时类中声明为public的构造方法。

Class<Person> personClass = Person.class;

Constructor<?>[] constructors = personClass.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
}

获取当前运行时类中声明的所有构造方法。

Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);
}

获取父类。

Class<? super Person> superclass = personClass.getSuperclass();
System.out.println(superclass);

获取带泛型的父类。

Type genericSuperclass = personClass.getGenericSuperclass();
System.out.println(genericSuperclass);

获取带泛型的父类的泛型。

ParameterizedType pt = (ParameterizedType) genericSuperclass;
System.out.println(Arrays.toString(pt.getActualTypeArguments()));

获取包名。

Package aPackage = personClass.getPackage();
System.out.println(aPackage);

获取实现的接口。

Class<?>[] interfaces = personClass.getInterfaces();
System.out.println(Arrays.toString(interfaces));

获取注解。

Annotation[] annotations = personClass.getAnnotations();

Override annotation1 = personClass.getAnnotation(Override.class);
System.out.println(annotation1);// null

for (Annotation annotation : annotations) {
    if (annotation instanceof MyAnnotation) {
        MyAnnotation ma = (MyAnnotation) annotation;
        System.out.println(ma.value());
    }
}

示例实体类

Creator

public class Creator<T> implements Serializable {
    private char gender;
    public double weight;

    private void breath() {
        System.out.println("生物呼吸");
    }

    public void eat() {
        System.out.println("生物吃东西");
    }
}

MyAnnotation

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello my annotation";
}

MyInterface

public interface MyInterface {

    String saySomething();

}

Person

@MyAnnotation("Hello This is Class")
public class Person extends Creator<Person> implements MyInterface, Comparable<Integer> {

    @MyAnnotation("Hello This is Private Field")
    private String name;

    @MyAnnotation("Hello This is Public Field")
    public int age;

    String nickname;

    static String ID = "0001";
    final String ID2 = "0001";

    @MyAnnotation("Hello This is Non Param Constructor")
    public Person() {
    }

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

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

    @MyAnnotation("Hello This is sayHello Method")
    public void sayHello() throws Exception {
        System.out.println("你好");
    }

    private String say(@MyAnnotation("Hello This is Param") String content) {
        System.out.println("要说的内容是#" + content);
        return content;
    }

    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 +
                '}';
    }

    @Override
    public String saySomething() {
        return "say from person#" + name + ", age#" + age;
    }

    @Override
    public int compareTo(Integer o) {
        return age;
    }
}
阅读 36 · 发布于 2021-03-31

————        END        ————

扫描下方二维码关注公众号和小程序↓↓↓

扫描二维码关注我
昵称:
随便看看 换一批