java反射实例详解

来源:互联网 发布:淘宝刷王者荣耀贵族8 编辑:程序博客网 时间:2024/05/23 14:06
本文先讲java反射的示例代码,希望看了代码以及分析对你有所帮助。 
【案例1】通过一个对象获得完整的包名和类名


package org.shen.own; 

import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.Hashtable; 

public class Hash { 
... 


package org.shen.own; 
public class Reflect { 
public static void main(String[] args) { 
Hash hash = new Hash(); 
System.out.println(hash.getClass().getName()); 



程序运行结果:org.shen.own.Hash 
补充一句:所有类的对象其实都是Class的实例。 

【案例2】实例化Class类对象

Hash代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. public class Reflect {  
  4.     public static void main(String[] args) {  
  5.         Class<?> hash1 = null;  
  6.         Class<?> hash2 = null;  
  7.         Class<?> hash3 = null;  
  8.           
  9.         try {  
  10.             hash1 = Class.forName("org.shen.own.Hash");  //返回与带有给定字符串名的类或接口相关联的 Class 对象  
  11.         } catch (ClassNotFoundException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.         hash2 = new Hash().getClass();  
  15.         hash3 = Hash.class;  
  16.           
  17.         System.out.println(hash1.getName());  
  18.         System.out.println(hash2.getName());  
  19.         System.out.println(hash3.getName());  
  20.     }  
  21. }  


运行结果: 
org.shen.own.Hash 
org.shen.own.Hash 
org.shen.own.Hash 

【案例3】通过Class实例化其他类的对象

Person代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. public class Person {  
  4.     private int age;  
  5.     private String name;  
  6.     public int getAge() {  
  7.         return age;  
  8.     }  
  9.     public void setAge(int age) {  
  10.         this.age = age;  
  11.     }  
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.     @Override  
  19.     public String toString() {  
  20.         return "Person [age=" + age + ", name=" + name + "]";  
  21.     }  
  22.       
  23.       
  24. }  


Reflect代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. public class Reflect {  
  4.     public static void main(String[] args) {  
  5.     Class<?> demo = null;  
  6.     try {  
  7.         demo = Class.forName("org.shen.own.Person");  
  8.     } catch (ClassNotFoundException e) {  
  9.         e.printStackTrace();  
  10.     }  
  11.     Person person = null;  
  12.     try {  
  13.         person = (Person)demo.newInstance();//这里不实例化  会报空指针异常  
  14.     } catch (InstantiationException e) {  
  15.         e.printStackTrace();  
  16.     } catch (IllegalAccessException e) {  
  17.         e.printStackTrace();  
  18.     }  
  19.     person.setAge(20);  
  20.     person.setName("shen");  
  21.     System.out.println(person);  
  22.       
  23.     }  
  24. }  


输出结果:Person [age=20, name=shen] 

但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误: 
Person构造函数代码  收藏代码
  1. public Person(int age, String name) {  
  2.     super();  
  3.     this.age = age;  
  4.     this.name = name;  
  5. }  


如下错误: 

错误代码  收藏代码
  1. java.lang.InstantiationException: org.shen.own.Person  
  2.     at java.lang.Class.newInstance0(Class.java:340)  
  3.     at java.lang.Class.newInstance(Class.java:308)  
  4.     at org.shen.own.Reflect.main(Reflect.java:13)  
  5. Exception in thread "main" java.lang.NullPointerException  
  6.     at org.shen.own.Reflect.main(Reflect.java:19)  


所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数 
【案例】通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象) 

示例代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4. import java.lang.reflect.InvocationTargetException;  
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) {  
  8.         Class<?> demo = null;  
  9.         try {  
  10.             demo = Class.forName("org.shen.own.Person");  
  11.         } catch (ClassNotFoundException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.           
  15.         Person per1 = null;  
  16.         Person per2 = null;  
  17.         Person per3 = null;  
  18.         Person per4 = null;  
  19.           
  20.         Constructor<?>[] cons = demo.getConstructors();//获取实体类的构造函数  共有四个  
  21.         int i;  
  22.         for(i=0;i<cons.length;i++){  
  23.             System.out.println(cons[i]);  
  24.         }  
  25.           
  26.         try {  
  27.             per1 = (Person) cons[0].newInstance(20);  
  28.             per2 = (Person) cons[1].newInstance();  
  29.             per3 = (Person) cons[2].newInstance("shenyc");  
  30.             per4 = (Person) cons[3].newInstance(20,"shenyc");  
  31.         } catch (InstantiationException e) {  
  32.             e.printStackTrace();  
  33.         } catch (IllegalAccessException e) {  
  34.             e.printStackTrace();  
  35.         } catch (IllegalArgumentException e) {  
  36.             e.printStackTrace();  
  37.         } catch (InvocationTargetException e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.         System.out.println(per1);  
  41.         System.out.println(per2);  
  42.         System.out.println(per3);  
  43.         System.out.println(per4);  
  44.     }  
  45. }  


运行结果: 
public org.shen.own.Person(int) 
public org.shen.own.Person() 
public org.shen.own.Person(java.lang.String) 
public org.shen.own.Person(int,java.lang.String) 
Person [age=20, name=null] 
Person [age=0, name=null] 
Person [age=0, name=shenyc] 
Person [age=20, name=shenyc] 
『案例』返回一个类实现的接口:

接口示例代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. public class Person1 implements China{  
  4.   
  5.     public Person1(){}  
  6.     public Person1(String sex){  
  7.         this.sex = sex;  
  8.     }  
  9.     @Override  
  10.     public void sayChina() {  
  11.         System.out.println("say ,hello , china!");  
  12.     }  
  13.   
  14.     @Override  
  15.     public void sayHello(String name, int age) {  
  16.         System.out.println(name + "   ---  " + age);  
  17.     }  
  18.     private String sex;  
  19.     public String getSex() {  
  20.         return sex;  
  21.     }  
  22.   
  23.     public void setSex(String sex) {  
  24.         this.sex = sex;  
  25.     }  
  26.       
  27.       
  28. }  
  29.   
  30.   
  31. package org.shen.own;  
  32.   
  33. public interface China {  
  34.     public static final String name = "Shenyc";  
  35.     public static int age = 20;  
  36.     public void sayChina();  
  37.     public void sayHello(String name,int age);  
  38. }  
  39.   
  40.   
  41.   
  42. package org.shen.own;  
  43.   
  44.   
  45. public class Reflect {  
  46.     public static void main(String[] args) {  
  47.     Class<?> cls = null;  
  48.     try {  
  49.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  50.     } catch (ClassNotFoundException e) {  
  51.         e.printStackTrace();  
  52.     }  
  53.       
  54.     Class<?> inters[] = cls.getInterfaces();  //拿到接口  
  55.     int i=0;  
  56.     for(;i<inters.length;i++){  
  57.         System.out.println(inters[i]);  
  58.     }  
  59.     }  
  60. }  


运行结果:interface org.shen.own.China 

得到Person1的父类: 
父类代码  收藏代码
  1. package org.shen.own;  
  2.   
  3.   
  4. public class Reflect {  
  5.     public static void main(String[] args) {  
  6.     Class<?> cls = null;  
  7.     try {  
  8.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  9.     } catch (ClassNotFoundException e) {  
  10.         e.printStackTrace();  
  11.     }  
  12.     System.out.println(cls.getSuperclass().getName());//拿到父类的名字  
  13.     Class<?> inters[] = cls.getInterfaces();  //拿到接口  
  14.     int i=0;  
  15.     for(;i<inters.length;i++){  
  16.         System.out.println(inters[i]);  
  17.     }  
  18.     }  
  19. }  


【案例】:获得其他类中的全部构造函数

例子代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4.   
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) {  
  8.     Class<?> cls = null;  
  9.     try {  
  10.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  11.     } catch (ClassNotFoundException e) {  
  12.         e.printStackTrace();  
  13.     }  
  14.     Constructor<?>[] cons = cls.getConstructors();  
  15.       
  16.     int i=0;  
  17.     for(;i<cons.length;i++){  
  18.         System.out.println(cons[i]);  
  19.     }  
  20.     }  
  21. }  


运行结果: 
public org.shen.own.Person1() 
public org.shen.own.Person1(java.lang.String) 

后面各个案例中都将使用Person1这个类。 

下面这个例子我们就来获取修饰符

获取修饰符代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4. import java.lang.reflect.Modifier;  
  5.   
  6.   
  7. public class Reflect {  
  8.     public static void main(String[] args) {  
  9.     Class<?> cls = null;  
  10.     try {  
  11.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  12.     } catch (ClassNotFoundException e) {  
  13.         e.printStackTrace();  
  14.     }  
  15.     Constructor<?>[] cons = cls.getConstructors();  
  16.       
  17.     int i=0;  
  18.     for(;i<cons.length;i++){  
  19.         Class<?> params[] = cons[i].getParameterTypes();  
  20.   
  21.         System.out.print("构造方法:");   
  22.         int mo = cons[i].getModifiers();//以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。应该使用 Modifier 类对这些修饰符进行解码。  
  23.         //System.out.println(mo);  //1  
  24.         System.out.print(Modifier.toString(mo)+" ");  //public  得到修饰符public  
  25.         System.out.print(cons[i].getName());    //得到构造函数的名字  pkg+calss 即 org.shen.own.Person1  
  26.         System.out.print("(");  
  27.           
  28.         //拿参数  
  29.         for(int j=0;j<params.length;++j){  
  30.             //System.out.println(params[j]);  
  31.             System.out.print(params[j].getName()+" arg"+i);  
  32.             if(j<params.length-1){  
  33.                 System.out.print(",");  
  34.             }  
  35.         }  
  36.         System.out.println("){}");  
  37.           
  38.           
  39.     }  
  40.       
  41.       
  42.     }  
  43. }  


运行结果: 
构造方法:public org.shen.own.Person1(){} 
构造方法:public org.shen.own.Person1(java.lang.String arg1){} 


有时候一个方法可以抛出异常,如下面的例子:

抛出异常的方法代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) {  
  8.     Class<?> cls = null;  
  9.     try {  
  10.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  11.     } catch (ClassNotFoundException e) {  
  12.         e.printStackTrace();  
  13.     }  
  14.   
  15.     Method method[] = cls.getMethods();  
  16.     int i=0;  
  17.     for(;i<method.length;i++){  
  18.         System.out.println(method[i]);  
  19.     }  
  20.           
  21.     }  
  22. }  


