Java反射常用的方法和使用技巧

朱雀 2024-04-18 14:24 219阅读 0赞

Class是Type接口的实现

  1. public final class Class<T> implements java.io.Serializable,
  2. GenericDeclaration,
  3. Type,
  4. AnnotatedElement { }

Class#isAssignableFrom判断父子关系

  1. // SuperClass.isAssignableFrom(Child.class)
  2. if (List.class.isAssignableFrom(clazz)) {
  3. }

Class#getSuperclass返回父类的类型

  1. public static void getAllFieldsContainsSuper(Class<?> clazz) {
  2. for (; !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
  3. Field[] declaredFields = clazz.getDeclaredFields();
  4. for (Field declaredField : declaredFields) {
  5. }
  6. }
  7. }

Class#newInstance构造对象

一定要有无参构造函数,注意:基本数据类型获取的class之后不能通过newInstance构造对象!

  1. public static final Map<String, Class<?>> BASIC_DATA_TYPE_MAP = new HashMap<>();
  2. static {
  3. BASIC_DATA_TYPE_MAP.put("int", Integer.class);
  4. BASIC_DATA_TYPE_MAP.put("double", Double.class);
  5. BASIC_DATA_TYPE_MAP.put("long", Long.class);
  6. BASIC_DATA_TYPE_MAP.put("short", Short.class);
  7. BASIC_DATA_TYPE_MAP.put("byte", Byte.class);
  8. BASIC_DATA_TYPE_MAP.put("boolean", Boolean.class);
  9. BASIC_DATA_TYPE_MAP.put("char", Character.class);
  10. BASIC_DATA_TYPE_MAP.put("float", Float.class);
  11. }
  12. public static <T> T getRandomNumber(Class<?> clazz) throws Exception {
  13. Random random = new Random();
  14. StringBuilder sb = new StringBuilder();
  15. sb.append(random.nextInt(10));
  16. String str = sb.toString();
  17. if (clazz.isPrimitive()) {
  18. clazz = BASIC_DATA_TYPE_MAP.get(clazz.getName());
  19. }
  20. Constructor<?> constructor = clazz.getConstructor(String.class);
  21. Object result = constructor.newInstance(str);
  22. return (T) result;
  23. }

Class#isPrimitive判断基本数据类型

注意:定义方法接收Object类型的参数,将基本数据类型传入,然后调用getClass方法,再调用isPrimitive返回false

  1. public static void main(String[] args) throws Exception {
  2. test(int.class);
  3. int n = 1;
  4. test(n);
  5. }
  6. public static void test(Class clazz) {
  7. // 返回true
  8. System.out.println(clazz.isPrimitive());
  9. }
  10. public static void test(Object object) {
  11. // 返回false
  12. System.out.println(object.getClass().isPrimitive());
  13. }

Class#getField判断基本数据类型的包装类型

  1. // 判断包装类型
  2. if (clazz.getField("TYPE") != null && ((Class) (clazz.getField("TYPE").get(null))).isPrimitive()) {
  3. return true;
  4. }
  5. // 整合判断基本数据类型和包装类型的方法
  6. public static boolean isPrimitive(Class<?> clazz) {
  7. try {
  8. // 判断基本数据类型
  9. if (clazz.isPrimitive()) {
  10. return true;
  11. }
  12. // 判断包装类型
  13. if (clazz.getField("TYPE") != null && ((Class) (clazz.getField("TYPE").get(null))).isPrimitive()) {
  14. return true;
  15. }
  16. } catch (Exception e) {
  17. }
  18. return false;
  19. }

Class的getDeclaredXxx和getXxx

getXxx是获取到自身和父类所有public级别的方法/属性/构造器
getDeclaredXxx是获取自身的所有方法,包括公用(public)方法、私有(private)方法等
如果需要列出所有继承自父类的方法,先获得父类,然后使用getDeclaredMethods,之后持续递归即可

Field#getType获取字段类型,返回Class

Field#getGenericType获取泛型真实类型,没有泛型返回null

  1. Type genericType = field.getGenericType();
  2. if (genericType != null && genericType instanceof ParameterizedType) {
  3. ParameterizedType parameterizedType = (ParameterizedType) genericType;
  4. // 可能有多个泛型
  5. Class actualType = (Class) parameterizedType.getActualTypeArguments()[0];
  6. }

Modifier判断修饰符

  1. if (Modifier.isFinal(declaredField.getModifiers()) && Modifier.isStatic(declaredField.getModifiers())) {
  2. continue;
  3. }

instantof判断对象是否是某个类的实例

在这里插入图片描述
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,219人围观)

还没有评论,来说两句吧...

相关阅读