zoukankan      html  css  js  c++  java
  • java反射——方法

            大家都知道反射技术在Java里面时非常重要的一个技术点,因为Java好多框架的编写都是基于反射的,别的不多说,spring框架里面的IOC就是基于反射实现。那么什么是反射呢?JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。说白了,反射就是加载类,并且反射出类的各个组成部分的一种实现方式。

         java是一种面向对象的语言,所以我们处理任何东西,第一反应就是去找对象,并且调用它内部封装的方法。接下来我们演示如何通过反射来获取一个类中的方法,并执行该方法。

    1.定义一个简单Person类

    package com.day09;
    
    public class Person {
    
    
        public void show() {
            System.out.println("I am  zhangsan  and my age is 1");
        }
    
        public void show(String name) {
            System.out.println("I am " + name);
        }
    
        public void show(String name, int age) {
            System.out.println("I am  " + name + "  and my age is " + age);
        }
    
        private void show(String[] hobbies) {
            System.out.println("my hobby such as: ");
            for (String hobby : hobbies) {
                System.out.println(hobby);
            }
        }
    
        public String getNameAndAge() {
            return "zhangsan:32";
        }
    
        public static void speak() {
            System.out.println("I am a person");
        }
    
        public static void main(String[] args) {
            System.out.println("this is main!");
        }
    }

    2.利用Junit来演示进行演示测试

    package com.day09;
    
    import java.lang.reflect.Method;
    
    import org.junit.Test;
    
    public class ReflectMethodDemo {
        /*
         * 反射普通的无参方法 public void show()
         */
        @Test
        public void reflectNoParameter() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("show", null);
            // 需要传入调用的对象,并传入方法参数,并运行该方法
            method.invoke(clazz.newInstance(), null);
        }
    
        /*
         * 反射普通的方法 public void show(String name)
         */
        @Test
        public void reflectOneParameter() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("show", String.class);
            // 需要传入调用的对象,并传入方法参数,并运行该方法
            method.invoke(clazz.newInstance(), "马里奥");
        }
    
        /*
         * 反射普通的方法public void show(String name, int age)
         */
        @Test
        public void reflectManyParameter() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("show", String.class, int.class);
            // 需要传入调用的对象,并传入方法参数,并运行该方法
            method.invoke(clazz.newInstance(), "马里奥", 100);
        }
    
        /*
         * 反射普通的私有方法 private void show(String[] hobbies)
         */
        @Test
        public void reflectPrivateParameter() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 因为是私有方法,所以要用传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getDeclaredMethod("show", String[].class);
            // 因为是私有方法,需要打开权限,设为可见
            method.setAccessible(true);
            // 需要传入调用的对象,并传入方法参数,并运行该方法new String[] { "游泳", "跑步", "健身", "篮球" }
            method.invoke(clazz.newInstance(), new Object[] { new String[] { "游泳", "跑步", "健身", "篮球" } });
        }
    
        /*
         * 反射普通的无参方法public String getNameAndAge()
         */
        @Test
        public void reflectReturnValue() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("getNameAndAge", null);
            // 需要传入调用的对象,并传入方法参数,并运行该方法,用一个object对象接收参数
            Object obj = method.invoke(clazz.newInstance(), null);
            System.out.println(obj);
        }
    
        /*
         * 反射静态方法 public static void speak()
         */
        @Test
        public void reflectStatic() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("speak", null);
            // 因为是静态方法,所以可以不传对象,直接null就行,并传入方法参数,并运行该方法
            method.invoke(null, null);
        }
    
        /**
         * 反射main方法
         * 
         * @throws SecurityException
         * @throws NoSuchMethodException
         * 
         */
        @Test
        public void reflectMain() throws Exception {
            // 将类加载如内存
            Class<?> clazz = Class.forName("com.day09.Person");
            // 传入方法的名称和方法的参数信息,得到我们需要的方法
            Method method = clazz.getMethod("main", String[].class);
            // 因为是静态方法,所以可以不传对象,直接null就行,并传入方法参数,并运行该方法
            method.invoke(null, new Object[1]);
        }
    
    }

    至此,我们已将常见的几种通过反射获取对象方法,并运行方法演示完毕,有不足的地方,希望大家多多提意见!

  • 相关阅读:
    Android之缩减apk大小[资源文件篇]:基于自定义Shape设置ShapeDrawable
    二叉排序树与堆的区别
    4、多用类型常量,少用#define预处理指令
    3、多用字面量语法,少用与之等价的方法
    2、在类的头文件中尽量少引入其他头文件
    1、了解Objective-C语言的起源
    iOS中date和string的转换
    OC中的抽象基类 和 接口
    Swift -- 基础部分 -- 1、常量和变量
    计算机原理简述-处理器和汇编
  • 原文地址:https://www.cnblogs.com/nanyangke-cjz/p/7106189.html
Copyright © 2011-2022 走看看