反射五部曲,getClass的操作

解析
1.获取反射对象类信息

object.getClass() :获取类对象信息

  Animal animal = new Animal();
        animal.setCode("10");
        animal.setName("miao");
        Class<?> aClass = animal.getClass();
        System.out.println(aClass);
        //class com.example.demo.pojo.relfect.Animal
   

aClass.getName() :获取类全名,包名+类名

 System.out.println(aClass.getName());
 // com.example.demo.pojo.relfect.Animal

aClass.getSimpleName() :仅获取类名

System.out.println(aClass.getSimpleName());
// Animal

aClass.getClassLoader() :获取该类的加载器

 System.out.println(aClass.getClassLoader());
 // sun.misc.Launcher$AppClassLoader@18b4aac2

拓展一下类加载器(双亲委派):
类的加载是从自定义类中,委托到最上层加载器开始寻找对应的类,找不到才逐个往下找。
若有上下层重复,会报错。也就是说沙箱保护机制会优先选择上层有的类。

在这里插入图片描述

2.获取类中的字段、方法

注意事项: 若要获取到值或调用的是private修饰的,需要先走第三步,让私有失效。

aClass.getDeclaredFields() :获取该类所有的字段
aClass.getDeclaredField("字段名") :获取该类某个字段

 Field[] fields = aClass.getDeclaredFields();
 Field code = aClass.getDeclaredField("code");
        for (Field field : fields) {
            System.out.println(field.getName());
            System.out.println(field.get(animal)+"\n");
            /**
             * code
             * 10
             * 
             * codeBz
             * null
             * 
             * name
             * miao
             * 
             * nameBz
             * null
             */
        }

aClass.getMethods() :获取该类所有方法
aClass.getMethod("方法名", 方法类型.class) :获取对应某个方法

        Method[] methods = aClass.getMethods();
        Method method1 = aClass.getMethod("methodTest", String.class);
        for (Method method : methods) {
            if (method.getName().equals("methodTest")) {
                System.out.println(method.getName());
                // methodTest
                System.out.println(method.invoke(animal, "加菲猫"));
                // 加菲猫
            }
            /**
             * equals
             * toString
             * hashCode
             * getName
             * setName
             * setCode
             * getNameBz
             * setCodeBz
             * setNameBz
             * getCodeBz
             * getCode
             * wait
             * wait
             * wait
             * getClass
             * notify
             * notifyAll
             */
        }
3.设置私有字符失效->private

方法.setAccessible(true)/ 字段.setAccessible(true).

@ApiModelProperty("原动物代码")
   private String code;
      Field code = aClass.getDeclaredField("code");
//        code.setAccessible(true);
        code.get(animal);

若不先让私有化失效,操作过程中可能会出现报错。
放开code.setAccessible(true);就好了。

Exception in thread "main" java.lang.IllegalAccessException: Class com.example.demo.pojo.relfect.Reflector can not access a member of class com.example.demo.pojo.relfect.Animal with modifiers "private"
	at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
	at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
	at java.lang.reflect.Field.get(Field.java:390)
4.获取某个对象对应字段的值

字段.get(对象) :表示获取某个对象中该字段的值。注意私有情况要先设定失效。

Animal animal = new Animal();
        animal.setCode("10");
        animal.setName("miao");
        Class<?> aClass = animal.getClass();
Field code = aClass.getDeclaredField("code");
        code.setAccessible(true);
        code.get(animal);

方法.invoke(方法名,入参) :调用某个方法

// 获取某个方法对象
Method method1 = aClass.getMethod("methodTest", String.class);
// 私有化失效
method1.setAccessible(true);
// 调用animal对象中的methodTest方法
method1.invoke(animal,"加菲猫");
5.设置某个字段的值

字段.set(对象,要设置的值) :设置某个字段的值。注意私有情况要先设定失效。

 Field code = aClass.getDeclaredField("code");
        code.setAccessible(true);
        //设置animal对象中code的值
        code.set(animal,"反射设置的code");
小案例

映射实体类

