美文网首页
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基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • java 反射基础

    1.java反射基础 2.java反射进阶 反射的两个显著的作用 反编译: .class —> .java 通过...

  • 谈谈移动开发编程中的反射(Reflection)

    目录 什么是反射(Reflection) Objective-C的反射 Objective-C的反射进阶 Java...

  • java 反射进阶

    1.java反射基础 2.java反射进阶 上一节介绍了反射基础,本节介绍更深入的反射概念。 1.获取不到Clas...

  • Java 动态代理,看这篇就够了

    这篇文章需要用到 Java 的反射知识,如果对反射还不清楚的小伙伴,可以先移步到这里 《Java进阶-反射》。 编...

  • 【Java 进阶】Java 反射

    反射:获取Class中所有字段(Field)与方法(Method),并实现调用(invoke) Java 反射简单...

  • Java高级进阶-反射

    前言 反射是高级框架的基础,是进阶必备知识点之一,今天就来总结一下反射前前后后相关的知识点。 1.反射机制介绍 J...

  • Java进阶系列——反射

    学习笔记,基础知识。开头文字很长,不要着急,干货会有的,先弄清楚概念,理解与使用起来就会事半功倍,不会纠结什么时候...

  • Java进阶-反射机制

    一、概念 Java反射是Java被视为动态(或准动态)语言的一个关键性质。指在程序运行状态中,可以构造任意一个类,...

  • Java 反射进阶

    1. 使用反射调用方法 2. 工厂模式 工厂模式主要负责对象创建的问题可通过反射进行工厂模式的设计,完成动态的对象...

网友评论

      本文标题:Java 反射进阶

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