反射到底有什么作用,能帮我们干些什么呢?

简介: 反射到底有什么作用,能帮我们干些什么呢?

反射能做什么

  • 对于任意一个类,都能知道这个类的所有属性和方法;
  • 对于任意一个对象,都能调用它的任意一个方法和属性。

反射常用的类

Constructor类: 提供类的构造方法的信息及对它的访问权限。
Field类: 提供类或接口上的字段的信息,及对它的动态访问权限。
Method类: 提供类或接口上某个方法的信息。

Class类

面向对象的世界里,万事万物都是对象。类也是对象,它是java.lang.Class类的示例对象。
Class类没有公共构造方法,那怎么创建Class类的对象?

创建Class类对象的三种方法

  • 使用类的`class`属性
Class c = Demo.class
  • 使用`Class`类的`forName`方法
try {
    Class c = Class.forName("xin.zhuyao.gzh.test20200722.Demo");
    //使用Class类的forName方法创建Class对象时,需要捕获ClassNotFoundException
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
  • 使用`Object`对象的`getClass`方法
Demo demo = new Demo();
Class c = demo.getClass();

虽然有3种方法但是它们创建的反射对象是完全相同的,也就是说:一个类只能有一个反射对象,有兴趣的小伙伴可以测试下。

Class类的主要方法

构造方法

//获得所有权限为public的构造方法
Constructor<?>[] getConstructors();

//获得权限为public的指定构造方法
Constructor<T> getConstructor(Class<?>... parameterTypes);

//获得所有构造方法,按声明顺序返回
Constructor<?>[] getDeclaredConstructors();

//获得指定构造方法
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);

方法

//获得所有权限为public的方法
Method[] getMethods();

//获得权限为public的指定方法
Method getMethod(String name, Class<?>... parameterTypes);

//获得所有方法,按声明顺序返回
Method[] getDeclaredMethods();

//获得指定方法
Method getDeclaredMethod(String name, Class<?>... parameterTypes);

成员变量

//获得权限为public的成员变量
Field[] getFields();

//获得权限为public的指定成员
Field getField(String name);

//获得所有成员变量,按声明顺序返回
Field[] getDeclaredFields();

//获得指定成员变量
Field getDeclaredField(String name);
说明:通过 getFields()getMethods()获得权限为 public的成员变量和方法时,将包含从超类中继承到的成员变量和方法;通过方法 getDeclaredFields()getDeclaredMethods()只能获得本类中定义的所有成员变量和方法。

这里就不介绍获取构造方法获取方法了,如果感兴趣的小伙伴可自行去查看。这里只介绍获取成员变量也就是Field这个类

Field类的主要方法

方法

//获得该成员变量的名称
String getName();

//获得表示给成员变量类型的Class对象
Class<?> getType();

//获得指定对象中成员变量的值,返回Object型
Object get(Object obj);

//将指定对象中成员变量的值设置为obj
void set(Object obj, Object value);

//获得指定对象中类型为int的成员变量
int getInt(Object obj);

//将指定对象种类型为int的成员变量的值设为i
void setInt(Object obj, int i)

//。。。八种数据类型都有就不一一列出了

//此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量void setAccessible(boolean flag);

写了这么多,我们在什么时候能用到呢?
现在比如有两个类,好比方说DO(数据库类)和DTO(数据处理专用类),它们之间很多字段都很相同,现在我要吧DO中的数据传给DTO做数据处理,难道我们要一个一个getset吗?我们可以写一个工具类。

用途

DemoDO

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DemoDO {

    private Integer id;

    private String name;

    private Integer sex;
    
    private String password;
}

工具方法

public static <S,T> T copyProperties(S source, Class<T> tClass){
    try {
        Class<?> sClass = source.getClass();
        T target = tClass.newInstance();
        if (null == source){
            return target;
        }
        Field[] fields = tClass.getDeclaredFields();
        for (Field field : fields) {
            try {
                Field declaredField = sClass.getDeclaredField(field.getName());
                field.setAccessible(true);
                declaredField.setAccessible(true);
                field.set(target,declaredField.get(source));
            } catch (NoSuchFieldException e) {
                log.info("没有该字段:{}",field.getName());
            }
        }
        return target;
    } catch (InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(String.format("%s must declaring none arguments constructor!", tClass.getTypeName()));
    }
}

测试

public static void main(String[] args) {
    DemoDO demoDO = DemoDO.builder().id(1).name("zy").sex(1).password("123").build();
    DemoDTO demoDTO = copyProperties(demoDO, DemoDTO.class);
    System.out.println(demoDTO.toString());
}

结果

DemoDTO(id=1, name=zy, sex=1)

当然这个只是例子,其实spring早就提供了这方面的工具了了,BeanUtils.copyProperties感兴趣的小伙伴可以去了解下。

相关文章
反射和反射的方法
反射和反射的方法
|
前端开发 编译器 容器
Java反射->什么是反射?->获取方式
Java反射->什么是反射?->获取方式
Java反射->什么是反射?->获取方式
|
Java API
Java反射(四)反射获取类的结构信息
介绍了Constructor Method Field Class的API
122 0
|
XML Java 数据格式
反射机制(什么是反射、反射操作构造器、方法、字段、反射加载资源)
反射机制(什么是反射、反射操作构造器、方法、字段、反射加载资源)
159 0
反射机制(什么是反射、反射操作构造器、方法、字段、反射加载资源)
|
算法 安全 C#
C#反射与特性(一):反射基础
C#反射与特性(一):反射基础
266 0
C#反射与特性(一):反射基础
C#反射与特性(四 实例化类型
C#反射与特性(四 实例化类型
282 0
C#反射与特性(四 实例化类型
|
C# 索引
C#反射与特性(八):反射操作的示例大全
C#反射与特性(八):反射操作的示例大全
344 0