Java反射
在java的面向对象编程过程中,通常我们需要先知道一个Class类,然后new 类名()方式来获取该类的对象。也就是说我们需要在写代码的时候 (编译期或者类加载之前)就知道我们要实例化哪一个类,运行哪一个方法,这种通常被称为 静态的类加载
那么有没有一种方法 在运行期动态的改变程序的调用行为的方法 呢?
这就是要为大家介绍的“java反射机制“。
反射机制
- 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到
- 加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象) ,这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个对象就像面镜子,透过这个镜子看到类的结构,所以,形象的称之为: 反射
Java反射机制原理示意图
Java反射机制可以完成
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时得到任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
反射相关的主要类
- java.lang.Class:代表个类,Class对象表示某 个类加载后在堆中的对象
- java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法
- java.lang.reflect.Field:代表类的成员变量,Field对象表示某个类的成员变量
- java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器
这些类在java.lang.reflection
反射优点和缺点
- 优点:可以动态的创建和使用对象(也是框架底层核心),使用灵活,没有反射机制,框架技术就失去底层支撑。
- 缺点:使用反射基本是解释执行,对执行速度有影响.
反射调用优化-关闭访问检查
- Method和Field、 Constructor对象都有setAccessible0方法
- setAccessible作用是启动和禁用访问安全检查的开关
- 参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查
通过反射创建对象
- 方式一:调用类中的public修饰的无参构造器
- 方式二:调用类中的指定构造器
- Class类相关方法
newInstance :调用类中的无参构造器,获取对应类的对象
getConstructor(Cas…clazz):根据参数列表,获取对应的构造器对象
getDecalaredConstructor(Cas…clazz):根据参数列表,获取对应的构造器对象 - Constructor类相关方法
setAccessible:暴破 //暴破[暴力破解],使用反射可以访间private构造器
newlnstance(Object…obj):调用构造器
通过反射访问类中的成员
访问属性
- 根据属性名获取Field对象
Field f = clazz对象.getDeclaredField(属性名); - 暴破: f.setAccessible(true); //f是Field
- 访问
f.set(o,值);
syso(f.get(o)); - 如果是静态属性,则set和get中的参数o, 可以写成null
访问方法
- 根据方法名和参数列表获取Method方法对象:
- Method m =clazz.getDeclaredMethod(方法名,XX.class); //得到本类的所有方法
- 获取对象: Object o= clazz.newInstance();
- 暴破: m.setAacessible(true);
- 访问: Object returnValue = m.invoke(o,实参列表);
- 注意:如果是静态方法,则invoke的参数o,可以写成null!
反射的使用
获取Class对象的三种方式
- Object ——> getClass();
- 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
- 通过Class类的静态方法:forName(String className)(常用)
反射的书写步骤
创建dao包,接口,类
public class BookDaoImpl implements BookDao {
@Override
public void add() {
System.out.println("BookDaoImpl...add");
}
}
public interface BookDao {
public void add();
}
创建service包,接口,类
public class BookServiceImpl implements BookService {
public String name;
int age;
protected String sex;
private String address;
public BookServiceImpl(){
}
public BookServiceImpl(String name){
this.name = name;
}
private BookServiceImpl(String name,int age,String sex,String address){
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
}
BookDao bookDao = new BookDaoImpl();
@Override
public void add() {
System.out.println("BookSeiviceImpl...add");
bookDao.add();
}
@Override
public void fun() {
System.out.println("BookSeiviceImpl...fun");
}
}
public class BoookServiceVip implements BookService {
BookDao bookDao = new BookDaoImpl();
@Override
public void add() {
System.out.println("BoookServiceVip...add");
}
@Override
public void fun() {
System.out.println("BoookServiceVip...fun");
}
}
public interface BookService {
public void add();
public void fun();
}
创建servlet包,接口,类,测试类
public class BookServlet {
BookService bookService = new BoookServiceVip();
@Test
public void add(){
System.out.println("BookServlet.add");
bookService.add();
}
}
public class Test01 {
public static void main(String[] args) throws Exception {
Class cla = Class.forName("com.gao.service.impl.BookServiceImpl");
Field[] fields = cla.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("---------");
Field[] fields1 = cla.getDeclaredFields();
for (Field field : fields1) {
System.out.println(field);
}
System.out.println("===========");
Constructor[] constructors = cla.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------------");
Constructor[] constructors1 = cla.getDeclaredConstructors();
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
System.out.println("======================");
Method[] methods = cla.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-------------");
Method[] methods1 = cla.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(method);
}
}
}
public class Test02 {
public static void main(String[] args) throws Exception {
//读取配置文件,获取内容
// File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
// InputStream stream=new FileInputStream(file);
InputStream stream = Test02.class.getClassLoader().getResourceAsStream("info.properties");
Properties p=new Properties();
p.load(stream);
String className=p.getProperty("className");
//1.通过全类名获取类的Class对象
Class cla = Class.forName(className);
//2.通过Class对象获取类的无参构造器
Constructor constructor = cla.getDeclaredConstructor();
//3.使用构造器创建对象
BookService bookService = (BookService) constructor.newInstance();
//4.使用对象调用方法
bookService.add();
}
}
public class Test03 {
public static void main(String[] args) throws Exception {
//读取配置文件,获取内容
// File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
// InputStream stream=new FileInputStream(file);
InputStream stream = Test03.class.getClassLoader().getResourceAsStream("info.properties");
Properties p=new Properties();
p.load(stream);
String className=p.getProperty("className");
String methodName=p.getProperty("methodName");
//1.通过全类名获取类的Class对象
Class cla = Class.forName(className);
//2.通过Class对象获取类的无参构造器
Constructor constructor = cla.getDeclaredConstructor();
//3.使用构造器创建对象
BookService bookService = (BookService) constructor.newInstance();
//4.获取方法名
Method method = cla.getDeclaredMethod(methodName);
//5.执行方法
method.invoke(bookService);
}
}