引入
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载
就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化
- 创建类的实例
- 类的静态变量,或者为静态变量赋值
- 类的静态方法
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
概述
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
使用
定义Bean类:
public class Person {
private String name;
public static String country = "中国";
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
"country='" + country + '\''+
'}';
}
private Person(String name,long i){
this.name = name;
}
public Person(){}
public Person(String name) {
this.name = name;
}
public Person(String name,int age ){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(String s){
System.out.println(this.name + "正在吃"+s);
}
private String study(String s){
System.out.println("学习" + s);
return "OK";
}
}
获取反射对象,Class对象
public static void main(String[] args) throws ClassNotFoundException {
//类加载的时候加载Class对象
//Class对象是类的说明书 ==>属性,方法,构造函数,注解
//获取反射对象,Class对象
//1.通过类获取
Class c = Person.class;
//2.通过对象的getClass()方法获取
Person p = new Person("小王");
Class c1 = p.getClass();
//3.通过类名称获取,全名称,全路径(重点)
Class c = Class.forName("cn.entity.Person");
}
获取构造函数
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = Class.forName("cn.entity.Person");
//反射获取构造函数
//1.getConstructor只能用于获取共有的构造函数
//1.getDeclaredConstructor用于获取私有的构造函数
//Person(String name)
//Constructor con =c.getConstructor(String.class);
//Person(String name,int age)
Constructor con =c.getConstructor(String.class,int.class);
//有了构造器就可以实例化
//Object o = con.newInstance("小王");
Object o = con.newInstance("xiaowang",20);
//调用者是Class反射对象 ,没有任何的参数 ,调用的是缺省的构造函数
Object o1 = c.newInstance();
//获取私有的构造器
Constructor con1 =c.getDeclaredConstructor(String.class,long.class);
//开放私有权限
con1.setAccessible(true);
//实例化
Object o2 = con1.newInstance("xiaowang",10l);
System.out.println(o2);
}
反射获取方法
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InstantiationException, InvocationTargetException {
Class c = Class.forName("cn.entity.Person");
//反射获取方法
//A.获取共有方法getMethod
Method m = c.getMethod("eat", String.class);
//调用方法
//1.得到对象
Object o = c.newInstance();
//2.反射调用方法
m.invoke(o,"苹果");
//B.获取私有方法getDeclaredMethod
Method m1 = c.getDeclaredMethod("study", String.class);
//开放权限
m1.setAccessible(true);
//反射调用
Object result = m1.invoke(o,"语文");
System.out.println(result);
}
获取属性
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException,IllegalAccessException, InstantiationException {
Class c = Class.forName("cn.entity.Person");
//A.反射获取共有属性
Field f = c.getField("country");
//1.得到对象
Object o = c.newInstance();
//2.反射获取属性
Object ss = f.get(o);
//3.反射设置属性
f.set(o,"美国");
System.out.println(ss);
//B.反射获取私有属性
Field f1 = c.getDeclaredField("name");
//开放权限
f1.setAccessible(true);
Object sss = f1.get(o);
System.out.println(sss);
System.out.println(o);
}
获取注解
public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException, NoSuchMethodException {
//1.反射获取类的注解
Class c = Class.forName("cn.entity.Person");
//反射中的注解对象
//Annotation a = c.getAnnotation(SuppressWarnings.class);
//获取类的所有注解
Annotation[] arr = c.getAnnotations();
System.out.println(arr.length);
//反射获取属性的注解
Field f =c.getDeclaredField("name");
f.setAccessible(true);
Annotation[] arr1 = f.getAnnotations();
System.out.println(Arrays.toString(arr1));
//反射获取方法的注解
Method m =c.getMethod("toString");
Annotation[] arr2 = m.getAnnotations();
System.out.println(Arrays.toString(arr2));
}