这两天研究AOP,上一篇的动态代理模式就是AOP底层实现的一种方式,而动态代理的实现就是依靠类反射来实现,今天顺便复习下类反射把
直接上代码,一些注意的东西、区别啥的都写在了注释里了~这边只例举了大部分常用的方法,还有一些什么通过类反射来获得Annotation啥的就不试了,反正在eclipse里打个.点全出来了 ヾ(o◕∀◕)ノヾ
package cn.com.classReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
/**
* Class对象
*/
//获得class对象
Son s = new Son() ;
//第一钟方法 全类名获取,用的最多
Class clazz = Class.forName("cn.com.classReflect.Son") ;
//第二种
Class clazz2 = s.getClass() ;
System.out.println(clazz == clazz2);//打印true
//第三种
Class clazz3 = Son.class ;
System.out.println(clazz2 == clazz3);//打印true
/**
* 利用Class类的newInstance()来获得类的实例
* 这边能使用==不报错,但是结果为false,两个对象指向不同的地址空间
* 那么这2个有啥区别呢?
* newInstance是JVM根据classLoader动态加载,类在加载的时候会调用
* 他的无参构造方法,只有在运行的时候才会去new,才会知道类的全路径,返回类的对象,遍历
* 类的属性、方法,属于动态编译
* 而new出的对象是在编译的时候就给类创建实例,分配内存空间,进行初始化,静态编译
*
* 需要注意的是:System.out.println(clazz == s)这种写法会编译报错
* 上述的三种方式获得的可不是类的实例,而是类,一个完全一样的、通过‘照镜子’而来
* 的类
*
* newInstance在运行时调用的是无参构造方法
*
* newInstance这种编译方式的可拓展性、速度优势、节省资源等特性据定了
* 他在Spring等中有着不可替代的作用
*/
System.out.println(clazz.newInstance() == s ) ;//打印False
System.out.println("---------我是凑表脸长长的分割线----------");
// 通过反射对象获得包名
System.out.println("获得包名:"+clazz.getPackage());
System.out.println("---------我是凑表脸长长的分割线----------");
// 通过类反射获得类的权限修饰符
System.out.println("获得类的权限修饰符"+Modifier.toString(clazz.getModifiers()));
System.out.println("---------我是凑表脸长长的分割线----------");
// 判断类是不是一个接口
if(clazz.isInterface()){
System.out.println("clazz对象是接口");
} else {
System.out.println("clazz对象是类");
}
System.out.println("---------我是凑表脸长长的分割线----------");
// 获得类的名
System.out.println(clazz.getSimpleName());
System.out.println("---------我是凑表脸长长的分割线----------");
// 获得类的全限定名
System.out.println(clazz.getName());
System.out.println("---------我是凑表脸长长的分割线----------");
// 获得父类的类名
System.out.println(clazz.getSuperclass().getSimpleName());
System.out.println("---------我是凑表脸长长的分割线----------");
// 字段属性
for (Field f : clazz.getDeclaredFields()) {//getFields·µ»Ø¹²ÓеÄÊôÐÔ
//获得字段的修饰符
System.out.print(Modifier.toString(f.getModifiers()) + " ");
//获得字段的数据类型
System.out.print(f.getType().getSimpleName() + " ");
//获得字段的名字
System.out.println(f.getName() + ";");
}
System.out.println("---------我是凑表脸长长的分割线----------");
// Contructor构造方法
for (Constructor c : clazz.getConstructors()) {
System.out.println("类的构造方法的权限修饰符"+Modifier.toString(c.getModifiers()) + " ");
System.out.println("获得构造方法的全限定名:"+c.getName());
}
System.out.println("---------我是凑表脸长长的分割线----------");
/**
* Method
*/
//获得Method数组:
Method[] methods = clazz.getDeclaredMethods() ;
System.out.println("一共有:"+methods.length+"个方法");
for(Method m : methods){
System.out.print(m.getName()+" ");
}
}
}