一、反射的概念
是指在运行过程中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用这个对象的所有方法和属性。这种动态获取信息和动态调用方法的功能称为JAVA的反射机制。
二、反射的优缺点
2.1、优点
通过反射的概念我们已经知道反射的优点是:使程序能够访问到装载到JVM中的类的内部信息(成员变量和成员方法)
2.2、缺点
性能问题:反射是一种解释操作,通过反射来访问字段和调用方法时要慢于直接代码
使用反射会模糊程序内部逻辑:反射绕过了源代码,使用反射后开发人员无法通过查看源代码来判断业务逻辑,会带来维护问题。使用反射往往比直接代码更复杂。
ps:Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
三、反射的使用
3.1、使用反射API来实例化对象
第一步获取Class实例,有三种方式
Class.forName(是不是很熟悉,JDBC通常通过此方式来获取数据库连接驱动类)
.class
getClass()
第二步使用Class的方法来实例化对象,有两种方式
第一种方式newInstance()
第二种方式
Constructor constructor = clazz.getConstructor();
constructor.newInstance();
话不多说,赶紧上代码
package com.cc.reflect.bean;public class Student
{private int id;private String name;@Overridepublic String toString(){return "Student [id=" + id + ", name=" + name + "]";}
}
package com.cc.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;import com.cc.reflect.bean.Student;/*** * @描述: 使用反射API来实例化对象* @版权: Copyright (c) 2019 * @作者: 程冲* @版本: 1.0 * @创建日期: 2019年5月17日 * @创建时间: 上午8:35:04*/
public class InstanceStudent
{public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, IllegalArgumentException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException{//1 第一步获取Class实例
// Class clazz = getClassByFullName("com.cc.reflect.bean.Student");//适用于知道类的完整路径名Class clazz = getClassByName();//适用于编译前就明确要操作的类
// Student student = new Student();Class clazz = getClassByObject(student);//适用于存在可以操作的实例//2 第二步使用Class的方法来实例化对象
// Object obj = getInstance1(clazz);//直接通过字节码文件来实例化对象,必须有无参构造器Object obj = getInstance2(clazz);//通过构造对象来实例化对象//3 第三步对象初始化Field fieldId = clazz.getDeclaredField("id");fieldId.setAccessible(true);fieldId.set(obj, 1);Field fieldName = clazz.getDeclaredField("name");fieldName.setAccessible(true);fieldName.set(obj, "张三");//上面的方法破坏了类成员的访问规则,一般不建议这么做System.out.println(obj);}private static Class getClassByFullName(String fullName) throws ClassNotFoundException{return Class.forName(fullName);}private static Class getClassByName(){return Student.class;}private static Class getClassByObject(Object obj){return obj.getClass();}private static Object getInstance1(Class clazz) throws InstantiationException, IllegalAccessException{return clazz.newInstance();}private static Object getInstance2(Class clazz) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{Constructor constructor = clazz.getConstructor();return constructor.newInstance();}
}
ps:本文只介绍了使用反射来实例化对象,有兴趣可以自己去研究一下如何访问类的属性、调用类的方法,比较简单。