Java_反射(反射及原理 / 动态代理及原理)
本文由 Luzhuo 编写,转发请保留该信息.
原文: http://blog.csdn.net/Rozol/article/details/77511333
反射: 在运行状态时, 能够获取任意一个类的所有属性和方法; 能够调用任意一个对象的所有属性和方法.
反射性能较低, 一般情况下不考虑用反射.
Proxy 动态代理: 用来修改已经具有的对象的方法, 控制方法是否执行, 或在方法执行之前和执行之后做一些额外的操作
Bean类
public class Bean {
/**
* 公有属性
*/
public int number = 10;
/**
* 私有属性
*/
private String name = Bean.class.getSimpleName();
/**
* 静态属性
*/
public static int max = Integer.MAX_VALUE;
/**
* 常量属性
*/
protected static final int min = Integer.MIN_VALUE;
/**
* 无参构造
*/
public Bean(){
}
/**
* 有参构造
* @param numbder
*/
public Bean(int number){
this.number = number;
}
/**
* 私有构造
* @param number
* @param name
*/
private Bean(int number, String name){
this.number = number;
this.name = name;
}
protected Bean(int number, String name, int max){
this.number = number;
this.name = name;
Bean.max = max;
}
/**
* 公有方法
* @param number
*/
public void setNumber(int number){
this.number = number;
}
public int getNumber(){
return this.number;
}
/**
* 私有方法
*/
private void setName(String name){
this.name = name;
}
private String getName(){
return this.name;
}
/**
* 静态方法
* @param max
*/
public static void setMax(int max){
Bean.max = max;
}
public static int getMax(){
return Bean.max;
}
/**
* protected方法
* @param min
* @return
*/
protected int getMin(){
return Bean.min;
}
@Override
public String toString() {
return "Bean [number=" + number + ", name=" + name + ", max=" + Bean.max + ", min =" + Bean.min + "]";
}
}
@Deprecated
public class SubBean extends Bean implements Serializable{
/**
* 调用父类方法, 并抛出一个异常
* @return
* @throws Exception
*/
public int getSuperNumber(int number) throws Exception{
return super.getNumber();
}
}
Class文件对象
在使用反射之前, 首先要获取Class类的文件对象, 然后才能通过反射去获取类的方法, 之后才能调用该方法.
/**
* 获取Class文件对象的几种方式
* @author Luzhuo
*/
public class GetClass {
public static void main(String[] args) throws ClassNotFoundException {
// 方式1: 通过对象获得
GetClass getClass = new GetClass();
Class<? extends GetClass> class1 = getClass.getClass();
// 方式2: 通过数据类型的一个静态calss属性
Class<GetClass> class2 = GetClass.class;
// 方式3: 通过全类名获得
Class<?> class3 = Class.forName("反射.reflect.GetClass");
// 方式4: 通过 类加载器 加载
Class<?> class4 = GetClass.class.getClassLoader().loadClass("反射.reflect.GetClass");
System.out.println(class1 == class2 && class2 == class3 && class3 == class4); // true
}
}
反射
反射: 在运行状态时, 能够获取任意一个类的所有属性和方法; 能够调用任意一个对象的所有属性和方法.
/**
* 反射: 在运行状态时, 能够获取任意一个类的所有属性和方法;
* 能够调用任意一个对象的所有属性和方法.
*
* 反射性能较低, 一般情况下不考虑用反射.
* @author Luzhuo
*/
public class reflect {
public static void main(String[] args) throws Exception {
// 创建对象(构造方法)
constructor();
// 属性
field();
// 方法
method();
// 案例: 通过反射调用已存在对象的方法
callOldInstance();
}
/**
* 对象的创建(构造方法)
* 访问 private / protected 修饰的构造方法时, 需要取消语法检查
*/
private static void constructor() throws Exception {
// 方式1: Class文件对象
Class<?> clazz = Bean.class;
Bean instance1 = (Bean) clazz.newInstance();
// 方式2: Class文件对象的构造方法
Constructor<?>[] cons = clazz.getConstructors(); // 所有公共构造方法
Constructor<?>[] allcons = clazz.getDeclaredConstructors(); // 所有构造方法(public / private / protected)
Constructor<?> con = clazz.getConstructor(int.class); // 获取指定公有构造方法
Constructor<?> decCon = clazz.getDeclaredConstructor(int.class, String.class); // 获取指定私有构造方法
decCon.setAccessible(true); // 取消Java语言访问检查(获取 priva