美文网首页
java 反射进阶

java 反射进阶

作者: 写代码的向日葵 | 来源:发表于2019-07-26 13:00 被阅读0次

1.java反射基础

2.java反射进阶


上一节介绍了反射基础,本节介绍更深入的反射概念。

1.获取不到Class

当Class.forName()中路径获取不到对应的Class时,会抛出异常。

2. 获取不到Field

  1. 确实不存在这个Field
  2. 修饰符导致的权限问题
    以上两种情况会抛出NoSuchFieldException异常

反射获取属性的修饰符

方法 本Class SuperClass
getField public public
getDeclaredField public procted private no
getFields public public
getDeclaredFields public procted private no
  1. getField只能获取对象中public修饰符的属性,并且能获取父类Class的public属性。
  2. getDeclaredField能获取对象中各种修饰符的属性,但无法获取父类的任何属性。

如何才能获取父类的属性呢?class对象会提供getSuperClass的方法来获取父类的对象,然后再通过父类调用
getDeclaredField来获取其属性。

  Class c1=Class.forName("com.zhang.Reflect");
  Class superClass=c1.getSuperClass();
  Field field=superClass.getDeclaredField("name");

3. 获取不到Method

和Field的情况类似,当方法名或参数数目类型没对上时,就会出NoSuchMethodException异常。获取方法体如下表

获取方法体

方法 本Class SuperClass
getMethod public public
getDeclaredMethod public procted private no
getMethods public public
getDeclaredMethods public procted private no

4. 获取不到Constructor

方法 本Class SuperClass
getConstructor public public
getDeclaredConstructor public procted private no

\color{red}{需要注意的是,构造方法无法调用父类的任何方法}
反射创建一个对象,可以使用Class.newInstance()和Constructor.newInstance()两种方法,不同之处在在于Class.newInstance()的使用受到限制,对应的Class中必须存在一个无参数的构造方法,并且必须要有访问权限,而constructor.newInstance()适用任何类型的构造方法,无论是否有参数都可以调用,只需要使用setAccessible()控制访问验证即可。所以一般建议使用constructor.newInstance().

5.反射静态方法

调用静态方法直接用Class.method()的形式就可以调用。

public  class TestMethod{
        static void test(){
              System.out.println("test");
         }
}

public class Test{
           public static void main(String[] args) {
            try {
                    Class clz=Class.forName("TestMethod");
                    Method method=clz.getDeclaredMethod("test");
                    method.invoke(null);
             }catch (ClassNotFoundException e) {
                  e.printStackTrace();
              } catch (NoSuchMethodException e) {
                  e.printStackTrace();
              } catch (IllegalAccessException e) {
                  e.printStackTrace();
              } catch (IllegalArgumentException e) {
                  e.printStackTrace();
              } catch (InvocationTargetException e) {
                  e.printStackTrace();
        }
    }
}

关键在于Method.invoke的第一个参数,static方法因为因为属于类本身,所以不需要填写对象,填写nuLL即可。

6.反射泛型参数方法

在说这个之前,我门需要看下invoke方法的代码

  @CallerSensitive
    public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        MethodAccessor ma = methodAccessor;             // read volatile
        if (ma == null) {
            ma = acquireMethodAccessor();
        }
        return ma.invoke(obj, args);
    }

第一个Object参数对应的Class对象实例,后面的参数是可变参数,可以接受多个参数。

public class TestMethod<T> {
    public void test(T t){
        System.out.println(t);
    }
}

public class Test {
    public static void main(String[] args) {
        try {
            Class clzT=TestMethod.class;
            Method method=clzT.getDeclaredMethod("test", Object.class);
            method.setAccessible(true);
            method.invoke(new TestMethod<Integer>(), 1);
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

}

其中有一个泛型基础——类型擦除。
当一个方法中有泛型参数时,编译器会自动类型向上转型,T向上转型是Object,所以实际上在TestMethod类中是test(Object t)。getDeclaredMethod需要用Object.class作为参数。

相关文章

  • 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/rhsrrctx.html