![cfd33138bbf8a023a71915f82b23da96.png](https://img-blog.csdnimg.cn/img_convert/cfd33138bbf8a023a71915f82b23da96.png)
反射机制作用
- 动态的加载类、动态的获取类的信息(属性,方法,构造器)
- 动态构造对象
- 动态调用类和对象的任意方法、构造器
- 动态调用和处理属性
- 获取泛型信息
- 处理注解
获取Class对象的方式有哪些?
1. Class clazz = Class.forName(全限定类名);
2. 类名.class
3. 对象名.getClass();
反射机制动态操作方法_属性_构造器
使用反射机制获取类的名称和属性的方法有哪些?
String getName();获取包名+类名
String getSimpleName();获取类名
Field getField(String fieldName) 得到公共的属性对象
Field getDeclareField(String fieldName) 得到指定名称的属性对象
Field []c.getDeclaredFields() 得到所有的属性对象
使用反射机制获取方法及构造方法的方法有哪些?
Method[] getDeclaredMethods() 得到公共的方法对象
Method[] c.getMethods() 得到父类及本类中的公共的方法对象
Method getDeclaredMethod(String methodName, Class …type)得到指定名称的
本类中公共的方法
Method getMethod(String methodName,Class type)得到本类或父类中的公共的方法
对象
Constructor[] getDeclaredConstructors() 得到公共的构造方法的对象
Constructor [] getConstructors() 得到公共的构造方法对象
Constructor getDeclaredConstructor(Class...type)得到指定参数的公共的构造方法对象
package com.sxt.fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestClass {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
//(1)获取类的名称
Class forName = Class.forName("com.sxt.entity.User");
//2.类名.class
//Class calzz = User.class;
//3.对象名.getClass()
//User user = new User();
//Class clazz = user.getClass();
System.out.println("类的全名称:"+forName.getName());//获取包名+类名
System.out.println("类的名称:"+forName.getSimpleName());//获取类名
//获取父类的
System.out.println("父类的全名称:"+forName.getSuperclass().getName());
System.out.println("父类的名称:"+forName.getSuperclass().getSimpleName());
System.out.println("-------------------------------------");
//(2)获取类的属性
System.out.println("获取类的属性:");
Field field = forName.getField("username");
System.out.println(field);//只能获取公共的属性
Field[] fields = forName.getFields();//只能获取所有公共属性
System.out.println("公共属性值共有:"+fields.length);
for (Field field2 : fields) {
System.out.println(field2);
}
//获取所有属性值
System.out.println("获取所有属性值:");
Field[] field3 = forName.getDeclaredFields();
System.out.println("属性值共有:"+field3.length);
for (Field field4 : field3) {
System.out.println(field4);
}
System.out.println("-------------------------------------");
//获取方法值Method[] getDeclaredMethods() 得到公共的方法对象
System.out.println("得到公共的方法对象:");
Method[] methods = forName.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-------------------------------------");
System.out.println("得到父类的方法对象:");
Method[] methods2 = forName.getMethods();
for (Method method : methods2) {
System.out.println(method);
}
System.out.println("-------------------------------------");
//获取构造器
System.out.println("获取构造器");
Constructor[] constructors = forName.getConstructors();
for (Constructor constructor : constructors) {
Class[] parameterTypes = constructor.getParameterTypes();//获取参数类型
int cMod = constructor.getModifiers();//获取构造器修饰符
String name = forName.getName();//获取名字
System.out.println(cMod+"---"+name+"---"+Arrays.toString(parameterTypes));
System.out.println(constructor);
}
}
}
![b3612761b75e0355c9f79a1353d9f26a.png](https://img-blog.csdnimg.cn/img_convert/b3612761b75e0355c9f79a1353d9f26a.png)
提高反射效率
通过设置setAccessible(true);方法取消安全检查。禁止安全检查,可以提高反射的运行速度
package com.sxt.fanshe;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 提高效率setAccessible(true);禁用安全检查,可以提高运行速度
* @date 2019年8月8日
*/
public class Test3 {
public static void test01(){
Object obj = new Object();
long startTime = System.currentTimeMillis();//设置开始时间
for (int i = 0; i < 1000000000; i++) {
obj.hashCode();
}
long endTime = System.currentTimeMillis();//设置结束时间
System.out.println("调用普通方法执行10亿次时间:"+(endTime-startTime)+"ms");
}
public static void test02() throws Exception{
Object obj = new Object();
Class clazz = obj.getClass();
//获取hashcode方法
Method method = clazz.getDeclaredMethod("hashCode", null);
long startTime = System.currentTimeMillis();//设置开始时间
for (int i = 0; i < 1000000000; i++) {
// obj.hashCode();
method.invoke(obj);
}
long endTime = System.currentTimeMillis();//设置结束时间
System.out.println("调用反射回调方法执行10亿次时间:"+(endTime-startTime)+"ms");
}
public static void test03() throws Exception{
Object obj = new Object();
Class clazz = obj.getClass();
//获取hashcode方法
Method method = clazz.getDeclaredMethod("hashCode", null);
method.setAccessible(true);//设置是否取消安全检查
long startTime = System.currentTimeMillis();//设置开始时间
for (int i = 0; i < 1000000000; i++) {
// obj.hashCode();
method.invoke(obj);
}
long endTime = System.currentTimeMillis();//设置结束时间
System.out.println("调用优化后反射回调方法执行10亿次时间:"+(endTime-startTime)+"ms");
}
public static void main(String[] args) throws Exception {
test01();
test02();
test03();
}
}
![66ece2d24f8e01806e21dc62b6f6f9d1.png](https://img-blog.csdnimg.cn/img_convert/66ece2d24f8e01806e21dc62b6f6f9d1.png)
反射操作泛型
Java 中的泛型仅仅是给编译器 javac 使用的,确保数据的安全性和免去强制类型转换的麻烦,但是一旦编译完成,所有与泛型有关的类型全部擦除。
使用泛型直接读取泛型,是读取不到的,因为反射是操作加载以后的类的。
package com.sxt.fanshe;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import com.sxt.entity.User;
public class TestGeneric {
public void test01(Map<String,User> map,List<User> list,String s){
System.out.println("TestGeneric.test01()");
}
public Map<Integer,User> test02(){
System.out.println("TestGeneric.test02()");
return null;
}
public String test03(){
System.out.println("TestGeneric.test03()");
return null;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
//获取test01方法的泛型参数信息
Class c=TestGeneric.class;
Method test01=c.getMethod("test01", Map.class,List.class,String.class);
//获取带泛型参数的类型
Type [] tytes=test01.getGenericParameterTypes();
System.out.println(tytes.length);
for (Type type : tytes) {
//System.out.println("#"+type);
if (type instanceof ParameterizedType) {
Type[] genericType= ((ParameterizedType) type).getActualTypeArguments();
//遍历每一个泛型参数中泛型的类型
for (Type genType : genericType) {
System.out.println("泛型类型:"+genType);
}
System.out.println("n--------------------------");
}
}
System.out.println("n----------------------------n");
//获取test02方法返回值的泛型信息
Method m2=c.getMethod("test02", null);
Type returnType=m2.getGenericReturnType();
//判断是否带有泛型
if(returnType instanceof ParameterizedType){
Type [] types=((ParameterizedType) returnType).getActualTypeArguments();
for (Type type : types) {
System.out.println("返回值的泛型类型:"+type);
}
}
System.out.println("n------------------------------n");
Method m3=c.getMethod("test03", null);
Type returnType3=m3.getGenericReturnType();
//System.out.println(returnType3);
System.out.println(returnType3 instanceof ParameterizedType);
}
}
![9b2aaa63550cc5eb675648ec0652d778.png](https://img-blog.csdnimg.cn/img_convert/9b2aaa63550cc5eb675648ec0652d778.png)