反射
机制:使用一个类时,会启动类加载器把class文件加载到内存中的方法区中,并为class文件创建一个对象,我们可以使用这个对象获取class文件中的成员变量,方法(私有的也能获取)(获取的过程称为解剖)
获取class对象的三种方式
这三种方式获取的都是同一个class对象
Person p = new Person();
Class c1 = p.getClass();
Class c2 = Person.class;
//这是通过静态方法获取,获取的时候会执行类中的静态代码块,需要抛出ClassNotFoundException
Class c3 = Class.forName("类名+包名"); //在类中选择类名,右键Copy Reference可获取
通过class对象实例化对象
Class c3 = Class.forName("类名+包名");
Constructor con = c3.getConstructor(); //获取的是空的构造方法
Constructor con1 = c3.getConstructor(String.class,int.class); //获取的是参数是(String,int)的构造方法
Constructor con2 = c3.getDeclaredConstructor(String.class); //获取私有构造方法
Object object = con.newInstance(); //实例化
Object object1 = con1.newInstance("斯柯达分",39);
con2.setAccessible(true); //取消权限检查,暴力反射
Object object2 = con2.newInstance("斯巴达");
Object obj = c3.newInstance(); //可以直接获取
获取成员方法
Class c3 = Class.forName("类名+包名");
Object obj = c3.newInstance();
Object v = c3.getMethod("getName").invoke(obj); //相当于执行了getName方法获取成员变量name的值
c3.getMethod("setName",String.class).invoke(obj,"斯拉夫吉萨"); //不用返回,返回值null 相当于执行了setName()方法
c3.getDeclaredMethod("私有方法的名字").setAccessible(true); //暴力反射
c3.getDeclaredMethod("私有方法的名字").invoke(obj); //invoke()作用是执行方法
注解
给JVM看的
自定义注解
//属性修饰符固定是 public abstract,默认是这个,可以不写
public @interface MyAnnotation{
//定义属性
public abstract int a();
public abstract double b() default 9.1; //默认值
public abstract String[] c();
}
自定义注解的使用
@MyAnnotation(a=100,c={"sa","asadf","rq"}) //b有默认值就不用写
public int age
来源:https://blog.csdn.net/qq_41200173/article/details/99301175