一:泛型获得类、属性、方法、构造类、注解
获得Class对象的三种方法
//方式一
Class clazz = Class.forName(“com.xxxx.student”):
//方式二
Class clazzs = String.class;
//方式三
String string = new String("abc");
Class clazz = string.getClass();
clazz.getName();//获得包名字+类名
clazz.getSimpleName();//获得类名
获得属性
//获得public Field(只获得本类的,不会获得父类的)
Field[] fields = clazz.getFields();
//获得所有 Field(本类和父类的)
Field[] declaredFields = clazz.getDeclaredFields();
//获得名字为name 且是public修饰的字段
Field field = clazz.getDeclaredField("name");
//获得名字为name的字段
Field declaredfield = clazz.getDeclaredField("name");
获得方法
//获得当前类以及父类的public修饰 的方法
Method[] methods = clazz.getMethods();
//获得的所有方法 (只获得本类,不包括父类的)
Method[] declaredMethods = clazz.getDeclaredMethods();
//获得public 修饰的指定名字的方法
Method getMethod = clazz.getMethod("getName");
//获得public 修饰的指定名字的方法 方法有参数必须传递参数类型对应的class对象
Method setMethod = clazz.getMethod("setName",String.class);
获得构造器
//获得public 修饰的构造方法(只获得当前类的)
Constructor[] constructors = clazz.getConstructors();
//获得 所有的构造方法(只获得当前类的)
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
//获得无参的构造方法
Constructor constructor = clazz.getConstructor();
//获得传入指定参数的构造方法
Constructor constructor2 = clazz.getConstructor(String.class,String.class);
获得注解
http://wangshirufeng.iteye.com/admin/blogs/2285263
二:通过反射API调用构造方法、属性、普通方法
通过反射API调用构造方法
Constructor constructor2 = clazz.getConstructor(String.class,String.class);
User user2 = (User)constructor2.newInstance("zhangsan","21");
通过反射API调用普通方法
Method method = clazz.getDeclaredMethod("setName",String.class);
method.invoke(user2,"lisi");
//上面两行代码等价于user2.setName("lisi");
通过反射API调用属性
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);//忽略安全检查
field.set(user2,"wangwu");
注意:反射机制的效率问题,忽略安全检查后能够提升效率,频繁调用反射的地方注意下。
//做法一: 普通调用 10亿次耗时 1344毫秒
user2.getName();
//做法二:反射调用 10亿次耗时 3800毫秒
method.invoke(user2);
//做法三:忽略安全检查的反射调用 2812毫秒
setAccessible(true);
method.invoke(user2);
三:通过反射操作泛型
反射操作类的泛型参数
Class clazz2 = UserAction.class;
//获得带有泛型的父类的类型
Type parentClass = clazz2.getGenericSuperclass();
//将类型强转为参数化类型,然后获得实际的泛型参数类型数组
Type[] argumentsType = ((ParameterizedType)parentClass).getActualTypeArguments();
for(Type type:argumentsType){
System.out.println("type="+type);
}
反射操作方法的参数的泛型类型
Method method = clazz2.getMethod("setUserList",List.class,Map.class,Person.class);
//获得方法的带泛型的参数类型数组
Type[] parameterTypes = method.getGenericParameterTypes();
//是否是参数类型
//parameterTypes[0] instanceof ParameterizedType;
反射操作方法的返回值泛型类型
//获得方法的返回值类型
Type returnTypes = method.getGenericReturnType();