Java学习自我总结——反射基础
Java反射基础
反射的意义:在不了解类结构,或者没有实例对象,或者类无法实例化的情况下动态的调用类方法(非静态方法)。
首先,准备一个Student类,
package chap07.sec2;
public class Student {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}}
类chap09.sec2.ReflectionTest2,
通过Class.forName获得类对象,通过强制转换成chap07.sec2.Student中Student对象,因为两个类在不同的package中,在强制转换的过程中自动导包。在取得对象的情况下调用setId(intid)&getId()两个方法,调用这两个方法的前提是:1.导包,并进行了强制转换;2.明确了解Student类的成员函数(实际上就是不满足“不了解类结构”这个条件,因为你其实已经明确的知道,Student类中存在这两个方法以及他们各自的方法参数);
public class ReflectionTest2 {
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("chap07.sec2.Student");
Student student = (Student) clazz.newInstance();
student.setId(5);
student.getId();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
类chap09.sec2.ReflectionTest,
仍然通过Class.forName获得类对象,注意:类对象的newInstance()方法生成的是一个Object的对象!因为不了解类结构,甚至不知道类的名字等等信息,通过getMethods()方法获得Method的对象method,method的getParameterTypes()方法获得该方法的参数类型(因为是测试,下图没有体现出来使用了method的getParameterTypes()方法),这时候使用invoke()来调用类的方法。
public class ReflectionTest {
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("chap07.sec2.Student");
Object object = clazz.newInstance();
Method[] methods = clazz.getMethods();
Method method1 = null;
Method method2 = null;
for (Method method : methods) {
if (method.getName().equals("setId")) {
method1 = method;
}
if (method.getName().equals("getId")) {
method2 = method;
}
}
//省略了getParameterTypes()的过程
method1.invoke(object, 5);
System.out.println(method2.invoke(object, new Object[0]));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Q&A
Q:我已经获得了实例对象,为什么不能用 . 直接调用方法,还需要invoke?
A:首先,1.我们可能并不了解类,没有办法做强制转换,而object显然是没有办法调用具体类的具体方法的;2.反射的目的是为了增加程序的通用性,我们可能对Student,Teacher,Manager等等一系列得类做类似上面代码中set和get的方法,如果每有一个新类我们就写一个新的强制转换,这样的程序代码重复率太高了。
上一篇: JAVA基础编程练习自我总结
下一篇: mybatis返回一个map集合