1. 反射
反射就是根據(jù)類名去獲取類的成員、構(gòu)造方法允蜈、方法冤吨、實現(xiàn)的接口、繼承的父類等
測試代碼:先建一個Person類陷寝,要有有參構(gòu)造函數(shù)锅很,箜參構(gòu)造函數(shù),私有公有成員凤跑,私有公有方法爆安,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);
????}
}
創(chuàng)建測試主程序:
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. 動態(tài)代理
假設(shè)在原來的類中有一個public方法doSomething(),可以供5個客戶處理舊的業(yè)務(wù)邏輯∽幸現(xiàn)在有一個客戶希望修改doSomething()方法實現(xiàn)一個增強的業(yè)務(wù)邏輯扔仓,這時需求修改這個方法褐奥,但是這個方法還有剩余4個老客戶在調(diào)用。
所以我們不能只為了新業(yè)務(wù)需求修改doS omething()翘簇,導致其他模塊受影響撬码。那么我們可以通過動態(tài)代理的方式,擴展doSomething的方法實現(xiàn)版保,使得在原有的方法中增加更多的業(yè)務(wù)邏輯呜笑,但又不是修改soSomething。
動態(tài)代理:在不修改原業(yè)務(wù)的基礎(chǔ)上彻犁,基于原業(yè)務(wù)的方法叫胁,進行重新的擴展,實現(xiàn)新的業(yè)務(wù)汞幢。
Demo代碼:
IBoss是計價方法的interface接口,里面有一個抽象方法:
Boss類實現(xiàn)了IBoss接口的抽象方法:
SaleAction類是調(diào)用舊計價方法的類:
ProxyBoss是一個動態(tài)代理的工具類,實現(xiàn)了新計價方法的代理轉(zhuǎn)換:
ProxySaleAction類是使用動態(tài)代理來計價的類买乃,區(qū)別于舊的計價方式为牍,使用了動態(tài)代理: