Java反射(一)

简介

Java反射是指在应用程序运行的时候动态的构造任意类的对象,可以了解任意一个类对象所属的类,可以了解任意一个类的

成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为java反射机制。

主要牵涉到的一个类叫Class类,该类代表普通类被加载到JVM中的字节码文件(.class)。

类加载器

类加载器ClassLoader,是将字节码文件加载到JVM中的一个东西。

例:Student类 ----javac编译—> Student.class ------ClassLoader------> JVM(OS)

类加载器的分类:

  • BootStrapClassLoader 用于加载java的核心类库,如java.lang包下的String
  • ExtensionClassLoader 用于加载java的拓展类库,如jre/lib/ext下的JAR文件,包括JDBC驱动程序,用于音频/图像处理的API等
  • ApplicationClassLoader classpath下的类,即用户自定义的类

类加载器的双亲委派机制:

  • 委托机制:
  • 将加载一个类的请求交给父类加载器,如果这个父类加载器找不到要加载的类,那么子类再加载它
  • 可见性机制:
  • 子类的加载器可以看见所有的父类加载器加载的类,但是父类加载器看不到子类加载器加载的类
  • 单一性机制:
  • 加载一个类,仅加载一次,可以确保在委托机制中,如果父类加载器已经加载过这个类了,子类加载器不会再次加载

demo:Class类

只举例构造器,方法,字段(注意,不带declared的都包括父类中的成员(private类型的拿不到),带declared的是指声明在本类中的成员,private类型的都能拿到,静态/非静态的都是一起得到的)和泛型。

Teacher和Student类

@Data
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
    public String name;

    private Integer age;

    private String gender;

    private List<Student> students;

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

    public void addAge(){
        this.age++;
    }

    public static void teach(){
        System.out.println("上课,同学们");
    }
}


@Data
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private Integer age;
    private String gender;
}
public class ReflectTest {
    public static void main(String[] args) {
        Class<Teacher> teacherClass = Teacher.class;
        /**
         * 构造器
         */
        System.out.println("------------------------构造器信息-----------------------------");
        Constructor<?>[] declaredConstructors = teacherClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            //1.打印构造器信息,包括构造器和其参数
            System.out.println(declaredConstructor.toString());
            System.out.println();

            //2.打印构造器的参数信息
            Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println(parameterType);
            }
            System.out.println();

        }

        /**
         * 成员方法/成员方法
         */
        System.out.println("---------------------方法信息---------------------------------");
        Method[] methods = teacherClass.getDeclaredMethods();
        for (Method method : methods) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            System.out.print(method.getName()+" : ");
            for (Class<?> parameterType : parameterTypes) {
                System.out.print(parameterType+",");
            }
            System.out.print("返回类型: "+method.getReturnType());
            System.out.println();
        }

        /**
         * 实例变量/静态变量
         */
        System.out.println("-----------------------实例变量信息--------------------------------");
        Field[] fields = teacherClass.getDeclaredFields();
        for (Field field : fields) {
            System.out.print(field.getType() + ": " + field.getName());
            System.out.println();
        }
        System.out.println();

        /**
         * 泛型
         */
        System.out.println("-----------------泛型----------------------------------");
        try {
            Field field = teacherClass.getDeclaredField("students");
            System.out.println("得到students字段类型:"+field.getType());
            Type genericType = field.getGenericType();
            System.out.println("得到students字段带泛型的类型:"+genericType.getTypeName());

            //判断这个类型是否是泛型
            if (genericType instanceof ParameterizedType){
                ParameterizedType parameterizedType = (ParameterizedType) genericType;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                System.out.print("students字段真实类型:");
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Munich*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值