JDK源码/轮子分析 :反射包 java.lang.reflect④ 之 Method 实例方法(类方法)探秘

今天的主角:java.lang.reflect.Method

Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。

与获得Field 对象一样,我们可以通过Class 对象的相关方法来获取Method对象。
获取本类中所有的方法, 但不包括继承的方法
Method[]    getDeclaredMethods()
Method    getDeclaredMethod(String name, Class<?>... parameterTypes)
获取公共的方法,包括继承而来的方法
Method[]    getMethods()
Method    getMethod(String name, Class<?>... parameterTypes)
老规矩,先上pojo
package com.hlmtest.java.reflect;
public class TestMethodClass {
     
      public TestMethodClass(){}
           
      public String toString(){
            return "我是toString()方法" ;          
     }
      @SuppressWarnings ( "unused" )
      private String privateToString(){
            return "我是privateToString()方法" ;         
     }
           
}
测试方法
package com.hlmtest.java.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestMethodObject {
      public static void main(String[] args ) throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            testMethod ();
     }
     
      public static void testMethod() throws NoSuchMethodException, SecurityException{
            //先获取Class 对象实例
           Class<TestMethodClass> clzz = TestMethodClass. class ;
            //获取本类中所有方法
           Method[] methods = clzz .getDeclaredMethods();
            for (Method m : methods ){
                System. out .println( m .getName()+ ";" );
           }
           System. out .println( "<--我是华丽的分割线-->" );
            //获取公共方法(包括继承来的)
           Method[] publucMethods = clzz .getMethods();
            for (Method m : publucMethods ){
                System. out .println( m .getName()+ ";" );
           }
           System. out .println( "<--我是华丽的分割线-->" );
            //根据名称及参数获取无论什么类型的方法
           Method m1 = clzz .getDeclaredMethod( "privateToString" , null ) ;
           System. out .println( m1 .getName()+ ";" );
           System. out .println( "<--我是华丽的分割线-->" );
            //根据名称及参数获取公共类型的方法
           Method m2 = clzz .getDeclaredMethod( "toString" , null ) ;
           System. out .println( m2 .getName()+ ";" );
           System. out .println( "<--我是华丽的分割线-->" );
            //这么干是会报错的
           Method m3 = clzz .getMethod( "privateToString" , null ) ;
           System. out .println( m3 .getName()+ ";" );
     }
     
}
运行结果

Method 对象获取到了,那么我们就要了解这个对象最重要的东西了。一个方法最重要的是什么呢?当然是能执行咯,难道拿来看啊。获得一个类的方法对象后如何让这个方法执行呢,那就要看我们的:Object    invoke(Object obj, Object... args)

invoke 这个词是不是很熟悉,当我们去看别的框架源码的时候相信大家见得最多的就是这个词了。没错这个就是得到方法对象后想让这个方法运行起来时需要用的方法。

package com.hlmtest.java.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestMethodObject {
      public static void main(String[] args ) throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            testMethod ();
     }
     
      public static void testMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
            //先获取Class 对象实例
           Class<TestMethodClass> clzz = TestMethodClass. class ;
           
            @SuppressWarnings ( "rawtypes" )
           Constructor<TestMethodClass> instance = clzz .getConstructor();
            //调用Constructor 的newInstance(Object... initargs ) 方法获得主对象实例
           TestMethodClass obj = instance .newInstance();
           
           Method m = clzz .getDeclaredMethod( "toString" , null ) ;
           Object methodReturn m .invoke( obj , null ) ;
            System. out .println( methodReturn .toString());
     }
     
}
运行结果

在TestMethodClass 中添加多一个带入参的方法:
public String argsMethod(String str ){
            return str ;          
     }
修改一下执行代码:
package com.hlmtest.java.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestMethodObject {
      public static void main(String[] args ) throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            testMethod ();
     }
     
      public static void testMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
            //先获取Class 对象实例
           Class<TestMethodClass> clzz = TestMethodClass. class ;
           
            @SuppressWarnings ( "rawtypes" )
           Constructor<TestMethodClass> instance = clzz .getConstructor();
            //调用Constructor 的newInstance(Object... initargs ) 方法获得主对象实例
           TestMethodClass obj = instance .newInstance();
           
           Method m = clzz .getDeclaredMethod( "argsMethod" , String. class );
           Object methodReturn m .invoke( obj , "我是测试带入参的方法" );
            System. out .println( methodReturn .toString());
     }
     
}
运行结果:

到此也就差不多了,大家想要了解更多的使用方法的话当然还是文档啦。

Field 的更多API可以查询:

其他

其他反射相关博客:
     JDK源码/轮子分析 :反射包 java.lang.reflect③ 之  Field 获取类的属性字段信息;
201800602



猜你喜欢

转载自blog.csdn.net/mottohlm/article/details/80548406