反射概念
简单的理解成动态的加载一个类,将字节码文件和字节码文件的成员封装成对象,来提供对其内容的操作。简单来说,反射技术就是对一个类的解剖。
反射的好处:大大的增强了程序的扩展性。
弊端:打破了封装性
反射基本步骤
1.获得Class对象,就是获取到指定的名称的字节码文件对象。
2.实例化对象,获得类的属性、方法或构造函数。
3.访问属性、调用方法、调用构造函数创建对象。
获取Class字节码对象(三种)
1.通过对象的getClass()方法获取(要建立对象,才能调用,常用于获得对象类型)
Object o = new Person();
Class clazz = o.getClass();
2.通过数据类型的静态属性(.class)获取(要明确类型才能调用,常用于传参)
Class clazz = Person.class;
3.使用Class类中的静态方法 forName()(扩展性最强,只需要获得类名的字符串,常用于类加载)
//通常可以重配置文件中获取
String className = "net.hncu.domain.Person";
Class clazz = Class.forName(className);
反射用法
反射类的成员方法(Method){指定方法&所有方法||公有&私有}:
//步骤一:获取class对象
Class<XmlDom> clazz = XmlDom.class;
//步骤二:获取Method
//1.获取指定 公有 的方法,注意参数是参数所属类型的.class文件。
Method method = clazz.getMethod("write", String.class,int.class);
//2.获取指定方法,可以是私有方法。
Method method1 = clazz.getDeclaredMethod("write", String.class,int.class);
//3.获取所有公有方法。
Method[] methods = clazz.getMethods();
//4.获取所有方法,包括私有方法。
Method[] methods1 = clazz.getDeclaredMethods();
//步骤三:实例化一个空参对象
Object object=clazz.newInstance();
//步骤四:设置暴力访问私有方法
method1.setAccessible(true);
//步骤五:执行一个方法
method1.invoke(object,"反射",10);
反射类的构造函数(Constructor):
Class clazz = XmlDom.class;
//1.获取一个公有 有参构造函数
Constructor<XmlDom> c = clazz.getConstructor(String.class,int.class);
//2.反射私有有参构造函数
Constructor<XmlDom> c = clazz.getDeclaredConstructor(String.class,int.class);
//3. 反射所有公有构造犯法
Constructor[] constructors = clazz.getConstructors();
//4. 反射所有构造反法,包括私有的
constructors = clazz.getDeclaredConstructors();
//#通过反射的有参构造函数进行实例化(调用的是构造器的newInstance()方法)
c.newInstance("反射",10);
反射类的属性(Field):
//通过字段名获得该字段
Field field = clazz.getField(fieldName);
field.setAccessible(true);
//给该字段赋值
field.setObject(value);
通过反射创建对象的方法(.getInstance):
1.通过Class类构造无参实例,一般被反射调用的类必须要有公有无参构造器(这也是为什么一般实现有参构造后还要写一个无参构造的原因):
//该方法构造的是无参的实例
Object object = Class.getInstance();
2.通过反射有参构造函数构造有参实例:
Class clazz = XmlDom.class;
//获取一个公有 有参构造函数
Constructor<XmlDom> c = clazz.getConstructor(String.class,int.class);
//通过反射的有参构造函数进行实例化(调用的是构造器的newInstance()方法)
c.newInstance("反射",10);
提取注解(Annotation)
获取 Annotation实例(详细):
getAnnotation(Class<T> annotationClass)
getDeclaredAnnotations()
getParameterAnnotations()
实用案例
1.获取该类或父类中的指定的方法(可能父类独有方法)
//传入字子类class对象,方法名,参数列表
public Method getMethod(Class clazz, String methodName, Class ... args) {
//若该类存在则返回并中断,如没有且不是Object类,获得其父类class
for (; clazz != Object.class; clazz = clazz.getSuperclass()){
try {
return clazz.getDeclaredMethod(methodName, args);
} catch (Exception e) {
}
}
return null;
}