java笔记(6) --反射中的方法调用

时间:2023-01-13 09:40:29


/**
 * 
 * Method类用于描述类中的方法: Method getMethod(String name, Class<?> ... parameterTypes)
 * 返回该Class对象表示类和其父类的指定的public方法; Method[] getMethods():
 * 返回该Class对象表示类和其父类的所有public方法; Method getDeclaredMethod(String name,
 * Class<?>... parameterTypes) 返回该Class对象表示类的指定的方法。和访问权限无关,但不包括继承的方法; Method[]
 * getDeclaredMethods(): 获得类所有的方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法;
 * 
 * 
 * 
 */




package cn.com.java.wwh.www;



import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


/**
 * @类的作用:用于练习反射方法的调用
 * 
 * 
 * @author 一叶扁舟
 * @version 1.0
 * @创建时间: 2014-2-12 下午4:11:32
 * 
 */


class Person {

public void sayHello1() {
System.out.println("你好!");
}


public static String sayHello2() {
return "一叶扁舟";
}


private String sayHello3(String name, int age) {
System.out.println(name + "---->" + age);
return name + age;
}


// 采用泛型处理
public List sayHello4(String name, int age) {
List list = new ArrayList();
list.add(name);
list.add(age);
return list;
}




public String[] sayHello5(String name, int age) {
return new String[] { name, age + "" };
}
}


public class ReflectDemo {


public static void main(String[] args) throws Exception {
// 使用反射调用Person里的sayHello方法
/**
* 1.得到方法所在类的字节码;-----> Class对象
* 2.获取sayHello方法; ------->  Method对象
* 3.执行Method所表示的方法(sayHello);
*/
// 获得类的字节码
Class<Person> claz = Person.class;
Method meth = claz.getMethod("sayHello2");
/**
* Object invoke(Object obj, Object... args) 对带有指定参数的指定对象调用由此 Method
* 对象表示的底层方法。

* 参数: obj - 调用底层方法所属对象,这里的sayHello就是底层方法,obj就应该是sayHello所在类的一个对象; args
* -底层方法调用需要的实际参数 返回: 访问底层方法的执行结果;


* 如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
*/


Object obj = meth.invoke(claz.newInstance());// 静态和非静态的都可以
Object obj1 = meth.invoke(null);// 静态的
System.out.println(obj1);


meth = claz.getDeclaredMethod("sayHello3", String.class, int.class);
System.out.println(meth);
// 调用之前可以设置为可以访问
meth.setAccessible(true);
// 传入的参数
Object obj2 = meth.invoke(claz.newInstance(), "福建师范大学", 22);
System.out.println(obj2);
// 用泛型处理
Method meth2 = claz.getMethod("sayHello4", String.class, int.class);


Object obj3 = meth2.invoke(claz.newInstance(), "一叶扁舟", 30);
System.out.println(obj3);
List list = (List) obj3;
System.out.println(obj3);
System.out.println(list.get(0));


// 方法练习五
// 这个方法必须是public,否则调用时会出现异常
Method meth5 = claz.getMethod("sayHello5", String.class, int.class);
Object obj5 = meth5.invoke(claz.newInstance(), "无悔", 22);
String[] array = (String[]) obj5;
System.out.println(meth5);
System.out.println(array[0]);
/**
* Array: static Object get(Object array, int index) 返回指定数组对象中索引的值。

* static int getLength(Object array) 以 int 形式返回指定数组对象的长度。


* static void set(Object array, int index, Object value)
* 将指定数组对象中索引组件的值设置为指定的新值。
*/
Array.set(array, 0, "哈哈");
Array.set(array, 1, "18");
// System.out.println(Array.get(array, 0));
// System.out.println(Array.get(array, 1));
// 获取array数组中的长度
int number = Array.getLength(array);
System.out.println("array数组的长度是:" + number);
for (int i = 0; i < number; i++) {
System.out.println(Array.get(array, i));
}
// 无参的方法
// 如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

Method me = claz.getMethod("sayHello1");
me.invoke(claz.newInstance());//正确
me.invoke(claz.newInstance(),null);//正确
me.invoke(claz.newInstance(), new Object[]{});//正确


Method met = claz.getDeclaredMethod("sayHello3",String.class, int.class);
// 设置可访问
met.setAccessible(true);
met.invoke(claz.newInstance(),"一叶扁舟&&无悔",22);
met.invoke(claz.newInstance(), "Yiyepianzhou",22);
met.invoke(claz.newInstance(), new Object[]{"呵呵",20});
}
}