反射基本介绍
基本过程:
1、编译Java文件,生成.class文件
2、使用Java虚拟机(JVM)将字节码文件(字节码文件在内存中使用Class类表示)加载到内存
4、使用反射的时候,首先获取到Class类,就可以得到class文件里的所有内容,包含属性、构造方法、普通方法
5、属性通过Filed类表示、构造方法通过Constructor表示、普通方法通过Method表示
API学习
接口定义
1 2 3 public interface Pc { void run () ; }
实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class Dell implements Pc { private String cpu; public int price; public Dell () { } public Dell (String cpu) { this .cpu = cpu; } @Override public void run () { System.out.println("Dell PC" ); } public String getCpu () { return cpu; } public void setCpu (String cpu) { this .cpu = cpu; } public int getPrice () { return price; } public void setPrice (int price) { this .price = price; } private void desc () { System.out.println("私有方法: 散热不好" ); } }
API学习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 @Slf4j public class ReflectEntrance { public static void main (String[] args) throws Exception { Class<?> dClazz = Class.forName("com.example.ref.Dell" ); log.info("Class.forName()=======:{}" , dClazz); Class<Dell> dClazz2 = Dell.class; log.info("类名.class=======:{}" , dClazz); Dell dell = new Dell(); Class<?> dClazz3 = dell.getClass(); log.info("对象.getClass()=======:{}" , dClazz3); System.out.println("\r" ); Method[] methods = dClazz.getMethods(); for (Method method: methods) { log.info("dClazz.getMethods()=======:{}" , method.getName()); } System.out.println("\r" ); Method[] declaredMethods = dClazz.getDeclaredMethods(); for (Method method : declaredMethods) log.info("dClazz.getDeclaredMethods()=======:{}" , method.getName()); System.out.println("\r" ); Class<?>[] interfaces = dClazz.getInterfaces(); for (Class<?>inter : interfaces) log.info("dClazz.getInterfaces()=======:{}" , inter); System.out.println("\r" ); Field[] fields = dClazz.getFields(); for (Field field : fields) log.info("dClazz.getFields()=======:{}" , field); System.out.println("\r" ); Field[] declaredFields = dClazz.getDeclaredFields(); for (Field field : declaredFields) log.info("dClazz.getDeclaredFields()=======:{}" , field.getName()); System.out.println("\r" ); Constructor<?>[] constructors = dClazz.getConstructors(); for (Constructor<?> c : constructors) log.info("dClazz.getConstructors()=======:{}" , c); System.out.println("\r" ); Class<?> superclass = dClazz.getSuperclass(); log.info("dClazz.getSuperclass()=======:{}" , superclass); System.out.println("\r" ); Dell dell1 = (Dell)dClazz.newInstance(); log.info("dClazz.newInstance()=======:{}" , dell1); dell1.run(); System.out.println("\r" ); Field cpu = dClazz.getDeclaredField("cpu" ); cpu.setAccessible(true ); cpu.set(dell1, "intel" ); log.info("设置变量=======:{}" , dell1.getCpu()); System.out.println("\r" ); Method setCpu = dClazz.getDeclaredMethod("setCpu" , String.class); setCpu.setAccessible(true ); setCpu.invoke(dell1, "AMD" ); log.info("调用方法=======:{}" , dell1.getCpu()); System.out.println("\r" ); Constructor<?> declaredConstructor = dClazz.getDeclaredConstructor(String.class); Dell hw = (Dell)declaredConstructor.newInstance("华为" ); log.info("构造方法=======:{}" , hw.getCpu()); } }
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 23:24:02.109 [main] INFO com.example.ref.ReflectEntrance - Class.forName()=======:class com.example.ref.Dell 23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 类名.class=======:class com.example.ref.Dell 23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 对象.getClass()=======:class com.example.ref.Dell 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:run 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getPrice 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setPrice 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setCpu 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getCpu 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:equals 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:toString 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:hashCode 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getClass 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notify 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notifyAll 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:run 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:desc 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getPrice 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setPrice 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setCpu 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getCpu 23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getInterfaces()=======:interface com.example.ref.Pc 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getFields()=======:public int com.example.ref.Dell.price 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:cpu 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:price 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell() 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell(java.lang.String) 23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getSuperclass()=======:class java.lang.Object 23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - dClazz.newInstance()=======:com.example.ref.Dell@3a5ed7a6 Dell PC 23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - 设置变量=======:intel 23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 调用方法=======:AMD 23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 构造方法=======:华为
有参构造反射
1 2 3 4 5 6 7 8 9 10 public static ConfigService createConfigService (Properties properties) throws NacosException { try { Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService" ); Constructor constructor = driverImplClass.getConstructor(Properties.class); ConfigService vendorImpl = (ConfigService) constructor.newInstance(properties); return vendorImpl; } catch (Throwable e) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e); } }
简单演示场景
我们做一个对象转map的演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class User implements Serializable { private String username; private String password; public User () { } public User (String username, String password) { this .username = username; this .password = password; } public String getUsername () { return username; } public void setUsername (String username) { this .username = username; } public String getPassword () { return password; } public void setPassword (String password) { this .password = password; } @Override public String toString () { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}' ; } }
通过反射操作字段变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 @Slf4j public class BeanUtils { public static <T> Map<String, Object> obj2map (T o) throws IllegalAccessException { Class<?> aClass = o.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); Map<String,Object> map = new HashMap<String, Object>(); for (int j = 0 ; j < declaredFields.length; j++) { Field declaredField = declaredFields[j]; String key = declaredField.getName(); declaredField.setAccessible(true ); Object value = declaredField.get(o); log.info("key={}, value={}" , key, value == null ? "" : value.toString()); map.put(key, value); } return map; } public static Object map2Obj (Map<Object, Object> map, Class<?> beanClass) throws Exception { if (map == null ) return null ; Object obj = beanClass.getDeclaredConstructor().newInstance(); Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { int mod = field.getModifiers(); if (Modifier.isStatic(mod) || Modifier.isFinal(mod)){ continue ; } Class<?> type = field.getType(); Object o = convertValType(map.get(field.getName()), type); field.setAccessible(true ); field.set(obj, o); } return obj; } private static Object convertValType (Object value, Class<?> fieldTypeClass) { Object retVal = null ; if (Long.class.getName().equals(fieldTypeClass.getName()) || long .class.getName().equals(fieldTypeClass.getName())) { retVal = Long.parseLong(value.toString()); } else if (Integer.class.getName().equals(fieldTypeClass.getName()) || int .class.getName().equals(fieldTypeClass.getName())) { retVal = Integer.parseInt(value.toString()); } else if (Float.class.getName().equals(fieldTypeClass.getName()) || float .class.getName().equals(fieldTypeClass.getName())) { retVal = Float.parseFloat(value.toString()); } else if (Double.class.getName().equals(fieldTypeClass.getName()) || double .class.getName().equals(fieldTypeClass.getName())) { retVal = Double.parseDouble(value.toString()); } else { retVal = value; } return retVal; } public static void main (String[] args) throws Exception { User user = new User("admin" , "123456" ); Map<String, Object> map = BeanUtils.obj2map(user); System.out.println(map); Object o = BeanUtils.map2Obj(map, User.class); System.out.println(o); } }
输出
1 2 {password=123456, username=admin} User{username='admin', password='123456'}
最后
本文到此结束。感谢阅读,如果您觉得不错,请关注公众号【当我遇上你】支持一下。