反射获取成员方法并使用1
我们学习一下Class类里面的如下方法
| 方法 | 作用 |
|---|---|
| method[] getMethods() | 返回所有公共成员方法对象的数组,包括继承的 |
| method[] getDeclaredMethods() | 返回所有成员方法对象的数组,不包括继承的 |
| method getMethod(String name, 类<?>... parameterTypes) | 返回单个公共成员方法对象 |
| method getDeclaredMethod(String name, 类<?>... parameterTypes) | 返回单个成员方法对象 |
我们还要学习一下Method类,该类在java.lang.reflect包下,该类被final修饰即该类是最终类,该类在类或接口上提供有关单个方法的信息和访问权限 我们来学习一下Method类里面的如下方法
| 方法 | 作用 |
|---|---|
| Object invoke(Object obj, Object... args) | 调用obj对象的成员方法,参数是args,返回值是Object类型 |
反射获取成员方法并使用1的练习
xxxxxxxxxxpackage ch27;
public class a_10_1Student {
//成员变量:私有、默认、公共 private String name; int age; public String address;
//公共构造方法,这里的这个也叫无参构造方法 public a_10_1Student() { } //私有构造方法 private a_10_1Student(String name) { this.name = name; } //默认构造方法 a_10_1Student(String name, int age) { this.name = name; this.age = age; } //公共构造方法 public a_10_1Student(String name, int age, String address) { this.name = name; this.age = age; this.address = address; }
//私有成员方法 private void function(){ System.out.println("function"); } //4个公共成员方法 public void method1(){ System.out.println("method-我在学生类里面哦"); } public void method2(String s){ System.out.println("method:"+s); } public String method3(String s,int i){ return s + "," + i; }
//重写的toString方法也是公共成员方法 public String toString() { return "a_4_1Student{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; }
}xxxxxxxxxxpackage ch27;
import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;
public class a_10_2测试 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取学生类的Class对象 Class<?> c = Class.forName("ch27.a_10_1Student");
//------------------------------------------------------------------------------------------------------
//使用上面的Class对象c来调用Class类的方法,获取学生类的公共成员方法 Method[] methods = c.getMethods();//右边返回的是数组 //遍历拿到的数组 for(Method method : methods){ System.out.println(method); } //注意上面的getMethods方法拿的不止是学生类的全部公共成员方法,还有跟学生类有关的其他地方的公共成员方法
System.out.println("----------------↑↑↑获取学生类的及继承自父类的所有公共成员方法----------------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//如何获取学生类里面的私有方法 Method[] methods2 = c.getDeclaredMethods();//右边返回的是数组 //遍历拿到的数组 for(Method method : methods2){ System.out.println(method); } System.out.println("-----------------↑↑↑获取学生类的所有成员方法,不包含继承的------------------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//如何获取学生类里面的某一个私有方法。这一小部分里面有很多反射知识,好好理解学透哦 Method m = c.getMethod("method1");//由于学生类的method1成员方法没有参数,所以这行的getMethod的第二个参数可省略 //拿到了学生类的method1的成员方法对象m。然后是获取无参构造方法创建对象,如下 Constructor<?> con = c.getConstructor();//getConstructor获取构造器 Object obj = con.newInstance();//newInstance创建对象 //使用method类里面的invoke方法 m.invoke(obj);//由于我们39行拿的method1在学生类里是无参的,所以这行的invoke方法的第二个参数可省略 //上面那行实际上就是调用了学生类里面的method1方法,我们在学生类里面的method1方法里面是有写输出语句的,如下 //输出method-我在学生类里面哦 System.out.println("----------------↑↑↑获取学生类的某个成员方法--------------------"); System.out.println(); //------------------------------------------------------------------------------------------------------
}}
反射获取成员方法并使用2
练习:通过反射实现如下操作 1、Student s = new Student(); 2、s.method1(); 3、s.method2("张三"); 4、String ss = s.method3("李四",18); 5、System.out.println(ss); 6、s.function();
反射获取成员方法并使用2的练习
xxxxxxxxxxpackage ch27;
public class a_11_1Student {
//成员变量:私有、默认、公共 private String name; int age; public String address;
//公共构造方法,这里的这个也叫无参构造方法 public a_11_1Student() { } //私有构造方法 private a_11_1Student(String name) { this.name = name; } //默认构造方法 a_11_1Student(String name, int age) { this.name = name; this.age = age; } //公共构造方法 public a_11_1Student(String name, int age, String address) { this.name = name; this.age = age; this.address = address; }
//私有成员方法 private void function(){ System.out.println("function-我是私有的成员方法呀"); } //4个公共成员方法 public void method1(){ System.out.println("method-我在学生类里面哦"); } public void method2(String s){ System.out.println("method:"+s); } public String method3(String s,int i){ return s + "," + i; }
//重写的toString方法也是公共成员方法 public String toString() { return "a_4_1Student{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; }
}xxxxxxxxxxpackage ch27;
import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;
public class a_11_2测试 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取学生类的Class对象 Class<?> c = Class.forName("ch27.a_11_1Student");
//-----------------------------------------------------------------------------------------------------
//【1、Student s = new Student();】 //通过无参构造方法来创建学生类的对象 Constructor<?> con = c.getConstructor();//getConstructor获取构造器 Object obj = con.newInstance();//newInstance创建对象 System.out.println(obj);
System.out.println("-------------上面的是通过反射来获取学生类的对象--------------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//【2、s.method1();】 Method m1 = c.getMethod("method1");//获取学生类里面的method1的成员方法 m1.invoke(obj); //上面那一行就相当于调用了学生类里面的method1的成员方法,输出学生类里面method1成员方法的内容
System.out.println("------------上面的是通过反射来调用学生类里面的method1无参的成员方法------------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//【3、s.method2("张三");】 Method m2 = c.getMethod("method2", String.class); //上面那行由于在学生类中的method2是带1个参的,所以这行的getMethod方法就需要写共二个参数 m2.invoke(obj,"张三"); //上面那一行就相当于调用了学生类里面的method2的成员方法,输出学生类里面method2成员方法的内容
System.out.println("-------------上面的是通过反射来调用学生类里面的method2带参的成员方法-----------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//【4、String ss = s.method3("张三",18);】 Method m3 = c.getMethod("method3", String.class, int.class); //上面那行由于在学生类中的method2是带2个参的,所以这行的getMethod方法就需要写共三个参数 Object o = m3.invoke(obj, "李四", 18);//由于学生类里面的method3方法是有返回值的,所以这行我们需要在左边接收一下返回值 System.out.println(o);
System.out.println("--------上面的是通过反射来调用学生类里面的method3带2个参带返回值的成员方法-------"); System.out.println(); //------------------------------------------------------------------------------------------------------
//【5、s.function();】 //Method m4 = c.getMethod("function");//注意function方法在学生类里面是私有成员方法 //m4.invoke(obj); //上面的两行报错(先注释,需要自行解开),无法调用学生类里面的function方法。原因:getMethod方法只能获取公共成员方法,不能获取到私有成员方法。解决如下 Method m5 = c.getDeclaredMethod("function"); m5.setAccessible(true);//暴力反射,在使用getDeclaredMethod方法后,必须在下一行使用暴力反射,最后就可以调用学生类里面的所有成员方法,调用如下 m5.invoke(obj); //总结:如果是调用私有成员方法,在获取时就使用getDeclaredMethod方法且使用暴力反射; getMethod方法是获取公共成员方法的 //对于这一小部分,我们可以知道在不确定成员方法是公共还是私有的情况下,我们最好就使用getDeclaredMethod来获取,且必须接着使用暴力反射
System.out.println("------上面的是通过反射来调用学生类里面的function不带参不带返回值的私有成员方法-----"); System.out.println();
}
}