java中的反射简介

一、简介

反射技术:动态的获取类中的成员,并调用该类的成员。(也可以叫对类的解剖)

反射技术核心问题:要拿到类的字节码文件,即.class文件


字节码文件中会包含以下内容:

name(类名),constructor(构造器),field(字段),method(方法);

所以会有相应的获取这些内容的方法

getName();getConstructor();getField();getMethod();


描述字节码文件的类:Class

字节码文件只加载一次,即每个类在内存中只有一份.class文件

二、如何获取一个字节码文件的对象?

方式一:

Object中的getClass();该方法在反射技术里,不合适,必须有对象才能使用,反射中不明确具体类

Person p = new Person();

Class clazz = p1.getClass();

方式二:

所有的数据类型都有自己的Class对象,每一个数据类型都有一个默认的静态属性.class,可以用该属性获取到字节码文件对象

这个也必须要有对象才可以

int.class int类型的class对象

Person.class Person类型的class对象


方式三(重点掌握):

Class.forName(String name),通过名称获取对应的字节码文件对象。

Class.forName(String name):name必须加上包名

三、动态创建对象:

1.根据给定的类名获取Class对象

Class clazz = Class.forName(className);

创建一个对象

Object obj = clazz.newInstance();

newInstance()调用空参数构造函数,如果没有空参数构造函数就会抛出java.lang.InstationException

一般被反射的类通常都有空参数构造函数


2.根据指定的构造器动态创建对象:

先获取指定的构造函数


(1).通过Class获取指定的构造函数,比如带两个参数

Constructor cons = clazz.getConstructor(String.class,int.class);参数为类型对象


(2).动过指定的构造器对对象进行初始化

Object obj = cons.newInstance("zhangsan",19);

四、动态的获取字段

clazz.getFields():获取所有字段

clazz.getFields(String name):获取指定名称的字段

getXXX():只能拿到公有的,也就是public的


getDeclaredXXX():可以拿共有的和私有的,只要你声明,就会被拿到

例如:getDeclaredConstructor()


要对非静态的字段操作必须有对象

filed.set(obj,12);不能给private修饰的字符赋值


使用父类的方法将访问权限检查能力取消

filed.setAccessible(true);暴力访问

filed.set(obj,12);

五、动态获取方法

1.反射非静态无参数方法:

Method method = clazz.getMethod("methodName",null);

method.invoke(obj,null);调用方法


2.反射静态无惨方法:

Method method = clazz.getMethod("methodName",null);

method.invoke(null,null);调用方法


3.反射非静态有参数方法:

Method method = clazz.getMethod("methodName",String.class,int,class);

method.invoke(obj,"zhangsan",49);