• 2、反射-Method&父类


    反射概述:

    Reflection是Java被视为动态语言的关键

    反射机制允许程序再执行期间借助于Reflection API取得任何类的内部信息

    并直接操作任意对象内部的属性及方法

    主要提供了功能:

    1、再运行时任意构造一个类的对象

    2、再运行时取任意一类所具有的成员变量和方法

    3、再运行时调用任意一个对象的方法

    4、生成动态代理

    Class是对一个类的描述

    1、类的属性:Field

    2、类的方法:Method

    3、类的构造器:Constrctor

     

    public class Person {
        String name;
        private int age;
        //私有方法
        private void test(){
        }
        //共有的无参方法
        public void test1(){
        }
        //共有的带参方法
        public void test2(String  m){
            System.out.println(m);
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
         System.out.println("name:" + name);
    this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age) { this.name = name; this.age = age; } public Person() { } }

    类的方法:Method

    Method对应 类中的方法:

    1、获取Method

    2、获取类的方法的数组: getDeclaredMethods()

    3、获取类指定的方法:getDeclaredMethod(String name,Class<?> ... parameterTypes)

      获取私有的方法进行执行还需要添加一行代码:method.setAccessible(true)

    4、执行方法:invoke(Object obj, Object ...arggs)

            Class clazz = Class.forName("refelect.Person");
    
            //1、得到clazz对应的类中的方法
            //注意:私有的方法无法获取
            Method[] methods = clazz.getMethods();
            for (Method method : methods){
                System.out.println(method.getName());
            }

         //2、获取所有的方法
            //获取当前类的方法
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method method:declaredMethods){
                System.out.println(method.getName());
            }

            //3、获取指定的方法,两个参数(1、方法名;2、参数(没有则不写))
            Method setName = clazz.getDeclaredMethod("setName", String.class);
            System.out.println(setName.getName());
            //获取私有的
            Method test = clazz.getDeclaredMethod("test");
            System.out.println(test.getName());

     

            //4、执行方法 invoke(Object obj, Object... args)
            //参数1:要执行的对象
            //参数2:传入的参数
            Object o = clazz.newInstance();
            setName.invoke(o,"MrChengs");

     自定义的invoke方法

    public Object invoke(Object obj,String methodName,Object ...args){
            Class [] parameterTypes = new Class[args.length];
            for (int i = 0 ; i < args.length ; i ++){
                parameterTypes[i] = args[i].getClass();
            }
            try {
                Method method = obj.getClass().getDeclaredMethod(methodName,parameterTypes);
                return method.invoke(obj,args);
            }catch (Exception e){
            }
            return  null;
        }

     

     方法的重载--直接传入全类名

       public Object invoke(String  className,String methodName,Object ...args){
    
            Object obj = null;
            try {
                obj = Class.forName(className).newInstance();
                return invoke(obj, methodName, args);
            }catch (Exception e){
                e.printStackTrace();
            }
            return  null;
        }
    
        public Object invoke(Object obj,String methodName,Object ...args){
            Class [] parameterTypes = new Class[args.length];
            for (int i = 0 ; i < args.length ; i ++){
                parameterTypes[i] = args[i].getClass();
            }
            try {
                Method method = obj.getClass().getDeclaredMethod(methodName,parameterTypes);
                return method.invoke(obj,args);
            }catch (Exception e){
            }
            return  null;
        }
    
        @Test
        public void  testInvoke(){
            Object obj = new Person();
            Object invoke = invoke("refelect.Person", "setName", "MrChengs");
            System.out.println(invoke);
    
        }

     关于父类的问题

     getSuperclass()

            Class clazz = Class.forName("refelect.Student");
            Class superclass = clazz.getSuperclass();
            System.out.println(superclass);

     

    public class Student extends  Person {
    
        private void test3(String  m){
            System.out.println("Student test3");
            System.out.println(m);
        }
    
    }
    public class Person {
    
        private void test2(String  m){
            System.out.println("Person test2");
            System.out.println(m);
        }
    }

     测试:

        public Object invoke1(Object obj,String methodName,Object ...args){
            Class [] parameterTypes = new Class[args.length];
            for (int i = 0 ; i < args.length ; i ++){
                parameterTypes[i] = args[i].getClass();
            }
            try {
                Method method = getMethod(obj.getClass(),methodName,parameterTypes);
                method.setAccessible(true);
                return method.invoke(obj,args);
            }catch (Exception e){
            }
            return  null;
        }
    
        //获取父类中的方法
        public Method getMethod(Class clazz,String methodName,Class ...para){
            for (;clazz != Object.class;clazz = clazz.getSuperclass()){
                try {
                    Method method = clazz.getDeclaredMethod(methodName,para);
                    return method;
                } catch (NoSuchMethodException e) {
                }
            }
            return null;
        }
    
        @Test
        public  void set(){
            //执行自身类的方法
            Object obj = new Student();
            invoke1(obj,"test3","Mr");
    
            //执行父类中的方法
            invoke1(obj,"test2","Mr");
        }

     

  • 相关阅读:
    JeeSite信息化快速开发平台
    Redis操作使用规范
    使用Redis配置JAVA_环境
    BZOJ 1029 [JSOI2007]建筑抢修 已更新
    COJ 2108 Day7-例1
    COJ 2105 submatrix
    COJ 2106 road
    更新一下缺省源
    hiho #1055 : 刷油漆
    COJ 0047 20702最大乘积
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10933320.html
Copyright © 2020-2023  润新知