输出结果: 
public void org.shen.own.Person1.sayChina()  //Person1里面的方法 
public void org.shen.own.Person1.sayHello(java.lang.String,int)//Person1里面的方法 
public java.lang.String org.shen.own.Person1.getSex()//Person1里面的方法 
public void org.shen.own.Person1.setSex(java.lang.String)//Person1里面的方法 
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException 
public final void java.lang.Object.wait() throws java.lang.InterruptedException 
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException 
public boolean java.lang.Object.equals(java.lang.Object) 
public java.lang.String java.lang.Object.toString() 
public native int java.lang.Object.hashCode() 
public final native java.lang.Class java.lang.Object.getClass() 
public final native void java.lang.Object.notify() 
public final native void java.lang.Object.notifyAll() 

 【案例】接下来让我们取得其他类的全部属性吧,最后我讲这些整理在一起,也就是通过class取得一个类的全部框架

取得全部属性代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Field;  
  4. import java.lang.reflect.Modifier;  
  5.   
  6.   
  7.   
  8. public class Reflect {  
  9.     public static void main(String[] args) {  
  10.     Class<?> cls = null;  
  11.     try {  
  12.         cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  13.     } catch (ClassNotFoundException e) {  
  14.         e.printStackTrace();  
  15.     }  
  16.     Field field[] = cls.getDeclaredFields();  //输出private java.lang.String org.shen.own.Person1.sex  
  17.       
  18.     Field f[] = cls.getFields();  //得到父类或者接口的字段 属性  
  19.     for(int i=0;i<field.length;i++){  
  20.         int mo = field[i].getModifiers();  
  21.         String p = Modifier.toString(mo);  
  22.         System.out.println(p);  
  23.         System.out.println(field[i]);  
  24.     }  
  25.     for(int j=0;j<f.length;j++){  
  26.         int mo = f[j].getModifiers();  
  27.         String p = Modifier.toString(mo);  
  28.         System.out.println(p);  
  29.         System.out.println(f[j]);  
  30.     }  
  31.     }  
  32. }  


