反射的基本概念
反射是一种技术,可以获得类的相关信息
反射技术在框架的实现中经常会被用到。
Class 是类型的模板,Class c = T.class 可以理解为,类的类型的对象,可以描述类的相关信息,如类的名称,访问修饰符,属性等信息。
在创建个对象是会出现异常,需要频繁抛出
1.如何创建class对象。
有三种方式
private static void getClasses() throws ClassNotFoundException {
//1.与类合作创建class对象
Class ca = User.class;
//2.对类进行拆解后,得到对象
User user = new User();
Class cb = user.getClass();
//3.对类的全名进行加载
Class cd = Class.forName("com.demo.clr.bean.User");
System.out.println((ca == cd) +"|"+(ca == cb));//true|true
}
说明:.class文件在内存中只有一个,ca,cb,cd指向同一个地址。
2.通过反射获取类的相关信息
private static void getInfo() {
//创建Class对象
Class cl = User.class;
System.out.println("获取类类型的所属包信息:"+cl.getPackage());
System.out.println("获取类类型的修饰符(在底层为int类型):"+cl.getModifiers());
System.out.println("获取类型的名称:"+cl.getName());
System.out.println("获取类型的简称:"+cl.getSimpleName());
System.out.println("获取类型的签名:"+cl.getSigners());
System.out.println("获取类型的父类:"+cl.getSuperclass());
System.out.println("获取是否为基本数据类型:"+cl.isPrimitive());
}
获取类类型的所属包信息:package com.demo.clr.bean
获取类类型的修饰符(在底层为int类型):1
获取类型的名称:com.demo.clr.bean.User
获取类型的简称:User
获取类型的签名:null
获取类型的父类:class java.lang.Object
获取是否为基本数据类型:false
3.获取字段信息
private static void getFields() throws NoSuchFieldException, IllegalAccessException {
User user = new User();
Class cu = user.getClass();
System.out.println("---------获取指定公开字段----------");
Field u_age = cu.getField("age");
//获取字段信息
System.out.println("修饰符:"+u_age.getModifiers());
System.out.println("字段名:"+u_age.getName());
System.out.println("类型:"+u_age.getType());
/*
* ---------获取指定公开字段----------
修饰符:1
字段名:age
类型:int
* */
System.out.println("--------获取所有公开字段---------");
//用数组接收字段
Field[] fs = cu.getFields();
for (Field f : fs) {
//获取字段信息
System.out.println("修饰符:"+f.getModifiers());
System.out.println("字段名:"+f.getName());
System.out.println("类型:"+f.getType());
}
/*
* --------获取所有公开字段---------
修饰符:1
字段名:age
类型:int*/
System.out.println("------获取非公开指定字段----------");
Field f_uN = cu.getDeclaredField("userName");
System.out.println("修饰符:"+f_uN.getModifiers());
System.out.println("字段名:"+f_uN.getName());
System.out.println("类型:"+f_uN.getType());
/**
* ------获取非公开指定字段----------
* 修饰符:2
* 字段名:userName
* 类型:class java.lang.String
*/
System.out.println("------获取非公开所有字段----------");
Field[] fields = cu.getDeclaredFields();
for (Field fi : fields) {
//获取字段信息
System.out.println("修饰符:"+fi.getModifiers());
System.out.println("字段名:"+fi.getName());
System.out.println("类型:"+fi.getType());
}
/**
* ------获取非公开所有字段----------
* 修饰符:2
* 字段名:userId
* 类型:int
* 修饰符:2
* 字段名:userName
* 类型:class java.lang.String
* 修饰符:2
* 字段名:account
* 类型:class java.lang.String
* 修饰符:2
* 字段名:password
* 类型:class java.lang.String
*/
//获取公共字段的值
System.out.println("age="+u_age.get(user));//age=20
//获取私有字段的值
f_uN.setAccessible(true);
System.out.println("name="+f_uN.get(user));//name=null
f_uN.setAccessible(false);
System.out.println("-------修改公共---------");
u_age.set(user,22);
System.out.println("age="+u_age.get(user));//age=22
System.out.println("---------修改静态公共----------");
Field u_am = cu.getDeclaredField("amount");
u_am.setAccessible(true);
u_am.set(null,2000);//amount=2000.0
System.out.println("amount="+u_am.get(null));
u_am.setAccessible(false);
}
4.获取方法信息
private static void getMethods() throws NoSuchMethodException {
User user = new User();
Class c = user.getClass();
//获取方法
Method method = c.getMethod("add",java.lang.String.class,int.class);
//获取方法信息
System.out.println("方法名:"+method.getName());
System.out.println("方法返回类型"+method.getGenericReturnType());
System.out.println("方法签名:"+method.toGenericString());
System.out.println("方法修饰符:"+method.getModifiers());
/**
* 方法名:add
* 方法返回类型class java.lang.String
* 方法签名:public java.lang.String com.demo.clr.bean.User.add(java.lang.String,int)
* 方法修饰符:1
*/
String addR = (String) method.invoke(user,"a",4);
System.out.println("addr:"+addR);//addr:a4
}
5.获取构造器的相关信息
private static void getConstractors() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取构造器
Class c = User.class;
Constructor constructor = c.getConstructor();
//1.获取实例化对象
User u =(User) constructor.newInstance();
System.out.println(u.add("a",1));//a1
User u2 =(User) c.newInstance();
System.out.println(u2.add("b",1));//b1
}