美文网首页
Java 反射进阶

Java 反射进阶

作者: Tinyspot | 来源:发表于2022-07-23 20:49 被阅读0次

    1. 使用反射调用方法

    // java.util.Properties#setProperty
    public synchronized Object setProperty(String key, String value) {
      return put(key, value);
    }
    
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        // 用反射方式调用此方法 properties.setProperty("name", "boy");
        invokeMethod(properties, "setProperty", new Class[]{String.class, String.class}, "name", "boy");
        System.out.println(properties.toString());
    }
    /**
     * 反射调用方法
     * @param obj 对象
     * @param methodName 方法名
     * @param types 参数类型
     * @param args 参数的值
     * @return
     */
    public static Object invokeMethod(Object obj, String methodName, Class<?>[] types, Object... args) throws Exception {
        Class<?> clazz = obj.getClass();
        // public Method getMethod(String name, Class<?>... parameterTypes) {}
        Method method = clazz.getMethod(methodName, types);
        // public Object invoke(Object obj, Object... args) {}
        return method.invoke(obj, args);
    }
    

    2. 工厂模式

    工厂模式主要负责对象创建的问题
    可通过反射进行工厂模式的设计,完成动态的对象创建

    public static void main(String[] args) throws Exception {
        // Usb usb = UsbFactory.createUsb(Mouse.class);
        // usb.service();
        UsbFactory.service(Mouse.class);
    }
    
    public class UsbFactory {
        public static Usb createUsb(Class<?> clazz) {
            Usb usb = null;
            try {
                usb = (Usb) clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return usb;
        }
    
        public static void service(Class<?> clazz) {
            try {
                Usb usb = (Usb) clazz.newInstance();
                usb.service();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public interface Usb {
        void service();
    }
    public class Mouse implements Usb {
        @Override
        public void service() {
            System.out.println("mouse running...");
        }
    }
    

    3. 泛型处理

    Java通过泛型擦除,一但编译完成,所有和泛型有关的类型全部擦除

    Class<User> userClass = User.class;
    Method invoke = userClass.getMethod("invoke", Map.class, List.class);
    Type[] genericParameterTypes = invoke.getGenericParameterTypes();
    for (Type genericParameterType : genericParameterTypes) {
        // ParameterizedType 参数化类型
        if (genericParameterType instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
            System.out.println(genericParameterType + "#" + Arrays.toString(actualTypeArguments));
        }
    }
    
    public void invoke(Map<String, Object> map, List<User> users) {
            System.out.println("invoke test");
        }
    

    4. 注解处理

    @Retention(RetentionPolicy.RUNTIME) 指定注解可以保留的域

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TypeValue {
        String value();
    }
    
    @Target({ElementType.FIELD, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ValueInfo {
        String name();
        String type() default "";
    }
    
    @TypeValue("userInfo")
    public class User {
        
        @ValueInfo(name = "age", type = "int")
        private Integer age;
        private String name;
    
        @ValueInfo(name = "test")
        public void test(String name) {
            System.out.println("test() running, name: " + name);
        }
    }
    

    获取方法上的注解

    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        Method method = clazz.getMethod("test", String.class);
        ValueInfo annotation = method.getAnnotation(ValueInfo.class);
        System.out.println(annotation.name() + ";" + annotation.type());
        // 调用方法
        User user = (User) clazz.newInstance();
        method.invoke(user, annotation.name());
    }
    

    获取属性上的注解

    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        System.out.println("类是否有TypeValue注解:" + clazz.isAnnotationPresent(TypeValue.class));
    
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ValueInfo.class)) {
                ValueInfo annotation = field.getAnnotation(ValueInfo.class);
                System.out.println(field.getName() + "注解上的值为:" + annotation.name());
            }
        }
    }
    
    Field field = userClass.getDeclaredField("age");
    FieldValue fieldValue = field.getAnnotation(FieldValue.class);
    System.out.println(fieldValue.name() + "; " + fieldValue.type());
    
    Annotation[] annotations = clazz.getAnnotations();
    System.out.println(Arrays.toString(annotations));
    

    相关文章

      网友评论

          本文标题:Java 反射进阶

          本文链接:https://www.haomeiwen.com/subject/orlmirtx.html