运行结果: 
private 
private java.lang.String org.shen.own.Person1.sex 
public static final 
public static final java.lang.String org.shen.own.China.name 
public static final 
public static final int org.shen.own.China.age 
【案例】其实还可以通过反射调用其他类中的方法:

通过发射调用其他类的方法代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.InvocationTargetException;  
  4. import java.lang.reflect.Method;  
  5.   
  6.   
  7. public class Reflect {  
  8.     public static void main(String[] args) {  
  9.         Class<?> cls = null;  
  10.         try {  
  11.             cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  12.         } catch (ClassNotFoundException e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.         try {  
  16.             Method method = cls.getMethod("sayChina");  //invoke Person1's sayChina method  
  17.             method.invoke(cls.newInstance());  
  18.             System.out.println(method);  
  19.               
  20.             Method m = cls.getMethod("sayHello", String.class,int.class);  
  21.             m.invoke(cls.newInstance(), "shenyc",20);  
  22.             System.out.println(m);  
  23.         } catch (SecurityException e) {  
  24.             e.printStackTrace();  
  25.         } catch (NoSuchMethodException e) {  
  26.             e.printStackTrace();  
  27.         } catch (IllegalArgumentException e) {  
  28.             e.printStackTrace();  
  29.         } catch (IllegalAccessException e) {  
  30.             e.printStackTrace();  
  31.         } catch (InvocationTargetException e) {  
  32.             e.printStackTrace();  
  33.         } catch (InstantiationException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37. }  

运行结果: 
say ,hello , china! 
public void org.shen.own.Person1.sayChina() 
shenyc   ---  20 
public void org.shen.own.Person1.sayHello(java.lang.String,int) 

【案例】调用其他类的set和get方法

调用其他类的set和get方法代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) throws Exception {  
  8.         Class<?> cls = null;  
  9.         try {  
  10.             cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  11.         } catch (ClassNotFoundException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.         Object o =cls.newInstance();  //Person1  
  15.           
  16.         setter(o,"Sex","shenyc",String.class);  
  17.         getter(o,"Sex");  
  18.           
  19.     }  
  20.       
  21.     //使用Person1中的get方法  
  22.     private static void getter(Object o,String attr) throws Exception{  
  23.   
  24.         Method method = o.getClass().getMethod("get"+attr);  
  25.         System.out.println(method.invoke(o));  
  26.   
  27.     }  
  28.       
  29.     //使用Person1中的set方法  
  30.     public static void setter(Object o,String att,String value,Class<?> type) throws Exception{  
  31.         Method method = o.getClass().getMethod("set"+att, type);  
  32.         method.invoke(o, value);  
  33.     }  
  34. }  


运行结果:shenyc 

【案例】通过反射操作属性

通过反射操作属性代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Field;  
  4.   
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) throws Exception {  
  8.         Class<?> cls = null;  
  9.         try {  
  10.             cls = Class.forName("org.shen.own.Person1");  //拿到Person1  
  11.         } catch (ClassNotFoundException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.         Object o = cls.newInstance();  
  15.         Field field[] = cls.getDeclaredFields();  //本例只有一个字段属性  所以不再使用遍历了  
  16.         field[0].setAccessible(true);  //不设置可访问,那么回报错误:自己可以试试  
  17.         field[0].set(o, "男");  
  18.         System.out.println(field[0].get(o));  
  19.     }  
  20. }  


【案例】通过反射取得并修改数组的信息:

通过反射取得并修改数组的信息代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Array;  
  4. import java.lang.reflect.Modifier;  
  5. public class Reflect {  
  6.     public static void main(String[] args) throws Exception {  
  7.         int[] array = {1,2,3,4,5};  
  8.         Class<?> cls = array.getClass().getComponentType();  //返回表示数组组件类型的 Class。如果此类不表示数组类,则此方法返回 null。  
  9.         //System.out.println(cls);  //输出int  
  10.         //数组的修饰符有点意思,有时间大家可以去研究一下  
  11.         System.out.println("数组类型:"+cls.getName()+ " 数组修饰符:"+Modifier.toString(cls.getModifiers()));  
  12.         System.out.println("array's length:"+Array.getLength(array));  
  13.         System.out.println("the first element of array:" + Array.get(array, 0));  
  14.         Array.set(array, 0100);  
  15.         System.out.println("修改后数组的第一个元素:"+Array.get(array, 0));  
  16.     }  
  17. }  


【案例】通过反射修改数组大小
通过反射修改数组大小代码  收藏代码
  1. package org.shen.own;  
  2.   
  3. import java.lang.reflect.Array;  
  4.   
  5.   
  6. public class Reflect {  
  7.     public static void main(String[] args) throws Exception {  
  8.         int[] array = {1,2,3,4,5,6,7,8,9};  
  9.         int[] newArr = (int[]) modifyArrayLength(array, 15);  
  10.         print(newArr);  
  11.         System.out.println();  
  12.         String[] arr = {"a","b","c"};  
  13.         String[] newArrStr = (String[])modifyArrayLength(arr, 15);  
  14.         print(newArrStr);  
  15.     }  
  16.       
  17.     //修改数组的大小  
  18.     public static Object modifyArrayLength(Object o,int length){  
  19.         //使用反射先拿到数组  
  20.         Class<?> c = o.getClass().getComponentType();  
  21.         Object newObj = Array.newInstance(c, length);  //新数组  
  22.           
  23.           
  24.         int l = Array.getLength(o);  
  25.         System.arraycopy(o, 0, newObj, 0, l);  
  26.         return newObj;  
  27.     }  
  28.     //输出数组  
  29.     public static void print(Object o){  
  30.         if(o==null){  
  31.             System.out.println("数组是空的");  
  32.             return;  
  33.         }  
  34.         Class<?> cls = o.getClass();  
  35.         if(!cls.isArray()){  
  36.             System.out.println("你所输入的不是数组");  
  37.             return;  
  38.         }  
  39.         System.out.println("数组的长度为:"+Array.getLength(o));  
  40.         System.out.print("数组是: ");  
  41.         for(int i=0;i<Array.getLength(o);i++){  
  42.             System.out.print(Array.get(o, i)+",");  
  43.         }  
  44.     }  
  45. }  

运行结果: 
数组的长度为:15 
数组是: 1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 
数组的长度为:15 
数组是: a,b,c,null,null,null,null,null,null,null,null,null,null,null,null, 

动态代理 【案例】首先来看看如何获得类加载器:

获得类加载器代码  收藏代码
  1. package org.shen.own;  
  2. public class Test {  
  3.   
  4. }  
  5.   
  6. package org.shen.own;  
  7.   
  8. public class Hello {  
  9.     public static void main(String[] args) {  
  10.         Test t =  new Test();  
  11.         System.out.println("类加载器:"+ t.getClass().getClassLoader().getClass().getName());  
  12.     }  
  13. }  


输出结果: 
类加载器:sun.misc.Launcher$AppClassLoader 


分析: 
其实在Java中有三类加载器: 
1.Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 
2.Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类 
3.AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 


动态代理
如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。 
动态代理 
http://shenyuc629.iteye.com/blog/1697485 


类的生命周期 

在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。 

类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前 

链接就是把二进制数据组装为可以运行的状态。 



链接分为校验,准备,解析这3个阶段 

校验一般用来确认此二进制文件是否适合当前的JVM(版本), 

准备就是为静态成员分配内存空间,。并设置默认值 

解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系) 

