类的加载:
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,
初始化三步来实现对这个类进行初始化
加载:
就是指将class文件读入内存,并为之创建一个class对象.
任何类被使用时系统都会建立一个class对象
连接:
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化:就是我们以前讲过的初始化步骤
反射:
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法.
对于任意一个对象,都能够调用它的任意一个方法
这种动态获取的以及动态调用对象的方法的功能称为java语音的反射机制.
简单来说,就可以把.class文件比做动物的尸体,而反射技术就是对尸体的一种解剖~!
通过反射技术,我们可以拿到该字节码文件中所有东西,例如成员变量,成员方法,
构造方法还包括私有!
获取字节码文件对象
1:对象名.getClass()
2:类名.class属性
3:Class.forName(“包名.类名”)
获取构造方法
Class的成员方法:
getConstructor(Class…objs) -> Constructor
getConstructors() -> Constructor[]
getDeclaredConstructor(Class...objs) -> Constructor
getDeclaredConstructors() -> Constructor[]
newInstance()-> Object
Constructor成员方法
newInstance(Object...objs) -> Object
获取成员变量
Class的成员方法:
getField(“属性名”) -> Field
getFields() -> Field[]
getDeclaredField("age") -> Field
getDeclaredFields() -> Field[]
Field的成员方法
set(Object obj,Object value)
get(Object obj) -> Object
获取成员方法
Class的成员方法:
getMethod(“方法名”) -> Method
getMethods() -> Method[] 获取自己的以及从父类或父接口中继承/实现过来的public修饰的成员方法对象
getDeclaredMethod("方法名",参数数组) -> Method
getDeclaredMethods() -> Method[] 获取的自己的任意修饰符修饰的成员方法对象
Method的成员方法:
invoke(Object obj,Object...params) -> Object
类名的引用 方法参数类型,没有参数的可以不写
Method的invoke使用时注意事项?
-
如果方法是static,我们怎样调用?
如果方法是静态的,在通过invoke调用时不需要传递对象 -
如果方法的参数是一个数组类型,怎样处理?
反射案例
通过属性对应的setXxx方法来完成操作(一般开发都是采用这种方式)Map<String,Object> map=new HashMap<>();
map.put(“name”, “张三”);
map.put(“age”, 18);
map.put(“sex”, “男”);
map.put(“addr”, “北京”);
//获得User类的Class
Class clazz=User.class;
Object obj = clazz.newInstance();
//获得User类中的方法
Method[] Methods = clazz.getDeclaredMethods();
Set keys = map.keySet();
//遍历key
for (String key : keys) {
//将所有的key前面添加set,与方法的名称来对比
String key1=“set”+String.valueOf(key.charAt(0)).toUpperCase()+key.substring(1);
for (Method method : Methods) {//遍历方法
String name = method.getName();
if(key1.equals(name)){
method.invoke(obj, map.get(key));
}
}
}
System.out.println(obj);