Luckylau's Blog

Java基础之反射的机制与用途

java的反射机制

什么是java.lang.Class类?

​ 众所周知Java有个Object类,是所有Java类的继承根源,其内声明了数个应该在所有Java类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class类的对象。

​ Class类十分特殊。它和一般class一样继承自Object,其实体用以表达Java程序运行时的class和interface,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void,也就是说运行时的class和interface,基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 Class 没有公共构造方法,Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的一个Class object(对象),因此不能显式地声明一个Class对象。

​ 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

​ 一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。

什么是反射机制?

Class类是Reflection起源。针对任何想探勘的class,唯有先为它产生一个Class object,接下来才能经由它唤起为数十多个的Reflection APIs。Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods。

​ Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

反射机制有什么优势?

在运行时判断任意一个对象所属的类。

在运行时构造任意一个类的对象。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时调用任意一个对象的方法。

生成动态代理。

如何使用反射机制?

通过Class类获取成员变量,成员方法和构造器

首先是获取类的Class对象,因为它是Reflection API 中的核心类,有4中方式:

方法 举例
运用.class 语法 Class<?> classType= Boolean.class; System.out.println(classType); 输出:class java.lang.Boolean
运用static method Class.forName() Class<?> classType = Class.forName(“java.lang.Boolean”); System.out.println(classType5); 输出:class java.lang.Boolean
运用primitive wrapper classes的TYPE 语法(这里返回的是原生类型,和Boolean.class返回的不同) Class<?> classType= Boolean.TYPE; System.out.println(classType3); 输出:boolean
调用getClass Boolean var= true; Class<?> classType = var.getClass(); System.out.println(classType); 输出:class java.lang.Boolean

然后获取类的属性和方法以及构造器:

public String getName():获得类的完整名字。

public Field[] getFields():返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。

public Field getField(String name) :返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

public Field[] getDeclaredFields():返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