完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。 

当没有任何引用指向Class对象时就会被卸载,结束类的生命周期 

使用反射实现工厂模式

Apple 代码  收藏代码
  1. package org.shen.factory;  
  2.   
  3. public class Apple implements Fruit{  
  4.   
  5.     @Override  
  6.     public void eat() {  
  7.         System.out.println("我在吃苹果");      
  8.     }  
  9. }  

Banana 代码  收藏代码
  1. [  
  2. package org.shen.factory;  
  3.   
  4. public class Banana implements Fruit{  
  5.   
  6.     @Override  
  7.     public void eat() {  
  8.         System.out.println("我在吃香蕉");      
  9.     }  
  10. }  
  11.   
  12. /code]  
  13.   
  14. <pre class="Fruit" name="code">package org.shen.factory;  
  15.   
  16. public interface Fruit {  
  17.     public abstract void eat();  
  18. }  
  19.   
  20. </pre>  
  21. <br>  
  22. <br><pre class="FactoryReflect " name="code">package org.shen.factory.reflect;  
  23.   
  24. import org.shen.factory.Fruit;  
  25.   
  26. public class FactoryReflect {  
  27.       
  28.     public static Object getInstance(String name){  
  29.         Fruit f = null;  
  30.         try {  
  31.             f = (Fruit) Class.forName(name).newInstance();  
  32.         } catch (InstantiationException e) {  
  33.             e.printStackTrace();  
  34.         } catch (IllegalAccessException e) {  
  35.             e.printStackTrace();  
  36.         } catch (ClassNotFoundException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.         return f;  
  40.     }  
  41.       
  42.       
  43. }  
  44.   
  45. </pre>  
  46. <br>  
  47. <br><pre class="TestRF " name="code">package org.shen.factory.reflect;  
  48.   
  49. import org.shen.factory.Fruit;  
  50.   
  51. public class TestRF {  
  52.     public static void main(String[] args) {  
  53.         Fruit f = (Fruit) FactoryReflect.getInstance("org.shen.factory.Apple");  
  54.         if(f!=null){  
  55.             f.eat();  
  56.         }  
  57.           
  58.     }  
  59. }  
  60.   
  61. </pre>  
  62. <br>  
  63. <br>现在就算我们添加任意多个子类的时候,工厂类就不需要修改。  
  64. <br>  
  65. <br>上面的代码虽然可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。  
  66. <br>  
  67. <br>  
原创粉丝点击