A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 官珺伟 高级黑马   /  2014-4-23 15:11  /  1431 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 官珺伟 于 2014-4-23 17:03 编辑
  1. //反射静态方法。
  2.   public static void method_4() throws Exception {
  3.   Class clazz = Class.forName("cn.itcast.bean.Person");
  4.   Method method = clazz.getMethod("function",null); //这里的空代表的是什么?
  5.    method.invoke(null,null); //俩个空是什么意思??
  6.   }
复制代码

如果不是静态方法,null可以换成对象吗?

5 个回复

倒序浏览
查看了一下API手册,这样解释的:
getMethod
public Method getMethod(String name,
                        Class<?>... parameterTypes)
                 throws NoSuchMethodException,
                        SecurityException返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。如果 parameterTypes 为 null,则按空数组处理。
如果 name 是 "<init>;" 或 "<clinit>",则将引发 NoSuchMethodException。否则,要反映的方法由下面的算法确定(设 C 为此对象所表示的类):

在 C 中搜索任一匹配的方法。如果找不到匹配的方法,则将在 C 的超类上递归调用第 1 步算法。
如果在第 1 步中没有找到任何方法,则在 C 的超接口中搜索匹配的方法。如果找到了这样的方法,则反映该方法。
在 C 类中查找匹配的方法:如果 C 正好声明了一个具有指定名称的公共方法并且恰恰有相同的形参类型,则它就是反映的方法。如果在 C 中找到了多个这样的方法,并且其中有一个方法的返回类型比其他方法的返回类型都特殊,则反映该方法;否则将从中任选一个方法。
注意,类中可以有多个匹配方法,因为尽管 Java 语言禁止类声明带有相同签名但不同返回类型的多个方法,但 Java 虚拟机并不禁止。这增加了虚拟机的灵活性,可以用来实现各种语言特性。例如,可以使用桥方法 (brige method)实现协变返回;桥方法以及将被重写的方法将具有相同的签名,不同的返回类型。



invoke
public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。

如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。

如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。

如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。


参数:
obj - 从中调用底层方法的对象
args - 用于方法调用的参数
返回:
使用参数 args 在 obj 上指派该对象所表示方法的结果
抛出:
IllegalAccessException - 如果此 Method 对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。
IllegalArgumentException - 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。
InvocationTargetException - 如果底层方法抛出异常。
NullPointerException - 如果指定对象为 null,且该方法是一个实例方法。
ExceptionInInitializerError - 如果由此方法引起的初始化失败。

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 yuon11937 于 2014-4-23 15:54 编辑

getMeethod()中的第一个参数是你要获取的方法的名字,使用字符串表示的,第二个参数是表示方法的形式参数的列表的Class对象的数组列表,比如说你的function方法形参是int型的,这个参数是int.class,为空说明你的function方法参数列表为空。invoke是调用你获取的方法,底层方法是静态的所以第一个参数为null,底层方法的形参是0,所以第二个也可以是null,第二个参数也可以是0.
回复 使用道具 举报
getMeethod()中的第一个参数是你要获取的方法的名字。invoke是调用你获取的方法,第一个参数是对象,由于静态的是没有对象的,所有第一个参数写null
回复 使用道具 举报
两个逗号后面的null都是指你所调用的方法的参数。
对于Method method = clazz.getMethod("function",null);
你想啊,获取method,function是方法名,但是方法可以重载啊,怎么确定你要获取的是哪个叫function的方法呢?必须得把方法签名确定下来吧?所以null就等于说你要取的是无参的function方法。
对于method.invoke(null,null);
现在你调用了这个function方法了,那么是哪个对象调用呢?这就是第一个null的含义。现在没有对象调用方法,说明这是个静态方法可以不加对象,所以第一个是null;第二个就是function方法的参数,因为你这个method是无参的嘛,所以也是null
回复 使用道具 举报
getMethod的API文档如下:
getMethod
public Method getMethod(String name,
                        Class<?>... parameterTypes)
                 throws NoSuchMethodException,
                        SecurityException返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。如果 parameterTypes 为 null,则按空数组处理。

可以看出getMethod第一个参数是一个String类型的噶方法的名字,第二个参数是该方法所获取的参数类型。这是因为方法可以重载,为了区分开来,就只有以该方法获取的参数的不同来区分,而该处获取的参数为null,则说明function是一个无参的方法。

再看看invoke的API文档:
invoke
public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
参数:
obj - 从中调用底层方法的对象
args - 用于方法调用的参数
返回:
使用参数 args 在 obj 上指派该对象所表示方法的结果

可以看到invoke是调用method所获得的方法,第一个参数是调用该方法的对象,而由于该方法是静态的,所以不需要对象,所以是null。invoke的第二个参数是调用function所要传入的参数,由于获取的是function的无参方法,所以第二个变量也是null .

如果该方法不是静态的,则invoke的第一个参数就不会是null,必然有一个对象来调用该方法,而invoke的第二个参数就要看之前getMothod时所获取的方法到底是有参的还是无参的。

评分

参与人数 1技术分 +1 收起 理由
天涯追梦 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马