使用java反射目的:使得代码灵活
如果你想写一个通用的方法,这个方法可以调用任何一个方法
一般方法:
public class Student{
public void say(){
System.out.println("hello world");
}
}
//调用java中任意一个对象的任何一个无参数方法
//这种方法太死板,不灵活
public void test(Object obj,String methodName){
//大概意思相当于
//obj.methodName();
if(obj instanceof Student){
Student s = (Student)obj;
if("say".equals(methodName)){
s.say();
}
if(){}
if(){}
if(){}
}
if(){}
if(){}
}
这方法很累赘,要分很多情况,显然不可取
这时候需要时候java反射机制
学好反射要了解抽象
java中的类都是程序员抽象出来的 学生->Student,老师->Teacher
我们可以将java中class类再次进行抽象
java中Class(注意不是小写的c),我们将class抽象成Class
学生->Student->s(对象) s可以指向任意一个学生
类->Class->c c可以指向任何一个类
每个java类对象,在内存中有且仅有一个对应得Class类型对应的c与之对应
现在我们需要获取Class对象c
现在我们就需要获取Class对象c
获取方法有3种
public class Student{
private String name;
public void say(){
System.out.println("hello world");
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
@SuppressWarnings("all")
public class Test{
public static void main(String args[])throw Exception{
//第一种
Class c1 = Student.class;
System.out.println(c1);
//第二种
Student s = new Student();
Class c2 = s.getClass();
System.out.println(c2);
//第三种(最常用)
//权限定名(包名点上类名)
String str = "com.test.Student"//java.lang.String也可以
Class c3 = Class.forName(str);
System.out.println(c3);
//三种方法都指向同一个对象
System.out.println(c1 == c2);//true
System.out.println(c2 == c3);//true
System.out.println(c1 == c3);//true
//创建对象
String str1 = "com.test.Student";
Class c = Class.forName(str);
Object obj = c.newInstance();//相当于new Student();必须包含无参构造器
//现在可以获取对象,和创建对象
//所有学生 --抽象--> Student s可以带任何一个学生
//java中所有类 --抽象--> Class c可以代表任何一个class
//java中所有方法 --抽象--> Method m可以代表任何一个方法
//可以通过c获取对应的m
//java中使用getMethod(String name,.... )
String methodName = "say";
Method m = c.getMethod(methodName);//可以加参数
System.out.println(m);
//相当于s.say();
Object returnValue = m.invoke(obj);//调用方法
System.out.println(returnValue);//returnValue返回值
}
}
使用java反射优化之后的代码
public class Student{
public void say(){
System.out.println("hello world");
}
}
//使用反射调用
public void test(Object obj,String methodName){
obj.getClass().getMethod(methodName).invoke(obj);
}