package com.example.demo.pojo.relfect;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
public class Animal {
    @ApiModelProperty("原动物代码")
    String code;
    @ApiModelProperty("原动物名")
    String codeBz;
    @ApiModelProperty("标准动物代码")
    String name;
    @ApiModelProperty("标准动物名")
    String nameBz;
    public String methodTest(String arg){
       return arg;
    }
}

具体实现类

其中的枚举类:AnimalEnum

package com.example.demo.pojo.relfect;

import com.example.demo.pojo.AnimalEnum;

import java.lang.reflect.Field;

public class Reflector {

    public static void main(String[] args) {
        //现在要通过code进行标准化name。
        Animal animal = new Animal();
        animal.setCode("10");
        animal.setName("miao");
        reflectCodeName(animal, "code", "name", AnimalEnum.match(animal.getCode()), "codeBz", "nameBz");
        System.out.println(animal);
        // Animal(code=10, codeBz=10, name=miao, nameBz=cat)
    }

  private static void reflectCodeName (Object object, String sourceField, String sourceField2, AnimalEnum
        animalEnum, String targetSource, String targetSource2){
            try {
                // 原数据判断
                Class<?> aClass = object.getClass();
                Field originValue = aClass.getDeclaredField(sourceField);
                originValue.setAccessible(true);
                Object o = originValue.get(object);
                if (o == null) {
                    return;
                }
                if (animalEnum == null) {
                    return;
                }
                // 获取标准数据
                Field targetValue = aClass.getDeclaredField(targetSource);
                // 设置private字段失效
                targetValue.setAccessible(true);
                //放入标准属性
                targetValue.set(object, animalEnum.getCode());

                Field originValue2 = aClass.getDeclaredField(sourceField2);
                originValue2.setAccessible(true);
                Object o2 = originValue2.get(object);

                if (o == null) {
                    return;
                }
                // 获取标准数据
                Field targetValue2 = aClass.getDeclaredField(targetSource2);
                targetValue2.setAccessible(true);
                targetValue2.set(object, animalEnum.getType());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
}

6.当需要反射到父类时

子类:

public class Cat extends Animal{
    @ApiModelProperty("猫叫")
    String miao;
    @ApiModelProperty("鱼品种")
    String fish;
}

实现类:


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ReflectorDad {
    public static void main(String[] args) {
        Cat cat = new Cat();
        //  获取当前类字段
        Class<?> aClass = cat.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName());
            /**
             * miao
             * fish
             */
        }
        //  获取父类字段
        Class<?> superclass = aClass.getSuperclass();
        Field[] superFields = superclass.getDeclaredFields();
        for (Field superField : superFields) {
            System.out.println(superField.getName());
            /**
             * code
             * codeBz
             * name
             * nameBz
             */
        }
        // 获取该类所有有关的字段
        List<Field> allField = getAllField(cat);
        for (Field field : allField) {
            System.out.println(field.getName());
        }
    }

    /**
     * 获取所有的字段信息
     * @param o
     * @return
     */
    public static List<Field> getAllField(Object o){
        List<Field> fields = new ArrayList<>();
        Class<?> aClass = o.getClass();

        while (aClass!=null){
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField.getName());
            }
            fields.addAll(Arrays.asList(declaredFields));
            if (aClass.getSuperclass()!=null){
                System.out.println(aClass.getSuperclass());
                aClass=aClass.getSuperclass();
            }else {
                aClass = null;
            }
        }
        return fields;
    }
}
7.反射案例箱
 /**
     * 筛选转换
     * 1.挑选出指定类型的数据
     * 2.转换成指定类型的对象
     *
     * @param source   数据
     * @param category 指定类型
     * @param tClass   指定类的类型
     * @param field    指定属性
     * @param <T>
     * @return
     */
    private static <T> List<T> filterTransformation(List<?> source, String category, Class<?> tClass, String field) {
        List<?> objects = source.stream().filter(s -> {
            try {
                return s.getClass().getSuperclass().getDeclaredField(field).get(s).
                        equals(category);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
            return false;
        }).collect(Collectors.toList());

        return (List<T>) BeanUtil.copyList(objects, tClass);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值