随笔 - 14, 文章 - 39, 评论 - 17, 引用 - 0
数据加载中……

JAVA的反射 (转)

JAVA的反射库提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵JAVA代码的程序,这项功能被大量的应用在JavaBeans中,他是JAVA的组建体系结构。

JAVA中的代理可以在运行时创建一个实现一组接口的新类,这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用,对于应用程序设计人员来说,遇到这种情况的机会很少。然而对于系统程序设计人员来说,代理带来的灵活性却十分重要。                                                              ---摘自《JAVA核心技术卷2》

有一些初学者对反射和代理有一点害怕,觉得这是高深的技术,不敢去碰,其实任何东西都没有那么复杂,只要你去接触,就会有收获,这篇文章主要讲解了反射和代理、AOP方面的知识,但是非常基本,如果有朋友不太明白可以发表评论,我会认真的解答的,下面我贴上两个程序的代码,很简单大家看一下。

--------------------------------------------------

/**
 *这个程序的功能是通过反射技术得到一个类(SrcClass)的两个String类型的成员变量
 *然后经过判断对字符串进行处理
 *这个题目的特点:通过对API的阅读了解Class类的使用方法
 *1、getDeclaredFields()得到所有的成员变量
 *2、Field类中的一些方法getType()
 *3、Field类继承于AccessibleObject类,有一个setAccessible()方法,查看API得到他的用途
 **/
import java.lang.reflect.Field;
class SrcClass
{
 private String name = "BeiJing.2008";//定义来两个String类型的变量,访问修饰都是私有的
 private String eMail = "BeiJing.2008@163.com";
 private int age = 25;
 
 
 public String toString()//覆盖父类的toString方法,打印数据
 {
  return "Name:[ " + this.name + " ] EMail: [ " + this.eMail + " ] Age: [ " + this.age + " ]";
 }
}

public class TestClass
{


 public static void main(String[] args)
 {
  SrcClass srcclass = new SrcClass();//首先实例化一个SrcClass类的实例,用于给amendString方法传值
  TestClass testclass = new TestClass();//再实力化一个TestClass的实例
  
  System.out.println(srcclass);//打印一遍原始信息

  
  testclass.amendString(srcclass);//调用amendString方法
  System.out.println(srcclass);//打印一遍修改后的信息

 }
 
 
 public void amendString(Object cls)//用于修改通过代理得到srcclass的String成员变量,进行替换处理
 {
  try
  {
   Field[] fidles = cls.getClass().getDeclaredFields();//得到srcclass.getClass()类中的所有成员变量
   for(Field field : fidles)//增强for循环
   {
    if(field.getType().equals(java.lang.String.class))//判断这个成员变量的类型是不是String类型的
    {                                                 //如果返回true就进行处理
     field.setAccessible(true);//设置这个变量不进行访问权限检查(我在SrcClass里设置的变量为private)
     String newString = (String)field.get(cls);//通过Field类的get方法得到String成员变量
     
     field.set(cls,newString.replaceAll("BeiJing","China"));//进行替换,再调用Field类的set方法进行修改
    }
   }
  }
  
  catch(SecurityException e)//
  {
   e.printStackTrace();
  }
  
  catch (IllegalArgumentException e)
  {
   
   e.printStackTrace();
  }
  
  catch (IllegalAccessException e)
  {
   
   e.printStackTrace();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }

}

------------------------------------------------

下面就是代理了,实现代理必须有4个类(一个接口3各类)

public interface FooInterface {
    public String printMassage();
}

---------------------------------------------

class ImplementFoo implements FooInterface {
    
      public String printMassage()
    {
               return "This is ImplementFoo ...";
    }
}

 

---------------------------------------------

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date;

class ImplementInvocationHandler implements InvocationHandler
{
    private Object foo;

    public ImplementInvocationHandler(Object foo) //获得将要运行类的实际对象
    {
       this.foo = foo;   
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable //
    {
        System.out.println("You want use " + proxy.getClass().getName() + "." + 

                                          method.getName() + " at " + new Date());
        return   method.invoke(foo);//方法调用
    }
   
}

---------------------------------------------

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
/**
 *   InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });

 *
 */
public class TestProxy {
   
 
    public static void main(String[] args)
    {
        ImplementFoo foo = new ImplementFoo();//实例化一个实现了FooInterface(自己定义的)接口的类
        InvocationHandler handler = new ImplementInvocationHandler(foo);
        //自己编写实现InvocationHandler接口的类
        //并且将他实例化,ImplementInvocationHandler类中有一个构造函数需要接受一个ImplementFoo类的对象,  因为我们将来
        //要使用ImplementFoo.printMassage方法,ImplementInvocationHandler类方法invoke中的method.invoke(foo)
        //需要知道他将调用谁的printMassage方法,所以我们要给ImplementInvocationHandler类传递一个ImplementFoo类的对象
       
         Class proxyClass = Proxy.getProxyClass(FooInterface.class.getClassLoader(),FooInterface.class);
        //此时我们就要制造出一个代理类了,使用Proxy类的静态方法getProxyClass,查看API得到答案
       
          FooInterface f;
        try
        {
      
            f =  (FooInterface) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(handler);
            System.out.println(f.hashCode());//动态实例化出一个代理类,并且调用他的hashCode、printMassage方法
            System.out.println(f.printMassage());
          
        } catch (SecurityException ex) {
            ex.printStackTrace();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
 
    }
   
}



posted on 2006-09-29 11:56 mlw2000 阅读(223) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: