Java反射机制


Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来。 Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。

JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。


1.实例化Class类对象

package   Reflect;
class   Demo{
     //other codes...
}
 
class   hello{
     public   static   void   main(String[] args) {
         Class<?> demo1= null ;
         Class<?> demo2= null ;
         Class<?> demo3= null ;
         try {
             //一般尽量采用这种形式
             demo1=Class.forName( "Reflect.Demo" );
         } catch (Exception e){
             e.printStackTrace();
         }
         demo2= new   Demo().getClass();
         demo3=Demo. class ;
          
         System.out.println( "类名称   " +demo1.getName());
         System.out.println( "类名称   " +demo2.getName());
         System.out.println( "类名称   " +demo3.getName());
          
     }
}

【运行结果】:

类名称   Reflect.Demo

类名称   Reflect.Demo

类名称   Reflect.Demo


2.通过Class实例化其他类的对象

package   Reflect;
 
class   Person{
      
     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;
     }
     @Override
     public   String toString(){
         return   "[" + this .name+ "  " + this .age+ "]" ;
     }
     private   String name;
     private   int   age;
}
 
class   hello{
     public   static   void   main(String[] args) {
         Class<?> demo= null ;
         try {
             demo=Class.forName( "Reflect.Person" );
         } catch   (Exception e) {
             e.printStackTrace();
         }
         Person per= null ;
         try   {
             per=(Person)demo.newInstance();
         } catch   (InstantiationException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         } catch   (IllegalAccessException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         per.setName( "Rollen" );
         per.setAge( 20 );
         System.out.println(per);
     }
}

【运行结果】:

[Rollen  20]

但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误,所以编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数。

3.通过class取得一个类的全部框架

class   hello {
     public   static   void   main(String[] args) {
         Class<?> demo = null ;
         try   {
             demo = Class.forName( "Reflect.Person" );
         } catch   (Exception e) {
             e.printStackTrace();
         }
         System.out.println( "===============本类属性========================" );
         // 取得本类的全部属性
         Field[] field = demo.getDeclaredFields();
         for   ( int   i = 0 ; i < field.length; i++) {
             // 权限修饰符
             int   mo = field[i].getModifiers();
             String priv = Modifier.toString(mo);
             // 属性类型
             Class<?> type = field[i].getType();
             System.out.println(priv + " "   + type.getName() + " "
                     + field[i].getName() + ";" );
         }
         System.out.println( "===============实现的接口或者父类的属性========================" );
         // 取得实现的接口或者父类的属性
         Field[] filed1 = demo.getFields();
         for   ( int   j = 0 ; j < filed1.length; j++) {
             // 权限修饰符
             int   mo = filed1[j].getModifiers();
             String priv = Modifier.toString(mo);
             // 属性类型
             Class<?> type = filed1[j].getType();
             System.out.println(priv + " "   + type.getName() + " "
                     + filed1[j].getName() + ";" );
         }
     }
}


【运行结果】:

===============本类属性========================

private java.lang.String sex;

===============实现的接口或者父类的属性========================

public static final java.lang.String name;

public static final int age;


4.将反射用于工厂模式

没有使用反射:

interface  fruit{
     public  abstract  void  eat();
}
 
class  Apple implements  fruit{
     public  void  eat(){
         System.out.println( "Apple" );
     }
}
 
class  Orange implements  fruit{
     public  void  eat(){
         System.out.println( "Orange" );
     }
}
 
// 构造工厂类
// 也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class  Factory{
     public  static  fruit getInstance(String fruitName){
         fruit f= null ;
         if ( "Apple" .equals(fruitName)){
             f= new  Apple();
         }
         if ( "Orange" .equals(fruitName)){
             f= new  Orange();
         }
         return  f;
     }
}
class  hello{
     public  static  void  main(String[] a){
         fruit f=Factory.getInstance( "Orange" );
         f.eat();
     }
 
}


使用反射机制:

package  Reflect;
 
interface  fruit{
     public  abstract  void  eat();
}
 
class  Apple implements  fruit{
     public  void  eat(){
         System.out.println( "Apple" );
     }
}
 
class  Orange implements  fruit{
     public  void  eat(){
         System.out.println( "Orange" );
     }
}
 
class  Factory{
     public  static  fruit getInstance(String ClassName){
         fruit f= null ;
         try {
             f=(fruit)Class.forName(ClassName).newInstance();
         } catch  (Exception e) {
             e.printStackTrace();
         }
         return  f;
     }
}
class  hello{
     public  static  void  main(String[] a){
         fruit f=Factory.getInstance( "Reflect.Apple" );
         if (f!= null ){
             f.eat();
         }
     }
}


现在就算我们添加任意多个子类的时候,工厂类就不需要修改。

上面的代码虽然可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。

结合属性文件的工厂模式,首先创建一个fruit.properties的资源文件:

apple=Reflect.Apple

orange=Reflect.Orange


package  Reflect;
 
import  java.io.*;
import  java.util.*;
 
interface  fruit{
     public  abstract  void  eat();
}
 
class  Apple implements  fruit{
     public  void  eat(){
         System.out.println( "Apple" );
     }
}
 
class  Orange implements  fruit{
     public  void  eat(){
         System.out.println( "Orange" );
     }
}
 
//操作属性文件类
class  init{
     public  static  Properties getPro() throws  FileNotFoundException, IOException{
         Properties pro= new  Properties();
         File f= new  File( "fruit.properties" );
         if (f.exists()){
             pro.load( new  FileInputStream(f));
         } else {
             pro.setProperty( "apple" , "Reflect.Apple" );
             pro.setProperty( "orange" , "Reflect.Orange" );
             pro.store( new  FileOutputStream(f), "FRUIT CLASS" );
         }
         return  pro;
     }
}
 
class  Factory{
     public  static  fruit getInstance(String ClassName){
         fruit f= null ;
         try {
             f=(fruit)Class.forName(ClassName).newInstance();
         } catch  (Exception e) {
             e.printStackTrace();
         }
         return  f;
     }
}
class  hello{
     public  static  void  main(String[] a) throws  FileNotFoundException, IOException{
         Properties pro=init.getPro();
         fruit f=Factory.getInstance(pro.getProperty( "apple" ));
         if (f!= null ){
             f.eat();
         }
     }
}


【运行结果】:Apple

参考:
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

http://blog.csdn.net/justinavril/article/details/2873664

你可能感兴趣的:(java,反射机制)