java 反射机制基础

反射(在类加载的时候,也想获取到类中的信息)//换一种方式使用类

正常情况下,要先进行类加载,然后创建对象调用

当我们不知道类中的属性,方法,构造器,注释时,我们也想调用类里面的属性与方法,可以通过反射获取到类的信息再使用。

java.lang.Class{//没有构造器,不能创建对象,所以所有类的类(包括object)就是它

}

Object就是Class的一个对象

new Class()//但是Class不能被创建对象= Object;

类的类 Class

属性的类 Field

方法的类 Method

构造器 ,注解。。。。。都有对应的大类,这些都是大类的对象

反射可以破坏封装

获取类中的public修饰的属性,也包含从父类中继承过来的public属性
Field[] getFields()
Field getField(String name)
获取类中声明的属性(包含私有的),但是不能获取从父类中继承过来的属性
Field[] getDeclaredFields()
Field getDeclaredField(String name)

获取当前类中的public方法,包含从父类中继承的public方法
Method[] getMethods()
Method getMethod(String name, Class<?>… parameterTypes)
获取当前类中声明的方法(包含私有的),但是不能获取从父类中继承过来的方法
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, Class<?>… parameterTypes)

反射访问属性

public static void main(String[] args)throws Exception {
    Student stu = new Student();
    Class c = stu.getClass();
    //获取类中名字叫name的属性
    Field f1 = c.getDeclaredField("name");
    //设置私有属性可以被访问,否则报错
    f1.setAccessible(true);
    //用反射的方式,给指定对象的name属性赋值
    //相当于之前的stu.name = "tom";
    f1.set(stu,"tom");
    //用反射的方式,获取这个属性的值
    //相当于之前的stu.name
    System.out.println(f1.get(stu));
    System.out.println("----------------------");
    //获取类中名字叫age的属性
    Field f2 = c.getDeclaredField("age");
    //用反射的方式,给指定对象的age属性赋值
    //相当于之前的stu.age = 20;
    f2.set(stu,20);
    //用反射的方式,获取这个属性的值
    //相当于之前的stu.age
    System.out.println(f2.get(stu));
    System.out.println("----------------------");
    //获取类中名字叫num的属性
    Field f3 = c.getDeclaredField("num");
    //用反射的方式,给静态属性num赋值,不需要对象
    //相当于之前的Student.num = 99;
    f3.set(null,99);
    //用反射的方式,获取这个静态属性的值,不需要对象
    //相当于之前的Student.num
    System.out.println(f3.get(null));
}

反射调用方法

public static void main(String[] args)throws Exception {
    Student stu = new Student();
    Class c = stu.getClass();
    //获取类中的toString方法,没有参数,这是从父类继承的方法
    Method m1 = c.getMethod("toString", null);
    //反射的方式,调用stu对象中的这个方法,没有参数,并接收执行结果
    //相当于之前的:Object result = stu.toString();
    Object result = m1.invoke(stu,null);
    //输出执行结果
    System.out.println(result);
    System.out.println("-------------------");
    //获取类中的sayHello方法,需要一个String类型的参数,这是自己定义的方法
    Method m2 = c.getMethod("sayHello", String.class);
    //反射的方式,调用stu对象中的这个方法,参数是"tom",并接收执行结果
    //相当于之前的:Object result = stu.sayHello("tom");
    result = m2.invoke(stu,"tom");
    //输出执行结果
    System.out.println(result);
}`

注意, public Object invoke(Object obj, Object… args)
obj,表示要调用哪个对象的方法,如果是静态方法,可以传null
args,可变参数,表示要调用的方法的参数列表
m.invoke(obj,null) 中的m,就是通过Class对象获取到的类中的某一个指定的方法

反射创建对象

使用反射的方式可以创建对象,也就是需要反射调用构造器。

例如,反射调用类中无参构造器创建对象

public static void main(String[] args)throws Exception {
    Class c = Student.class;
    //默认调用类中的无参构造器来创建对象
    //相当于之前的:Object obj = new Student();
    Object obj = c.newInstance();
    System.out.println(obj);
}

例如,反射调用类中有参构造器创建对象

public static void main(String[] args)throws Exception {
    Class c = Student.class;
    //获取类中的俩参构造器
    Constructor constructor = c.getConstructor(String.class, int.class);
    //调用有参构造器创建对象,并传入对应的参数值
    //相当于之前的:Object obj = new Student("tom",20);
    Object obj = constructor.newInstance("tom",20);
    System.out.println(obj);
}

反射获取注解

使用反射,可以获取到一个类中的注解信息

与上面类似,但是只能抓到runtime阶段运行的注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值