JAVA反射机制知多少

目录

目标

概述

实战

获取类

获取构造方法并用反射的方式创建对象

获取成员变量

获取成员方法并通过反射的方式调用

获取注解


目标

了解反射机制的概念,通过反射的方式动态地获取类的名称、成员变量、构造方法、成员变量,注解信息。


概述

什么是反射

java类编译完成以后变成class字节码文件,java项目启动时会将class文件加载到内存中。此时,在运行的java程序中:

  • 整个类会变成Class类的对象。
  • 构造方法会变成Construct类的对象。
  • 成员变量会变成Field类的对象。
  • 成员方法会变成Method类的对象。

将类的各个组成部分封装成对象,这个过程就是反射。


实战

获取类

package com.ctx.test;

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

    public String phone;
    public boolean sex;

    protected String address;
    String tel;

    public Student() {

    }

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

    public void fun() {

    }

    public String fun(String msg) {
        return null;
    }
}
    public static void main(String[] args) throws ClassNotFoundException {
        //方法一:通过Class.forName("全类名")获取。常用于加载配置文件,即把类名称放在配置文件中,然后读取配置文件加载类。
        Class<?> studentClass = Class.forName("com.ctx.test.Student");
        //方法二:通过类名.Class获取。常用于作为参数传递。
        Class<Student> studentClass2 = Student.class;
        //方法三:通过类的对象.getClass()获取。常用于对象获取字节码。
        Student student = new Student();
        Class<? extends Student> studentClass3 = student.getClass();

        //都输出true,证明同一个Class文件在一次程序运行中,只会被加载一次。
        System.out.println(studentClass==studentClass2);
        System.out.println(studentClass2==studentClass3);
    }

获取构造方法并用反射的方式创建对象

package com.ctx.test;

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

public class GetConstructor {
    String name;
    Boolean sex;
    Integer age;

    @Override
    public String toString() {
        return "GetConstructor{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }

    public GetConstructor() {

    }

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

    GetConstructor(Integer age) {
        this.age=age;
    }

    protected GetConstructor(Boolean sex) {
        this.sex=sex;
    }

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        new GetConstructor().createObject();
    }

    /**
     * 获取构造方法
     * @throws NoSuchMethodException
     */
    public void getConstructor() throws NoSuchMethodException {
        //获取所有的public的构造方法
        Constructor<?>[] constructors = GetConstructor.class.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("=================");
        //设置参数列表,获取指定的public构造方法。我这里参数列表没写,获取的就是无参数的public构造方法。
        Constructor<GetConstructor> constructor = GetConstructor.class.getConstructor();
        System.out.println(constructor);
        System.out.println("=================");
        //获取所有构造方法
        Constructor<?>[] declaredConstructors = GetConstructor.class.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("=================");
        //获取指定的构造方法。我这里指定了参数列表为String,获取的就是一个String的构造方法。
        Constructor<GetConstructor> declaredConstructor = GetConstructor.class.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);
    }

    /**
     * 通过反射的方式获取对象。
     * @throws InvocationTargetException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public void createObject() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
        Constructor<GetConstructor> declaredConstructor = GetConstructor.class.getDeclaredConstructor(String.class);
        GetConstructor obj = declaredConstructor.newInstance("张三");
        System.out.println(obj);
    }
}

获取成员变量

package com.ctx.test;

import java.lang.reflect.Field;

/**
 * 获取成员变量
 */
public class GetMemberVar {
    public static void main(String[] args) {
        new GetMemberVar().setPrivateValue();

    }

    /**
     * 获取public访问修饰符描述的成员变量。
     */
    public void getPublicMemberVar(){
        //获取所有public访问修饰符描述的成员变量。
        Field[] fields = Student.class.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //获取指定的public类型的成员变量。
        try {
            Field sex = Student.class.getField("sex");
            System.out.println(sex);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取所有成员变量。
     */
    public void getDeclareMemberVar(){
        //获取所有成员变量。
        Field[] declaredFields = Student.class.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //获取指定的成员变量。
        try {
            Field name = Student.class.getDeclaredField("name");
            System.out.println(name);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 给非private成员变量设定值。
     */
    public void setValue(){
        Student student = new Student();
        try {
            Field address = Student.class.getDeclaredField("address");
            //给成员变量设值。
            address.set(student,"xxxx");
            //成员变量取值。
            Object o = address.get(student);
            System.out.println("address="+o);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 给private成员变量设定值。
     */
    public void setPrivateValue(){
        Student student = new Student();
        try {
            Field name = Student.class.getDeclaredField("name");
            //忽略访问修饰符的限制。
            name.setAccessible(true);
            //给成员变量设值。
            name.set(student,"张三");
            //成员变量取值。
            Object o = name.get(student);
            System.out.println("name="+o);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

}

获取成员方法并通过反射的方式调用

package com.ctx.test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class GetMethod {
    String name;

    @Override
    public String toString() {
        return "GetMethod{" +
                "name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        new GetMethod().getMethod();
    }

    /**
     * 获取成员方法并调用
     */
    public void getMethod() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Method[] methods = GetMethod.class.getMethods();
        //获取所有public成员方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("================");
        //获取指定的成员方法
        Method test = GetMethod.class.getMethod("test", String.class);
        System.out.println(test);
        System.out.println("================");
        //获取所有成员方法
        Method[] declaredMethods = GetMethod.class.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("================");
        Method test2 = GetMethod.class.getDeclaredMethod("test2",String.class);
        Object zhangsan = test2.invoke(GetMethod.class.newInstance(), "zhangsan");
        System.out.println(zhangsan);
    }

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

    private String test2(String name) {
        return "a";
    }

    protected void test3() {

    }

    void test4() {

    }
}

获取注解

package com.ctx.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String name() default "未知";
    boolean sex() ;
    int age();

}
package com.ctx.test;

import org.springframework.scheduling.annotation.Scheduled;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@MyAnnotation(name="李四",sex = true, age = 35)
public class GetAnnotation {
    public static void main(String[] args) throws NoSuchMethodException {
        new GetAnnotation().getAnnotation();
    }

    /**
     * 获取注解
     */
    public void getAnnotation() throws NoSuchMethodException {
        //判断方法上是否存在这个注解
        Method method = GetAnnotation.class.getMethod("fun2");
        boolean annotationPresent1 = method.isAnnotationPresent(Scheduled.class);
        if(annotationPresent1){
            Scheduled annotation = method.getAnnotation(Scheduled.class);
            System.out.println(annotation.cron());
        }
    }

    /**
     * 判断注解是否存在并获取
     */
    public void existAnnotation() throws NoSuchMethodException {
        //判断类上是否存在这个注解
        boolean annotationPresent = GetAnnotation.class.isAnnotationPresent(MyAnnotation.class);
        if(annotationPresent){
            MyAnnotation annotation = GetAnnotation.class.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.sex());
            System.out.println(annotation.age());
            System.out.println(annotation.name());
        }

        //判断方法上是否存在这个注解
        Method method = GetAnnotation.class.getMethod("fun");
        boolean annotationPresent1 = method.isAnnotationPresent(MyAnnotation.class);
        if(annotationPresent1){
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.sex());
            System.out.println(annotation.age());
            System.out.println(annotation.name());
        }
    }

    @MyAnnotation(name="张三",sex = false, age = 18)
    public void fun(){

    }

    @Scheduled(cron = "0 0/15 * * * ?")
    public void fun2(){

    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值