一、Method
- Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
- 所反映的方法可能是类方法或实例方法(包括抽象方法)。
- Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;
- 但如果要进行收缩转换,则会抛出 IllegalArgumentException。
二、常用方法
public final class Method extends AccessibleObject implements GenericDeclaration, Member
{
//按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。
public Class<?>[] getParameterTypes(){}
//以 String 形式返回此 Method 对象表示的方法名称
public String getName(){}
//返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型
public Class<?> getReturnType(){}
/**
* 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法
* 个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
* 如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null
*/
public Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException{}
}
三、示例
- Method类代表某个类中的一个成员方法
- 得到类中的某一个方法
- 例子: Method charAt = Class.forName(“java.lang.String”).getMethod(“charAt”,int.class)
- 调用方法
- 通常方式:System.out.println(str.charAt(1));
- 反射方式:System.out.println(charAt.invoke(str,1));
- Jdk1.4和jdk1.5的invoke方法的区别
- Jdk1.5:public Object invoke(Object obj,Object... args)
- Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法需要将一个数组作为参数传递给invoke方法
package day23;
import java.lang.reflect.*;
/**
* 写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法
*/
public class ReflectDemo {
public static void main(String[] args) throws Exception
{
String className = "day23.ArgumentTest";
print(className);
}
private static void print(String className) throws Exception {
Method mainMethod = Class.forName(className).getMethod("main", String[].class);
//wrong number of arguments运行时会出现参数个数不对的异常
//mainMethod.invoke(null, new String[]{"zhangsan","lisi","wangwu"});
//解决办法
mainMethod.invoke(null, (Object)new String[]{"zhangsan","lisi","wangwu"});
}
}
class ArgumentTest
{
public static void main(String[] args)
{
for(String str : args)
System.out.println(str);
}
}
- 在上述例子中,启动java程序的main方法的参数是一个字符串数组,
- 即public static void main(String[]args),
- 通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?
- 按jdk1.5的语法,整个数组是一个参数,
- 而按jdk1.4的语法,数组中的每个元素对应一个参数,
- 当把一个字符串数组作为参数传递给invoke方法时,
- javac会到底按照哪种语法进行处理呢?
- jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散称为若干个单独的参数,
- 所以在main方法传递参数时,不能使用代码mainMethod.invoke(null,new String(“aaa”,”dddd”,”sss”)),
- javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现wrong number of arguments
- 解决办法:
- mainMethod.invoke(null,new Object[](new String[]{‘’’’’’}
- 或者mainMethod.invoke(null,(Object)new String[]{‘’’’’’’’’’})