【Java】反射 & 反射性能 & 反射操作泛型 & 反射操作注解

反射机制

  • 运行时加载,探知,使用编译期间完全未知的类。
  • 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用他的任意一个方法和属性。
  • jvm加载完类之后,在堆内存中,就产生了一个对应的Class类型的对象,这个对象就包含了完整的类的结构信息。Class(大写c)是一个类。
  • 一个类只有一个Class反射对象。

反射的使用

首先定义一个类User作为例子

​
package Reflection;

public class User {

    public int id;
    private int age;
    String name;

    public User(){

    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

有三种方式来获得某一个类的Class对象

/方式1
Class<?> demo1 = Class.forName(path);
//方式2
Class demo2 = Reflection.User.class;
//方式3
Class demo3 = path.getClass();

获取类的名字 

demo1.getName();//获得类名+包名
demo1.getSimpleName();//获得类名

获得属性信息 

Field[] fields1 = demo1.getFields();//只能获得public的属性
Field[] fields2 = demo1.getDeclaredFields();//获得所有属性
Field field3 = demo1.getDeclaredField("name");//获取指定属性

 获取方法信息同属性,把Field换为Method
如果方法有参数,必须传入参数类型对应的Class对象

Method method = demo1.getDeclaredMethod("setAge", int.class);

通过反射API调用构造方法,构造对象 

User u1 = (User)demo1.newInstance();//其实是调用了User的无参构造
Constructor constructor = demo1.getDeclaredConstructor(int.class,int.class,String.class);
User u2 = (User) constructor.newInstance(001,18,"yst");//利用有参构造,利用newInstance传参

通过反射API调用普通方法,好处是可以动态的调用方法,例如从其他地方传过来再放到参数中 

User u3 = (User)demo1.newInstance();
Method method2 = demo1.getDeclaredMethod("setName", String.class);
method2.invoke(u3,"yst222");

通过反射API操作属性
因为定义age属性为private,所以set不能访问,要用setAccessible取消安全检查 

User u4 = (User)demo1.newInstance();
Field f = demo1.getDeclaredField("age");
f.setAccessible(true);
f.set(u4,22);

反射性能

经过测试,使用反射调用方法所用时间远大于直接调用方法,所以当需要频繁调用反射的时候可以取消安全检查,这样使效率提高4倍。

Class.setAccessible(true); 这样就可以取消安全检查。

反射操作泛型

package Reflection;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class ReflectionGenerics {

    public void test1(Map<String,Reflection.User> map, List<Reflection.User> list){
        System.out.println("test1");
    }

    public Map<Integer,Reflection.User>test2(){
        System.out.println("test2");
        return null;
    }

    public static void main(String[] args) {
        try {
            //获得指定方法参数泛型信息
            Method m = ReflectionGenerics.class.getMethod("test1",Map.class,List.class);
            //获得泛型参数类型
            Type[] t = m.getGenericParameterTypes();
            for (Type x: t) {
                System.out.println("#"+x);
                //如果是一个参数类型
                if(x instanceof ParameterizedType){
                    //强制类型转换
                    Type[] genericTypes = ((ParameterizedType)x).getActualTypeArguments();
                    for(Type y : genericTypes){
                        System.out.println("泛型类型:"+y);
                    }
                }
            }

            //获得指定方法返回值泛型信息
            Method m2 = ReflectionGenerics.class.getMethod("test02", null);
            Type returnType = m2.getGenericReturnType();
            if(returnType instanceof ParameterizedType){
                Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments();

                for (Type genericType : genericTypes) {
                    System.out.println("返回值,泛型类型:"+genericType);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

反射操作注解

参考【Java】自定义注解 & 反射机制读取注解实现简单ORM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值