前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反射到底有什么作用,能帮我们干些什么呢?

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

作者头像
用户2242639
发布2022-01-18 16:01:14
3120
发布2022-01-18 16:01:14
举报
文章被收录于专栏:Java经验总结Java经验总结

反射能做什么

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

反射常用的类

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

Class类

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

创建Class类对象的三种方法

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

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

Class类的主要方法

构造方法

代码语言:javascript
复制
//获得所有权限为public的构造方法
Constructor<?>[] getConstructors();

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

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

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

方法

代码语言:javascript
复制
//获得所有权限为public的方法
Method[] getMethods();

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

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

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

成员变量

代码语言:javascript
复制
//获得权限为public的成员变量
Field[] getFields();

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

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

//获得指定成员变量
Field getDeclaredField(String name);

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

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

Field类的主要方法

方法

代码语言:javascript
复制
//获得该成员变量的名称
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

代码语言:javascript
复制
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DemoDO {

    private Integer id;

    private String name;

    private Integer sex;
    
    private String password;
}

DemoDTO

代码语言:javascript
复制
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DemoDO {

    private Integer id;

    private String name;

    private Integer sex;
    
}

工具方法

代码语言:javascript
复制
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()));
    }
}

测试

代码语言:javascript
复制
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());
}

结果

代码语言:javascript
复制
DemoDTO(id=1, name=zy, sex=1)

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java经验总结 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 反射能做什么
  • 反射常用的类
  • Class类
  • Class类的主要方法
    • 构造方法
      • 方法
        • 成员变量
        • Field类的主要方法
          • 方法
          • 用途
            • DemoDO
              • DemoDTO
                • 工具方法
                  • 测试
                    • 结果
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档