反射的三种实现方式
1.通过 new 关键字获取javaBean实例,通过实例获取到Class对象。new 关键字会产生一个Student对象,一个Class对象
Persone stu = new Persone();
Class per1= stu.getClass();
2.通过类获取Class对象
Class per2= Student.class;
3.通过类路径(包名+类名)获取Class对象
Class per3= Class.forName("com.guhui.webserver.Persone")
备注:在运行期间,一个类,只有一个Class对象产生。可以通过==判断对象的引用是否相等
System.out.println(per1 == per3);
获取构造方法
1.获取所有公有构造方法
Constructor[] conArray = clazz.getConstructors();
2.获取所有构造方法(包括:私有、受保护、默认、公有)
Constructor[] conArray = clazz.getDeclaredConstructors();
3.获取公有、无参的构造方法
3.1因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
3.2返回的是描述这个无参构造函数的类对象。
Constructor con = clazz.getConstructor(null);
4.获取私有构造方法
Constructor con = clazz.getDeclaredConstructor(int.class);
方法注明调用参数类型
获取类成员变量
1.获取所有公有的字段
Field[] fieldArray = clazz.getFields();
2.获取所有的字段(包括私有、受保护、默认的)
Field[] fieldArray = clazz.getDeclaredFields();
3.获取公有字段,并调用
Field f = clazz.getField("name");
Object obj = clazz.getConstructor().newInstance();
//为字段设置值
f.set(obj, "张家辉");
//验证
Persone stu = (Persone) obj;
System.out.println("验证姓名:" + stu.getName());
4.获取私有字段,并调用
Field f = clazz.getDeclaredField("phoneNum");
Object obj = clazz.getConstructor().newInstance();
//暴力反射,解除私有限定
f.setAccessible(true);
f.set(obj, "18888889999");
Persone stu = (Persone) obj;
System.out.println("验证电话:" + stu.getPhoneNum());
获取成员方法
1.获取所有的公有方法
Method[] methodArray = clazz.getMethods();
2.获取所有的方法包括私有方法
Method[] methodArray = clazz.getDeclaredMethods();
3.获取公有的show1(String name)方法
Method m = clazz.getMethod("show1", String.class);
Object obj = clazz.getConstructor().newInstance();
m.invoke(obj, "张家辉");
4.获取私有的Object show4(Integer age)方法
Method m = clazz.getDeclaredMethod("show4", int.class);
m.setAccessible(true);//解除私有限定
Object obj = clazz.getConstructor().newInstance();
Object result = m.invoke(obj, 20);
通过反射越过泛型检查
List<String> list = new ArrayList<>();
list.add("gu");
list.add("hui");
Class clz = list.getClass();
Method method = clz.getMethod("add",Object.class);
method.invoke(list,500);
method.invoke(list,new Double(5.5));
for (Object o : list) {
System.out.println(o);
}
通过反射拿到泛型
- 拿到方法参数泛型类型
public void reflectTest1(Map<String,Persone> map, List<Persone> list){
System.out.println("ReflectTest.reflectTest1()");
}
public void test7(){
Class clz = Persone.class;
try {
Method reflectTest1 = clz.getMethod("reflectTest1", Map.class, List.class);
Type[] genericParameterTypes = reflectTest1.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("#"+genericParameterType.getTypeName());
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("泛型类型:"+actualTypeArgument.getTypeName());
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
- 拿到方法返回类型泛型
public Map<Integer,Persone> reflectTest2() throws NoSuchMethodException {
return null;
}
public void test8(){
Class clz = Persone.class;
try {
Method reflectTest1 = clz.getMethod("reflectTest2", null);
Type genericReturnType = reflectTest1.getGenericReturnType();
System.out.println("#:"+genericReturnType.getTypeName());
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("泛型类型:"+actualTypeArgument.getTypeName());
}
}
}catch (NoSuchMethodException e){
e.printStackTrace();
}
}
- 拿到方法抛出异常类型
public Map<Integer,Persone> reflectTest2() throws NoSuchMethodException {
return null;
}
public void test9(){
Class clz = Persone.class;
try {
Method reflectTest1 = clz.getMethod("reflectTest2");
Type[] genericReturnType = reflectTest1.getGenericExceptionTypes();
for (Type type : genericReturnType) {
System.out.println("#:"+type.getTypeName());
}
}catch (NoSuchMethodException e){
e.printStackTrace();
}
}