反射机制(Reflection)

本文详细介绍Java反射机制的应用,包括如何获得Class对象、获取类的完整结构、动态创建对象及操作等。同时,还介绍了如何获取泛型信息和注解信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        java有一定动态性,使用反射可以在程序运行时借助Reflection API获得任何类的信息,并直接改变其中的属性和方法。步骤如下:

一、获得反射对象的Class对象

        加载完类之后,在方法区就会生成一个class对象,这个对象包含了类的完整信息。

    Class c=Class.forName("com.fan.Person");
    Class c1=(new Person(1,"ming")).getClass();
    Class c2=Person.class;
    System.out.println(c.equals(c1));

Notations:一个类有唯一的Class对象,类的整个结构被封装在这个对象中。一个Class对象对应一个加载到JVM的.class文件。

        除了上面获得Class对象的三种方法,每种内置包装类型都有Type属性。

                Class c3=Integer.TYPE;

        或获得父类类型:

                Class c4=c3.getSuperClass();

二,获取类的完整结构

        类的完整结构包括:Field,Method,Constructor,SuperClass,Interface,Annotation

        Class c=Class.forName("com.fan.Person");
//        获得类的名字
        System.out.println(c.getName());
        System.out.println(c.getSimpleName());
//        获得类的属性(使用getFields的话只能访问public的属性)
        Field[] F=c.getDeclaredFields();
        for (Field f:F){
            System.out.println(f);
        }
//        获取类的方法
        Method[] M=c.getDeclaredMethods();
        for(Method m:M){
            System.out.println(m);
        }
//        获得指定方法,加上传参的class,因为有方法重载
        Method m=c.getDeclaredMethod("setName", String.class);
//        获得指定的构造器
        Constructor[] c1=c.getConstructors();

三,动态创建对象并操作

        Class c=Class.forName("com.fan.Person");
//        调用类的无参构造器构造类,类里没有无参构造器就要报错
        Person P=(Person)c.newInstance();
//        通过有参数的构造器构造对象
        Constructor C=c.getDeclaredConstructor(int.class,String.class);
        Person P1=(Person)C.newInstance(5,"clearlove");
//        获取函数并调用
        Method setName=c.getDeclaredMethod("setName", String.class);
        setName.invoke(P,"shy");
        System.out.println(P.getName());
//        操作属性,通过setAccessible取消java访问权限检查
        Field name=c.getDeclaredField("name");
        name.setAccessible(true);
        name.set(P1,"the sky");

Notations:使用反射调用方法比普通方式慢很多,在反射调用前用setAccessible关闭权限会快一些。

四、获取泛型信息和注解信息

(1)获得泛型信息

        Method m=Person.class.getDeclaredMethod("test",Map.class);
//       注意这里有很多getTypes方法,要看泛型用在了哪里就调用哪个
        Type[] generiticParameters=m.getParameterTypes();
        for (Type t:generiticParameters){
            System.out.println(t);
            //      参数是Map<String,Integer>,只获得了Map,需要获得真的泛型参数
            //t是一个参数化的类型,强转它获得真实的参数信息
            if(t instanceof ParameterizedType){
                Type[] actualParameterType=((ParameterizedType) t).getActualTypeArguments();
                for (Type a:actualParameterType){
                    System.out.println(a);
                }
            }

(2)获取注解信息

注解定义和位置如下:

@title("Person")
public class Person {
    private int age;
    private String name;

    public Person(){
        this.age=0;
        this.name=null;
    }

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

    @title("test")
    public void test(Map<String,Integer> map){

    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface title{
    String value();
}

主程序中获取注解:

//反射获得注解,这种只得到类上面的注解
        Class c=Person.class;
        Annotation[] annotations=c.getAnnotations();
        for (Annotation a:annotations){
            System.out.println(a);
        }
//        获得注解中的值,传入注解.class可以获得注解的字节码文件
        title t;
        t = (title) c.getAnnotation(title.class);
        System.out.println(t.value());
//        获得其他位置的注解,方法上的为例
        Method m=c.getDeclaredMethod("test",Map.class);
        System.out.println(m.getAnnotation(title.class).value());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值