反射获取成员方法并使用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的练习
xxxxxxxxxx
package 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 + '\'' +
'}';
}
}
xxxxxxxxxx
package 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的练习
xxxxxxxxxx
package 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 + '\'' +
'}';
}
}
xxxxxxxxxx
package 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();
}
}