zoukankan      html  css  js  c++  java
  • java反射-使用反射来操纵方法

    博客已迁移到CSDN《https://blog.csdn.net/qq_33375499

    一个类的主要成员时方法,辣么我们通过反射获取到一个类的所有方法信息后,总的寻找一种方式去操作调用这些方法,这样反射才有意义有意思。

    Method对象有一个方法invoke。      public Object invoke(Object obj, Object... args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException。    该方法的解释API解释为:

    对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。 
    如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。 
    
    如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。 
    
    如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。 
    
    如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。 
    
    如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。 
    

      下面我用ArrayList 类来做了一个测试:

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Parameter;
    import java.util.ArrayList;
    
    /**
     * java反射 工具类
     */
    public class ClassUtil {
        /**
         * 通过反射操作对象方法
         */
        public static void method() {
            try {
                // 本例中传入的是ArrayList 对象,就以ArrayList 对象的add方法为例
                ArrayList arrayList = new ArrayList();
                // 1.获取该类的类类型
                Class c = arrayList.getClass();
                // 2.获取该类自己定义的所有方法
                Method[] methods = c.getDeclaredMethods();
                // 3.得到所有方法列表信息
                for (Method method : methods) {
                    System.out.print(method.getName() + "(");
                    Class[] parameterTypes = method.getParameterTypes();
                    for (int i = 0, len = parameterTypes.length; i < len; i++) {
                        System.out.print(parameterTypes[i].getName());
                        if (i != len - 1) {
                            System.out.print(",");
                        }
                    }
                    System.out.print(")
    ");
                }
                // 4.使用方法 invoke 来操作方法 add
                Method method = c.getMethod("add", new Class[]{Object.class});
                method.invoke(arrayList, "测试1");
                method.invoke(arrayList, 100);
                method.invoke(arrayList, 100.0f);
    
                // 5.测试打印 arrayList 对象
                System.out.println("================" + arrayList);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            ClassUtil.method();
        }
    }

      对于java集合中的泛型,是用于在编译阶段程序员输入验证的,我们可以通过反射的方式,来绕过这种输入验证。如上面的栗子,我们将 ArrayList<String> arrayList = new ArrayList(); 指定泛型为String类型,其他代码不变,你会发现,打印输出的结果还是一样。

  • 相关阅读:
    [自娱自乐] 2、超声波测距模块DIY笔记(二)
    [自制简单操作系统] 9、命令行与应用程序 整体回顾
    [汇编] C语言中嵌入汇编
    [Java Web] 5、JSP (1) 注释 & Scriptlet
    [自娱自乐] 1、超声波测距模块DIY笔记(一)
    [Java Web] 4、JavaScript 简单例子(高手略过)
    [C#] Timer + Graphics To Get Simple Animation (简单的源码例子,适合初学者)
    [自制简单操作系统] 8、多任务(三)——多窗口与优先级
    [自制简单操作系统] 7、多任务(二)——任务管理自动化&任务休眠
    [自制简单操作系统] 6、多任务(一)
  • 原文地址:https://www.cnblogs.com/www-123456/p/10878100.html
Copyright © 2011-2022 走看看