public Field getDeclaredField(String name): 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package test;
import java.lang.reflect.Field;
public class MethodDemo {
public static Object getStaticProperty(String className, String fieldName)throws Exception {
Class cl = Class.forName(className);
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);
Object property = field.get(cl);
return property;
}
public static Object getProperty(Object owner, String fieldName)throws Exception {
Class cl = owner.getClass();
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);//访问私有
Object property = field.get(cl);
return property;
}
public static Field getField(Object owner, String fieldName)throws Exception {
Class cl = owner.getClass();
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);//访问私有
return field;
}
public static void main(String[] args) {
People p = new People();
String str ="abc";
try {
System.out.println(MethodDemo.getStaticProperty("test.People", "org"));
System.out.println(MethodDemo.getProperty(p, "org"));
System.out.println(p.getName());
Field field =MethodDemo.getField(p, "name");
field.set(p, "tom");
System.out.println(str);
Field field2 =MethodDemo.getField(str, "value");
field2.set(str, "def".toCharArray());
System.out.println(str);
System.out.println(p.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class People{
private String name ;
private Integer age ;
private static String org ="baidu";
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}

public Method getMethod(String name,Class<?>… parameterTypes):返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
public Method[] getMethods():返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
public Method getDeclaredMethod(Stringname,Class<?>… parameterTypes):返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
public Method[] getDeclaredMethods():返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package test;
import java.lang.reflect.Method;
public class MethodDemo {
public static Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
Class ownerClass = owner.getClass();
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass[i] = args[i].getClass();
}
Method method = ownerClass.getMethod(methodName,argsClass);
//method.setAccessible(true);//访问私有
return method.invoke(owner, args);
}
public static Object invokeMethod(Object owner, String methodName) throws Exception {
Class ownerClass = owner.getClass();
Method method = ownerClass.getMethod(methodName);
//method.setAccessible(true);//访问私有
return method.invoke(owner);
}
public static void main(String[] args) {
Person per = new Person("tom",12);
try {
MethodDemo.invokeMethod(per, "print");
System.out.println(MethodDemo.invokeMethod(per, "eat",new Object[]{"apple"}));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Person{
private String name;
private Integer age;
public Person(){
}
public Person(String name ,Integer age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void print(){
System.out.println("name:" + this.name + " age:" + this.age);
}
public String eat(String fruit){
if(fruit.equals("apple")){
return "happy";
}
return "sad";
}
}

public Constructor getConstructor(Class<?>… parameterTypes) :返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
public Constructor<?>[] getConstructors():返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
public Constructor getDeclaredConstructor(Class<?>… parameterTypes):返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
public Constructor<?>[] getDeclaredConstructors():返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
public class RefConstructor {
public static void main(String args[]) throws Exception {
RefConstructor ref = new RefConstructor();
ref.getConstructor();
}
public void getConstructor() throws Exception {
Class c = null;
c = Class.forName("java.util.ArrayList");
Class cs[] = {java.util.Collection.class};
System.out.println("\n-------------------------------\n");
Constructor cst1 = c.getConstructor(cs);
System.out.println("1、通过参数获取指定Class对象的构造方法:");
System.out.println(cst1.toString());
Constructor cst2 = c.getDeclaredConstructor(cs);
System.out.println("2、通过参数获取指定Class对象所表示的类或接口的构造方法:");
System.out.println(cst2.toString());
Constructor cst3 = c.getEnclosingConstructor();
System.out.println("3、获取本地或匿名类Constructor 对象,它表示基础类的立即封闭构造方法。");
if (cst3 != null) System.out.println(cst3.toString());
else System.out.println("-- 没有获取到任何构造方法!");
Constructor[] csts = c.getConstructors();
System.out.println("4、获取指定Class对象的所有构造方法:");
for (int i = 0; i < csts.length; i++) {
System.out.println(csts[i].toString());
}
System.out.println("\n-------------------------------\n");
Type types1[] = c.getGenericInterfaces();
System.out.println("1、返回直接实现的接口:");
for (int i = 0; i < types1.length; i++) {
System.out.println(types1[i].toString());
}
Type type1 = c.getGenericSuperclass();
System.out.println("2、返回直接超类:");
System.out.println(type1.toString());
Class[] cis = c.getClasses();
System.out.println("3、返回超类和所有实现的接口:");
for (int i = 0; i < cis.length; i++) {
System.out.println(cis[i].toString());
}
Class cs1[] = c.getInterfaces();
System.out.println("4、实现的接口");
for (int i = 0; i < cs1.length; i++) {
System.out.println(cs1[i].toString());
}
System.out.println("\n-------------------------------\n");
Field fs1[] = c.getFields();
System.out.println("1、类或接口的所有可访问公共字段:");
if(0==fs1.length){
System.out.println("-- 没有获取到可访问公共字段!");
}else{
for (int i = 0; i < fs1.length; i++) {
System.out.println(fs1[i].toString());
}
}
try {
System.out.println("2、类或接口的指定已声明指定公共成员字段:");
Field f1 = c.getField("MIN_VALUE");
System.out.println(f1.toString());
} catch (Exception e) {
// TODO: handle exception
System.out.println("-- 没有获取到MIN_VALUE公共成员字段!");
}
Field fs2[] = c.getDeclaredFields();
System.out.println("3、类或接口所声明的所有字段:");
for (int i = 0; i < fs2.length; i++) {
System.out.println(fs2[i].toString());
}
Field f2 = c.getDeclaredField("serialVersionUID");
System.out.println("4、类或接口的指定已声明指定字段:");
System.out.println(f2.toString());
System.out.println("\n-------------------------------\n");
Method m1[] = c.getMethods();
System.out.println("1、返回类所有的公共成员方法:");
for (int i = 0; i < m1.length; i++) {
System.out.println(m1[i].toString());
}
try {
System.out.println("2、返回指定公共成员方法:");
Method m2 = c.getMethod("addAll", new Class[]{Collection.class});
System.out.println(m2.toString());
} catch (Exception e) {
// TODO: handle exception
System.out.println("-- 没有获取指定公共成员方法!");
}
try {
System.out.println("3、返回指定公共成员方法:");
Method m2 = c.getMethod("listIterator", new Class[]{});
System.out.println(m2.toString());
} catch (Exception e) {
// TODO: handle exception
System.out.println("-- 没有获取指定公共成员方法!");
}
}
}

获取类、属性、方法的修饰域

类Class、Method、Constructor、Field都有一个public方法int getModifiers()。该方法返回一个int类型的数,表示被修饰对象( Class、 Method、 Constructor、 Field )的修饰类型的组合值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package test;
import java.lang.reflect.Modifier;
public class modifier {
public static String getField(Object owner, String fieldName)throws Exception {
Class cl = owner.getClass();
int mod= cl.getDeclaredField(fieldName).getModifiers();
return Modifier.toString(mod);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Feature feature = new Feature();
try {
System.out.println(modifier.getField(feature, "name"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Feature{
private String name ;
private Integer age ;
private static String org ="baidu";
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}

新建类的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.lang.reflect.Constructor;
public class Instance {
//有参数
public static Object newInstance(String className, Object[] args) throws Exception {
Class cl = Class.forName(className);
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass[i] = args[i].getClass();
}
Constructor cons = cl.getConstructor(argsClass);
return cons.newInstance(args);
}
//无参数
public static Object newInstance(String className) throws Exception {
Class cl = Class.forName(className);
Constructor cons = cl.getDeclaredConstructor();
return cons.newInstance();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Person per1=(Person) Instance.newInstance("test.Person", new Object[]{"tom",12});
System.out.println(per1.getName());
Person per2=(Person) Instance.newInstance("test.Person");
per2.setName("jerry");
System.out.println(per2.getName());
String str = (String) Instance.newInstance("java.lang.String", new Object[]{"abcdef"});
System.out.println(str);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Person{
private String name;
private Integer age;
public Person(){
}
public Person(String name ,Integer age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}

动态创建和访问数组元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package test;
import java.lang.reflect.Array;
public class Arrayreflect
public static void main(String[] args) {
try {
Class<?> classType = Class.forName("java.lang.String");
Object array = Array.newInstance(classType, 10);
Array.set(array, 2, "lucky");
String s =(String) Array.get(array, 2);
System.out.println(s);
Class<?> classType2 = Class.forName("java.lang.String");
int [] dim = new int [] {10,10,10};
Object arrays = Array.newInstance(classType2, dim);
//获取三维数组的第三个数组组件array2Obj,是一个二维数组
Object array2Obj_2d = Array.get(arrays, 3);
//获取array2Obj_2的第二个数组组件,是一个一维数组
Object array2Obj_1d = Array.get(array2Obj_2d, 2);
//设置下标为8的值为abcdf
Array.set(array2Obj_1d, 8, "abcdf");
String arrayCast[][][] = (String[][][]) arrays;
System.out.println(arrayCast[3][2][8]);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

示例代码使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package test;
import java.lang.reflect.Array;
public class GrowArray {
public static Object growArray(Object array ,int size){
Class<?> classtype =array.getClass().getComponentType();
Object arrayObject = Array.newInstance(classtype, size);
System.arraycopy(array, 0, arrayObject, 0, Math.min(Array.getLength(array), size));
return arrayObject;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a= new int[]{1,2,3};
int[] b =(int[]) GrowArray.growArray(a, 5);
System.out.println(b.length);
}
}

动态创建代理类

代理模式:代理模式的作用=为其他对象提供一种代理以控制对这个对象的访问。

代理模式的角色:
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

java.lang.reflect.Proxy Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
InvocationHandler 是代理实例的调用处理程序 实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

动态Proxy是这样的一种类:
​ 它是在运行生成的类,在生成时你必须提供一组Interface给它,然后该class就宣称它实现了这些interface。你可以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

1
2
3
4
5
package proxy;
public interface Subject {
public void Request();
public String Response(String request);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package proxy;
public class RealSubject implements Subject {
@Override
public void Request() {
// TODO Auto-generated method stub
System.out.println("RealSubject");
}
@Override
public String Response(String request) {
// TODO Auto-generated method stub
System.out.println("request : "+request);
if(request.equals("ok")){
return "202";
}else{
return null;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicSubject implements InvocationHandler{
private Object sub;
public DynamicSubject(Object sub) {
this.sub = sub;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Method:"+ method + ",Args:" + args);
return method.invoke(sub, args);
}
public static void main(String[] args) {
RealSubject realSub = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSub);
Class<?> classType = handler.getClass();
/*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
* Subject sub = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),
new Class[]{Subject.class}, handler);
*/
Subject sub = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),
realSub.getClass().getInterfaces(), handler);
System.out.println(sub.getClass());
sub.Request();
System.out.println(sub.Response("ok"));
}
}

另外附录一个例子说明动态代理的用处

我们有一个字体提供类,有多个方法

1
2
3
4
5
6
package ProxyDemo;
public interface FontProvider {
public String getFont(String name);
public void setFont(String size);
public void deleteFont(String name);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package ProxyDemo;
public class FontProviderFromDisk implements FontProvider {
@Override
public String getFont(String name) {
// TODO Auto-generated method stub
System.out.println("字体名字: " +name);
return name + " from Disk";
}
@Override
public void setFont(int size) {
// TODO Auto-generated method stub
System.out.println("set font size : " +size);
}
@Override
public void deleteFont(String name) {
// TODO Auto-generated method stub
System.out.println("delete font name : " +name);
}
}
1
2
3
4
5
6
package ProxyDemo;
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
return new FontProviderFromDisk();
}
}
1
2
3
4
5
6
7
8
9
10
11
package ProxyDemo;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
FontProvider fontProvider = ProviderFactory.getFontProvider();
String font = fontProvider.getFont("微软雅黑");
System.out.println(font);
fontProvider.deleteFont("宋体");
fontProvider.setFont(10);
}
}

现在我们希望给他加上一个日志系统,最直接的对FontProviderFromDisk中的所有方法修改,加入日志,显然这是很繁琐的。另外有两种方式

方法一:静态代理

首先定义LogProvider类,实现FontProvider接口,充当代理,当然也要修改ProviderFactory工厂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package ProxyDemo;
import java.util.logging.Logger;
public class LogProvider implements FontProvider {
private FontProvider fontProvider;
private Logger logger =Logger.getLogger("LogProvider");
public LogProvider(FontProvider fontProvider) {
this.fontProvider = fontProvider;
}
public String getFont(String name) {
logger.info("get Font " + name);
return fontProvider.getFont(name);
}
@Override
public void setFont(int size) {
// TODO Auto-generated method stub
logger.info("set Font size " + size);
fontProvider.setFont(size);
}
@Override
public void deleteFont(String name) {
// TODO Auto-generated method stub
logger.info("delete Font " + name);
fontProvider.deleteFont(name);;
}
}
1
2
3
4
5
6
package ProxyDemo;
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
return new LogProvider(new FontProviderFromDisk());
}
}

问题来了,假如又有一个ImgeProvider接口以及实现类ImgeProviderFromDisk也需要加入日志系统,我们这时要扩展LogProvider,实现ImgeProvider接口。随着越来越多的类需要加入日志系统,代理类LogProvider的实现会越来越繁多。那么动态代理就体现其优越了。

方法二:动态代理

原先接口实现类如ImgeProviderFromDisk,FontProviderFromDisk的代码不需要改动,同时代理类的代码实现后也不需要改动了。相比较静态代理来说,代理类轻松很多了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package ProxyDemo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;
public class LogProvider implements InvocationHandler {
private Object provider;
private Logger logger =Logger.getLogger("LogProvider");
public LogProvider(Object provider) {
this.provider = provider;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
logger.info(method.getName() + args[0].toString());
return method.invoke(provider, args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package ProxyDemo;
import java.lang.reflect.Proxy;
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
Class cl = LogProvider.class;
return (FontProvider) Proxy.newProxyInstance(cl.getClassLoader(),
new Class[] { FontProvider.class }, new LogProvider(new FontProviderFromDisk()));
}
public static ImgeProvider getImgeProvider() {
Class cl = LogProvider.class;
return (FontProvider) Proxy.newProxyInstance(cl.getClassLoader(),
new Class[] { ImgeProvider.class }, new LogProvider(new ImgeProviderFromDisk()));
}
}

参考:

http://lavasoft.blog.51cto.com/62575/43218/

http://blog.csdn.net/yongjian1092/article/details/7364451

http://azrael6619.iteye.com/blog/429797

http://www.cnblogs.com/yaozhongxiao/archive/2013/05/21/3091353.html

http://www.cnblogs.com/lzq198754/p/5780331.html

Luckylau wechat
如果对您有价值,看官可以打赏的!