反射基础学习

JAVA反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用他的任意一个方法和属性(动态获取指定类及其成员,并运行其中的内容)

使用反射,可以在运行时对类Class、构造方法Constructor、普通方法Method、字段Field进行操作

应用程序已经运行,无法在其中进行new对象的建立,就无法使用对象。这时可以根据配置文件的类全名(带有包名)去找对应的字节码文件,并加载进内存,并创建该类对象实例。这就需要使用反射技术完成

获取class对象的三种方式

一、  采用继承自Object类的getClass()方法  有点不方便  需要用到该类并创建该类的对象  再调用getClass()方法完成

Person p = new Person();
Class classzz = p.getClass();

二、 采用每个类型都具备的class静态属性 比第一个简单 但还是必须要使用到该类

Class classzz = Person.class;

三、 采用Class类中的静态forName(className)方法  不需要直接使用具体的类 只需要知道该类的全名  名字可以作为参数传递 可以提高扩展性 最常用

Class classzz = Class.forName("cn.a2490.test.Person");   注:必须使用全名(包含包名)

API

获取classzz对象对应的类的全部构造器

Constructor[] ctros = classzz.getDeclaredConstructors();

获取classzz对象对应的类的public权限的构造器

Constructor[] constructors = classzz.getConstructors();

获取classzz对象对应的类的public方法

Method[] methods = classzz.getMethods();

获取classzz对象对应类的指定的方法  方法名  参数的class对象

Method method = classzz.getMethod("setName", String.class);

获取classzz对象对应类的全部注解

Annotation[] annotations = classzz.getAnnotations();

获取classzz对象对应的类的全部内部类

Class[] inClasses = classzz.getDeclaredClasses();

        使用Class.forName()方法加载Inner内部类 

Class inClasszz = Class.forName("Person$Inner");

获取classzz对象对应的类的外部类

Class outClass = classzz.getDeclaringClass();

获取classzz对象对应的类的包

Package classPackage = classzz.getPackage();

获取classzz对象对应的类的父类

Class superclass = classzz.getSuperclass();

应用

class对象可以获得对应类的方法(Method)、构造器(Constructor)、成员变量(Field)。这三个类都实现了java.lang.reflect.Member接口,可通过Method对象来执行相应的方法、通过Constructor对象调用对应的构造器创建实例、通过Field对象直接访问或修改对象的成员变量值

创建对象的方式(Constructor对象)

平时的方式:

        先加载Person类进入内存

        将该类封装成Class对象

        根据Class对象,用new操作符创建Person对象

        调用构造函数对该对象进行初始化

Person p = new Person();

反射的方式

        通过forName()根据指定的类名去查找对应的字节码文件,并加载进入内存

        将该字节码文件封装成class对象

        直接通过newIntstance()方法完成该类的创建

        newInstance()方法调用就是该类中的空参数构造函数完成对象的初始化

    方式一:使用classzz对象对应的类的默认构造器

Object object = classzz.newInstance();

    方式二:使用classzz对象对应的类的指定的构造器

Constructor constructor = classzz.getConstructor(String.class);
Object object = constructor .newInstance("张三");

方法调用(Method对象)

Person p = new Person();
Class classzz = p.getClass();
Method mtd = classzz.getMethod("setName",String.class);
mtd.invoke(p,"张三");

注:当通过invoke方法来调用对应方法时,要求程序必须有调用该方法的权限。如果需要调用某个对象的private方法,则使用Method.setAccessible(Boolean flag),当值为true时,表示该Method对象在使用时取消访问权限检查

访问成员变量(Field对象)

Person p = new Person();
Class classzz = p.getClass();
Field nameField = classzz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(p,"张三");
//nameField.setInt(p,007);

获取成员变量的值:getXXX(Object object);

设置成员变量的值:setXXX(Object object,XXX val);

注:此XXX对应8大基本数据类型,若成员变量的类型为引用数据类型,则直接使用get/set方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值