java也是一门编译型语言,但凡的是编译型语言,都有着不灵活的一面,不能像js这样的解释性语言的动态化,但是编译型语言都有强大的运行时,而反射就是java的运行时的体现。
下面看一个简单的Demo
public static void printClassMethodMessage(Object obj){
Class s = obj.getClass();
System.out.println(s.getName());
//获取所有的方法数组
Method[] ms = s.getMethods();
for (int i=0;i<ms.length;i++){
//获取该方法的返回值类型
Class returnType = ms[i].getReturnType();
//返回值类型的名字
System.out.print(returnType.getName()+ " ");
//方法名
System.out.print(ms[i].getName()+"(");
//获取该方法所有的参数
Class[] paramTypes = ms[i].getParameterTypes();
for (Class class1: paramTypes ) {
//获取每个参数的类名
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}
最后看一下编译和运行时的差异
public static void main (String[] args) {
//普通数组
ArrayList list = new ArrayList();
//只能保存字符串的数组
ArrayList<String> list1 = new ArrayList<String>();
list1.add("hello");//可以添加
// list1.add(20); //编译错误
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1==c2);
try {
Method m = c2.getMethod("add", Object.class); //利用反射获取数组 add 方法
m.invoke(list1,20); //方法调用
System.out.println(list1.size()); //大小为2
System.out.println(list1);
for (Object ob: list1 ) {
System.out.println(ob); //正常
}
for (String str: list1 ) {
System.out.println(str);// 报错
}
}catch (Exception e){
e.printStackTrace();
}
}
上面的例子说明了,编译时和运行时的差别,运行时是有黑魔法的,它可以绕过编译去进行一些编译器不允许的操作。
反射的使用场景在spring框架是很广泛的,例如AOP面向切面编程和动态代理...