反射
反射【剖析】类的手术刀,获取类的一切资源。
类的资源如下:
属性
构造器
方法
获取属性之后可以做什么? 1.获取值 2.赋值
获取构造器之后可以做什么? 1.将对象实例化
获取方法之后可以做什么? 1.调用该方法
反射的真正意义:在知道类路径的情况下,去获取类的资源
目标:反射的目标和我们类的实例化是一样的 访问的规则
方式不一样
入侵类 剖析 可以使用私有的方法
class Person{
private int pid;
private String pname;
private char psex;
private Person(int pid,String pname,char psex)
{
this.pid=pid;
this.pname=pname;
this.psex=psex;
}
public Person()
{
}
private void sayHello()
{
}
private static void doSomething()
{
}
}
反射的概念
把某个资源变成Class的过程,我们称为叫做反射。
3种反射的方式
1.将对象变成Class
Person p=new Person();
Class clz=p.getClass(); //getClass() 1.查看真实的类对象 2.反射方法获取Class对象
2.将类变成Class
Class clz=Person.class; //class不是一个方法
3.使用Class类的静态方法 获取Class对象
Class clz=Class.forName("类路径")
4.获取该类的所有构造器
Constructor[] constructors = clz.getConstructors(); //获取所有的public的构造器
Constructor[] constructors = clz.getDeclaredConstructors(); //获取所有的构造器
通过特征获取单个构造器 【根据构造器的参数类型来区分不同的构造器】
Constructor c=clz.getDeclaredConstructor(int.class,String.class,char.class);
实例化 newInstance(),实例化的时候根据调用构造器不同 传入相应的实参
如果当前的构造器是私有的,我们无法去使用。
c.setAccessible(true); //之前暴力授权
Object o=c.newInstance(1,"张三”,'女’); //以多态的方式获取到我们对象
5.获取该类的属性
Field[] fields= clz.getFields(); //获取所有的public的属性
Field[] fields = clz.getDeclaredFields(); //获取所有的属性
通过属性名和特征获取单个属性
Field pname=clz.getDeclaredField("pname");
要获取属性的值 要先实例化
如果说当前的属性是私有的,我们无法使用
pname.setAccessible(true); // 需要在实例化之前暴力授权
一般对属性的操作 就是获取值 和 设置值
Object value=pname.get(o); //这里o表示实例化的对象 value是以多态的方式获取的
pname.set(o,"张三"); //这里o表示实例化的对象 "张三"表示我们要传递实参
6.获取该的方法
Method[] methods= clz.getMethods(); //获取所有的public的方法
Method[] methods = clz.getDeclaredMethods(); //获取所有的属性
通过方法名和特征获取单个方法
Method sayhello=clz.getDeclaredMethod("sayHello",null); //方法没有参数 填写null值
如果该方法是私有
sayhello.setAccessible(true); // 之前暴力授权
使用invoke方法来执行该方法 有返回值你可以接受 如果方法的返回值类型是void 那么会返回Void类
Object result=sayhello.invoke(o,null); //第一个参数是对象
静态方法的调用
Method doSomething=clz.getDeclaredMethod("doSomething",null); //方法没有参数 填写null值
Object result=doSomething.invoke(null,null); //因为我是一个静态方法 所以可以将第一个参数设置为null
7.注解标注在类,方法,全局变量的上面
1.特殊的意义
2.存放一些数据
@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface Hello
{
int id() default 1;
String name() default " ";
}
@Target 表示可以使用在哪些资源上
@Retention 表示在什么时候有效 如果我们想要在反射的时候去解析 一定要设置为 RetentionPolicy.RUNTIME
使用反射获取类上的注解
@Hello(id=51,name="冉益")
public class Person
{
@Hello(id=52,name="冉益2")
int pid;
@Hello(id=53,name="冉益3")
public Person()
{
// TODO Auto-generated constructor stub
}
@Hello(id=54,name="冉益4")
public void sayHello()
{
}
}
//获取类上面的注解
Class clz=Person.class;
Hello hello=clz.getDeclaredAnnotation(Hello.class);
hello.id();
hello.name();
//获取属性上的注解信息
Field pid=clz.getDeclaredFiled("pid");
Hello hello=pid.getDeclaredAnnotation(Hello.class);
hello.id();
hello.name();
//获取构造器上的注解信息
Constructor c = clz.getDeclaredConstructor(null);
Hello declaredAnnotation = c.getDeclaredAnnotation(Hello.class);
System.out.println(declaredAnnotation.id());
System.out.println(declaredAnnotation.name());
//获取方法上面的注解信息
Method sayHello=clz.getDeclaredMethod("sayHello", null);
Hello declaredAnnotation2 = sayHello.getDeclaredAnnotation(Hello.class);
System.out.println(declaredAnnotation2.name());
System.out.println(declaredAnnotation.id());