1. 反射
反射就是根据类名去获取类的成员、构造方法、方法、实现的接口、继承的父类等
测试代码:先建一个Person类,要有有参构造函数,箜参构造函数,私有公有成员,私有公有方法,toString方法
public class Person {
public String name = null;
private int age = 0;
public Person() {
name = "kluter";
age = 34;
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
private Person(String name){
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void getSth(String testStr){
out.println(testStr);
}
}
创建测试主程序:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MyReflect {
public String className = null;
public Class personClass = null;
/**
* reflect Person class
* @throws Exception
*/
public void init() throws Exception {
className = "com.gamebear.reflect.Person";
personClass = Class.forName(className);
}
/**
* get a class object by reflect
*/
public void getClassName(){
out.println(personClass);
}
/**
* get a class object by Class
*/
public void getClassName2(){
out.println(Person.class);
}
/**
* get a instance of object, it will call the null param constructure
* @throws Exception
*/
public void getNewInstance() throws Exception{
out.println(personClass.newInstance());
}
/**
* get non-private constructor with params
* @throws Exception
*/
public void getPublicConstructor() throws Exception{
//get constructor by params
Constructor constructor = personClass.getConstructor(String.class, int.class);
//use params constructor get a object instance
Person person = (Person)constructor.newInstance("lesslin", 27);
//print it out
out.println(person.getName());
out.println(person.getAge());
}
public void getPrivateConstructor() throws Exception{
//get the private constructor
Constructor con = personClass.getDeclaredConstructor(String.class);
//set the limits of authority
con.setAccessible(true);//delete the limits of authority
//new a instance by private constructor
Person person2 = (Person)con.newInstance("nainai");
//print it out
out.println("**" + person2.getName());
out.println("**" + person2.getAge());
}
/**
* get public attribute
* @throws Exception
* @throws
*/
public void getNotPrivateField() throws Exception{
Constructor constructor = personClass.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("aaa", 11);
Field field = personClass.getField("name");
field.set(obj, "bbb");
out.print(field.get(obj));
}
/**
* get private attribute
* @param args
* @throws Exception
* @throws
* @throws Exception
*/
public void getPrivateField() throws Exception{
Constructor constructor = personClass.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("ccc", 33);
Field field2 = personClass.getDeclaredField("age");
field2.setAccessible(true);
field2.set(obj, 44);
out.println(field2.get(obj));
}
/**
* get and call public method
*/
public void getNotPrivateMethod()throws Exception{
out.println(personClass.getMethod("toString"));
Object obj = personClass.newInstance();
Method method = personClass.getMethod("toString");
Object object = method.invoke(obj);
out.println(object);
}
/**
* get and call private method
* @param args
* @throws Exception
*/
public void getPrivateMethod()throws Exception{
Object obj = personClass.newInstance();
Method method = personClass.getDeclaredMethod("getSth", String.class);
method.setAccessible(true);
Object value = method.invoke(obj, "test***********");
out.println(value);
}
/**
* other method in reflect
* @param args
* @throws Exception
*/
public void otherMethod()throws Exception{
//get the class Loader
out.println(personClass.getClassLoader());
//get all the implement Interfaces
Class[] interfaces = personClass.getInterfaces();
for(Class class1 : interfaces){
out.println(class1);
}
//reflect the direct super class of this class
out.println(personClass.getGenericSuperclass());
//is array
out.println(personClass.isArray());
out.println(new String[3].getClass().isArray());
//is Enum
out.println(personClass.isEnum());
//is interface
out.println(personClass.isInterface());
}
public static void main(String[] args) throws Exception {
MyReflect mr = new MyReflect();
mr.init();
// mr.getClassName();
// mr.getClassName2();
// mr.getNewInstance();
// mr.getPublicConstructor();
// mr.getPrivateConstructor();
// mr.getNotPrivateField();
// mr.getPrivateField();
mr.getNotPrivateMethod();
mr.getPrivateMethod();
mr.otherMethod();
}
}
2. 动态代理
假设在原来的类中有一个public方法doSomething(),可以供5个客户处理旧的业务逻辑。现在有一个客户希望修改doSomething()方法实现一个增强的业务逻辑,这时需求修改这个方法,但是这个方法还有剩余4个老客户在调用。
所以我们不能只为了新业务需求修改doS omething(),导致其他模块受影响。那么我们可以通过动态代理的方式,扩展doSomething的方法实现,使得在原有的方法中增加更多的业务逻辑,但又不是修改soSomething。
动态代理:在不修改原业务的基础上,基于原业务的方法,进行重新的扩展,实现新的业务。
Demo代码:
IBoss是计价方法的interface接口,里面有一个抽象方法:
Boss类实现了IBoss接口的抽象方法:
SaleAction类是调用旧计价方法的类:
ProxyBoss是一个动态代理的工具类,实现了新计价方法的代理转换:
ProxySaleAction类是使用动态代理来计价的类,区别于旧的计价方式,使用了动态代理: