<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>heshencao</title>
    <description></description>
    <link>http://heshencao.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title> 设计模式的例子</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/237547" style="color:red;">http://heshencao.javaeye.com/blog/237547</a>&nbsp;
          发表时间: 2008年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">////////////////////////////////////////////////////////////////////

创建模式

////////////////////////////////////////////////////////////////////


//FactoryMethod模式的例子 

package pattern.a.factoryMethod;

interface Product {
  
  void operation();

}

class ConProduct1 implements Product {
  
  //不同的实现可以有不同的产品操作
  public void operation() {}

}

class ConProduct2 implements Product {
  
  //不同的实现可以有不同的产品操作
  public void operation() {}

}


interface Factory {
  
  Product CreateProduct();

  void operation1();
  
}

class ConFactory1 implements Factory {
  
  //不同的实体场类 在创建产品是可以有不能的创建方法
  public Product CreateProduct() {
      Product product = new ConProduct1();
      operation1();
      return product;
  }
  
  public void operation1() {}

  public static Factory getFactory() {
      return new ConFactory1();
  }
}

class ConFactory2 implements Factory {
  
  //不同的实体场类 在创建产品是可以有不能的创建方法
  public Product CreateProduct() {
      Product product = new ConProduct2();
      operation1();
      return product;
  }
  
  public void operation1() {}

  //
  public static Factory getFactory() {
      return new ConFactory2();
  }
}

public class FactoryMethod {
  public static void main(String[] args) {
      Factory factory = ConFactory1.getFactory();
      Product product = factory.CreateProduct();
      product.operation();
  }
}


***********************************************************************


//AbstractoryFactory模式的例子 
//我觉得这个模式与FactoryMethod 就是创建产品的数量上有区别

package pattern.a.abstractfactory;

//产品A的接口和实现
interface ProductA {}

class ProductA1 implements ProductA {}

class PorductA2 implements ProductA {}

//产品B的接口和实现
interface ProductB {}

class ProductB1 implements ProductB {}

class ProductB2 implements ProductB {}

//工程和工厂的实现
interface Factory {
    
    ProductA CreateA();
    
    ProductB CreateB();

}

//1工厂产生1系列产品
class ConFactory1 implements Factory {
    
    public ProductA CreateA() {
        return new ProductA1();
    }
    
    public ProductB CreateB() {
        return new ProductB1();
    }
    
}

//2工厂产生2系列产品
class ConFactory2 implements Factory {
    
    public ProductA CreateA() {
        return new PorductA2();
    }
    
    public ProductB CreateB() {
        return new ProductB2();
    }
    
}

class ConFactory {}

public class AbstractFactory {

    public static void main(String[] args) {
        //1工厂产生1类产品
        Factory factory1 = new ConFactory1();
        ProductA a1 = factory1.CreateA();
        ProductB b1 = factory1.CreateB();
        
        //2工厂产生2类产品
        Factory factory2 = new ConFactory1();
        ProductA a2 = factory2.CreateA();
        ProductB b2 = factory2.CreateB();        
    }
}


***********************************************************************


//Builder模式的例子
// 模式的宗旨是 将部件创建的细节 和部件的组装方法分离!!! 考兄弟悟性要高

package pattern.a.builder;

class director {
    
    //construct 中存放着组装部件的逻辑 注意 逻辑的分离 
    public Product construct(Builder builder) {
        builder.buildPart1();
        builder.buildPart2();
        operation();
        Product product = builder.retrieveProduct();
        return product;
    }
    
    public void operation() {}
}

class Product {}

interface Builder {
    
    void buildPart1();
    
    void buildPart2();
    
    Product retrieveProduct();
    
}

class ConBuilder1 implements Builder {
    
    public void buildPart1() {}
    
    public void buildPart2() {}
    
    public Product retrieveProduct() {
        return null;
    }
    
}

class ConBuilder2 implements Builder {
    
    public void buildPart1() {}
    
    public void buildPart2() {}
    
    public Product retrieveProduct() {
        return null;
    }    
    
}

public class BuilderPattern {

    public static void main(String[] args) {
    }
    
}


***********************************************************************


//Singleton模式例子

package pattern.a.singleton;

// 一种简单的形式
class SingletonExample {
 
 private static SingletonExample instance;
 
 private SingletonExample() {}
 
 public static SingletonExample getInstance() {
  
  if (instance == null) {
   instance = new SingletonExample();
  }
  return instance;
 }  
 
 synchronized public static SingletonExample getInstance1() {
  
  if (instance == null) {
   instance = new SingletonExample();
  }
  return instance;
  
 } 
 
 public static SingletonExample getInstance2() {
  
  synchronized(SingletonExample.class) {
   if (instance == null) {
    instance = new SingletonExample();
   }
  }
  return instance;
  
 }
}

//利用类加载时 初始化只产生一次
class SingletonExample2 {
 
 private static SingletonExample2 instance = new SingletonExample2();
 
 private SingletonExample2() {}
 
 public static SingletonExample2 getInstance() {
  
  return instance;
  
 }
}

public class SingletonPattern {

 public static void main(String[] args) {
 }
}


***********************************************************************


//Prototype模式例子

package pattern.a.prototype;

interface Prototype {
    Prototype myclone();
}

class ConPrototype1 implements Prototype{
    private String a;
    
    public ConPrototype1(String a) {
        this.a = a;
    }
    
    public Prototype myclone() {
        return new ConPrototype1(a);
    }
}

class ConPrototype2 implements Prototype{
    private int b;
    
    public ConPrototype2(int b) {
        this.b = b;
    }
    
    public Prototype myclone() {
        return new ConPrototype2(b);
    }
}

public class PrototypePattern {
    public static void main(String[] args) {
        Prototype inst1 = new ConPrototype1("testStr1");
        Prototype inst2 = null;
        inst2 = inst1.myclone();
    }
}


***********************************************************************


////////////////////////////////////////////////////////////////////

结构模式

////////////////////////////////////////////////////////////////////


//Adapter模式的例子

package pattern.b.Adapter;

// 类适配
interface Target1 {
 
 void request();
 
}

class Adaptee1 {
 
    public void specRequest() {}

}

class Adapter1 extends Adaptee1 implements Target1 {

 public void request() {
  super.specRequest();
 }

}

//对象适配

interface Target2 {
 
 void request();

}

class Adaptee2 {

    public void specRequest() {}

}

class Adapter2 implements Target2 {

 private Adaptee2 adaptee;
 
 public Adapter2(Adaptee2 adaptee) {
  this.adaptee = adaptee;
 }
 
 public void request() {
     adaptee.specRequest();
 }

}

public class AdapterPattern {

 public static void main(String[] args) {
 }
 
}


***********************************************************************


//Proxy模式例子

package pattern.b.proxy;

interface Subject {
 
 void request();
 
}

//真正处理请求的地方
class RealSubject implements Subject {
 
 public void request() {
  
  System.out.println("real access");
  
 }
 
}

//ProxySubject是与用户交互的类 他是REalSubject的代理
//在处理功能之上的一层  这里可以做前操作 后操作 例如可以验证是否处理请求。
class ProxySubject implements Subject {
 
 private RealSubject real;
 
 public ProxySubject(RealSubject real) {
  this.real = real;
 }
 
 //
 public void request() {
  
  preRequest();
  real.request();
  afterRequest();
  
 }
 
 private void preRequest() {}
 
 private void afterRequest() {}
 
}


//java自身提供代理类使用反射机制

public class ProxyPattern {

 public static void main(String[] args) {
 }

}

***********************************************************************


//Composite 模式例子
//在用户的角度 并不知道 不见是单独的还是符合的 只要调用接口级方法 operation 

package pattern.b.composite;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

// 安全模式 在接口级只提供部分功能 leaf 和 composite 有不同的功能
interface Component1 {
    
    public void operation();
    
}

class leaf1 implements Component1 {
    
    public void operation() {
        System.out.println("this is the leaf1");
    }
    
}

class Composite1 implements Component1 {
    private List components;
    
    public Composite1() {
        components = new ArrayList();
    }
    
    public void operation() {
        Iterator it = components.iterator();
        Component1 com = null;
        while (it.hasNext()) {
            com = (Component1) it.next();
            com.operation();
        }
    }
    
    public void addComponent(Component1 com) {
        components.add(com);
    }
    
    public void removeComponent(int index) {
        components.remove(index);
    }
    
}

// 透明模式 接口定义全部功能 leaf中可能使用空方法或抛出异常 活着写一层 抽象类 写上默认实现方法(极端情况下 是空或异常)


interface Component2 {
    
    public void operation();
    
    public void addComponent(Component2 com);
    
    public void removeComponent(int index);
    
}

class leaf2 implements Component2 {
    
    public void operation() {
        System.out.println("this is the leaf1");
    }
    
    //这个使用空方法
    public void addComponent(Component2 com) {}
    
    //这个使用不支持异常
    public void removeComponent(int index){
        throw new UnsupportedOperationException();
    }
}

class Composite2 implements Component2 {
    private List components;
    
    public Composite2() {
        components = new ArrayList();
    }
    
    public void operation() {
        Iterator it = components.iterator();
        Component2 com = null;
        while (it.hasNext()) {
            com = (Component2) it.next();
            com.operation();
        }
    }
    
    public void addComponent(Component2 com) {
        components.add(com);
    }
    
    public void removeComponent(int index) {
        components.remove(index);
    }
    
}

//也可以用一个抽象类

abstract class AbstractComponent implements Component2{
    public void operation() {}
    
    public void addComponent(Component2 com) {}
    
    abstract public void removeComponent(int index);    
}

public class CompositePattern {

    public static void main(String[] args) {
    }
    
}


***********************************************************************


//Flywight 模式例子
// 将共同的跟不同的属性分离  共享共同属性 而不同属性由外部传入 进行特定操作

package pattern.b.flyweight;
import java.util.HashMap;
import java.util.Map;

// 1没有办法通过obj.value方式 2没有改变属性的方法 3不能通过继承重置属性 所以这个对象是 immutable 不可变的
final class State {
    private String value = null;
    
    public State(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

interface Flyweight {
    void operation(String extrinsicState);
}

class ConFlyweight1 implements Flyweight {
    //state 表示享元的内部状态
    //或者用构造函数传入
    private State state = new State("state1");
    
    //out 为外部传给享元的 外部状态
    public void operation(String out) {
        //使用外部状态和内部状态来执行 operation操作
        System.out.println("ConFlyweight1: " + out + state.getValue());
    }
}

// 充数的
class ConFlyweight2 implements Flyweight {
    private State state = new State("state2");
    
    public void operation(String out) {
        System.out.println("ConFlyweight2: " + state.getValue() + out );
    }
}

class FlyweightFactory {
    Map flyweights = new HashMap();
    
    public Flyweight getFlyweight(String key) {
        if (flyweights.containsKey(key)) {
            return (Flyweight) flyweights.get(key);
        } else {
            // 这里就随便写的
            Flyweight flyweight = null;
            if (key.charAt(key.length() - 1) == '1') {
                flyweight = new ConFlyweight1();
                flyweights.put(key, flyweight);
            } else {
                flyweight = new ConFlyweight2();
                flyweights.put(key, flyweight);
            }
            return flyweight;
        }
    }
}

public class FlyweightPattern {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1a = factory.getFlyweight("flytest1");
        flyweight1a.operation("outparam1");
    }
}


***********************************************************************


// Bridge 模式例子
//对一处的操作 改成引用一个对象 具体操作再另一个对象中进行 这样便于功能扩展

package pattern.b.bridge;

interface Implementor {
    void realOperation();
}

class ConImplementor1 implements Implementor {
    public void realOperation() {
        System.out.println("do the real operation1");
    }
}

class ConImplementor2 implements Implementor {
    public void realOperation() {
        System.out.println("do the real operation2");
    }
}

abstract class Abstraction {
    protected Implementor imp;
    
    public Abstraction(Implementor imp) {
        this.imp = imp;
    }
    
    protected void med0() {}
    
    abstract public void operation();
}

class ConAbstraction extends Abstraction{
    public ConAbstraction(Implementor imp) {
        super(imp);
    }
    
    public void operation() {
        med0();
        imp.realOperation();
    }
}

public class BridgePattern {
    public static void main(String[] args) {
        Implementor imp = new ConImplementor1();
        Abstraction abs = new ConAbstraction(imp);
        abs.operation();
    }
}


***********************************************************************


//Decorator 模式例子

package pattern.b.decorator;

//源部件和修饰类的共同接口
interface Component {
    void operation();
}

class ConComponent implements Component {
    public void operation() {
        System.out.println("the begin operation");
    }
}

//没有提供给component赋值的方法 所以声明这个类为抽象的 这里并没有抽象的方法就是不像让这个类有实例
abstract class Decotor implements Component{
    private Component component;
    
    public void operation() {
        component.operation();
    }
}

class ConDecotor1 extends Decotor {
    private Component component;
    
    public ConDecotor1(Component component) {
        this.component = component;
    }    
    
    public void operation() {
        super.operation();
        //!!注意这里 这里提供了功能的添加 
        // 这里就是Decorator的核心部分 不是修改功能而是添加功能 将一个component传入装饰类调用对象的接口
        //方法 在此过程添加功能 重新实现接口方法的功能
        med0();
    }
    
    private void med0() {
        System.out.println("1");
    }
}

class ConDecotor2 extends Decotor {
    private Component component;
    
    public ConDecotor2(Component component) {
        this.component = component;
    }    
    
    public void operation() {
        super.operation();
        med0();
    }
    
    private void med0() {
        System.out.println("2");
    }
}

//class  

public class DecoratorPattern {
    public static void main(String[] args) {
        //注意 起点位置是从一个ConComponent开始的!!
        Component component = new ConDecotor2(new ConDecotor1(new ConComponent()));
        component.operation();
    }
}


***********************************************************************


//Facade 的例子
//在子系统上建立了一层 对外使用感觉比较简单 Facade的方法中封装与子系统交互的逻辑

package pattern.b.facade;

class Exa1 {
    public void med0() {}
}

class Exa2 {
    public void themed() {}
}

//这就是一个简单的Facade的方法的例子
class Facade {
    public void facdeMed() {
        Exa1 exa1 = new Exa1();
        exa1.med0();
        
        Exa2 exa2 = new Exa2();
        exa2.themed();
    }
}

public class FacadePattern {
    public static void main(String[] args) {
    }
}


***********************************************************************


////////////////////////////////////////////////////////////////////

行为模式

////////////////////////////////////////////////////////////////////


//Command 模式例子
//感觉将一个类的方法 分散开了 抽象成了接口方法 注意 参数和返回值要一致
//每个Command封装一个命令 也就是一种操作

package pattern.c.command;

//这个是逻辑真正实现的位置
class Receiver {
    public void med1() {}
    
    public void med2() {}
}

interface Command {
    // 要抽象成统一接口方法 是有局限性的
    void execute();
}

class ConCommand1 implements Command{
    private Receiver receiver;
    
    public ConCommand1(Receiver receiver) {
        this.receiver = receiver;
    }
    
    public void execute() {
        receiver.med1();
    }
}

class ConCommand2 implements Command{
    private Receiver receiver;
    
    public ConCommand2(Receiver receiver) {
        this.receiver = receiver;
    }
    
    public void execute() {
        receiver.med2();
    }
}

class Invoker {
    private Command command;
    
    public Invoker(Command command) {
        this.command = command;
    }
    
    public void action() {
        command.execute();
    }
}

public class CommandPattern {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        // 生成一个命令
        Command command = new ConCommand1(receiver);
        Invoker invoker = new Invoker(command);
        invoker.action();
    }
}


***********************************************************************


//Strategy 模式例子
//Strategy中封装了算法

package pattern.c.strategy;

interface Strategy {
    void stMed();
}

class Constrategy1 implements Strategy  {
    public void stMed() {}
}

class constrategy2 implements Strategy  {
    public void stMed() {}
}

class Context {
    private Strategy strategy;
    
    public Context (Strategy strategy) {
        this.strategy = strategy;
    }
    
    public void ContextInterface() {
        strategy.stMed();
    }
}

public class StrategyPattern {
    public static void main(String[] args) {
    }
}


***********************************************************************


//State模式例子
//将一种状态和状态的助理封装倒state中

package pattern.c.state;

class Context {
 private State state = new CloseState();
 
 public void changeState(State state) {
  this.state = state;
 }
 
 public void ruquest() {
  state.handle(this);
 }
}

interface State {
 void handle(Context context);
}

//表示打开状态
class OpenState implements State{
 public void handle(Context context) {
  System.out.println("do something for open");
  context.changeState(new CloseState());
 }
}

//表示关闭状态
class CloseState implements State{
 public void handle(Context context) {
  System.out.println("do something for open");
  context.changeState(new OpenState());
 }
}

public class StatePattern {
 public static void main(String[] args) {
 }
}


***********************************************************************


//Visitor模式例子
//双向传入

package pattern.c.visitor;
import java.util.*;

interface Visitor {
 void visitConElementA(ConElementA conElementA);
 void visitConElementB(ConElementB conElementB);
}

class ConVisitor1 implements Visitor{
 public void visitConElementA(ConElementA conElementA) {
  String value = conElementA.value;
  conElementA.operation();
  //do something
 }
 public void visitConElementB(ConElementB conElementB) {
  String value = conElementB.value;
  conElementB.operation();
        //do something
 }
}

class ConVisitor2 implements Visitor{
 public void visitConElementA(ConElementA conElementA) {
  String value = conElementA.value;
  conElementA.operation();
        //do something
 }
 public void visitConElementB(ConElementB conElementB) {
  String value = conElementB.value;
  conElementB.operation();
        //do something
 }
}

interface Element {
 void accept(Visitor visitor);
}

class ConElementA implements Element {
 String value = "aa";
 
 public void operation() {}
 
 public void accept(Visitor visitor) {
  visitor.visitConElementA(this);
 }
}

class ConElementB implements Element {
 String value = "bb";
 
 public void operation() {}
 
 public void accept(Visitor visitor) {
  visitor.visitConElementB(this);
 }
} 

class ObjectStructure {
 private List Elements = new ArrayList();
 
 public void action(Visitor visitor) {
  Iterator it = Elements.iterator();
  Element element = null;
  while (it.hasNext()) {
   element = (Element) it.next();
   element.accept(visitor);
  }
 }
 
 public void add(Element element) {
  Elements.add(element);
 }  
}

public class VisitorPattern {
 public static void main(String[] args) {
  ObjectStructure objs = new ObjectStructure();
  objs.add(new ConElementA());
  objs.add(new ConElementA());
  objs.add(new ConElementB());
  objs.action(new ConVisitor1());
 }
}


***********************************************************************


//Observer模式例子

package pattern.c.observable;
import java.util.*;

class State {}

interface Subject {
 void attach(Observer observer);
 
 void detach(Observer observer);
 
 void myNotify();
 
 State getState();
 
 void setState(State state);
}

class ConSubject implements Subject {
 List observers = new ArrayList();
 State state = new State();
 
 public void attach(Observer observer) {
  observers.add(observer);
 }
 
 public void detach(Observer observer) {
  observers.remove(observer);
 }
 
 public void myNotify() {
  Iterator it = observers.iterator();
  Observer observer = null;
  while (it.hasNext()) {
   observer = (Observer) it.next();
   observer.update();
  }
 }
 
 public State getState() {
  return state;
 }
 
 public void setState(State state) {
  this.state = state;
 } 
}

interface Observer {
 void update();
}

class ConObserver1 implements Observer{
 private Subject subject;
 
 public ConObserver1(Subject subject) {
  this.subject = subject;
 }
 
 public void update() {
  State state = subject.getState();
  // do something with state
 }
}

class ConObserver2 implements Observer{
 private Subject subject;
 
 public ConObserver2(Subject subject) {
  this.subject = subject;
 }
 
 public void update() {
  State state = subject.getState();
  // do something with state
 }
}

public class ObservablePattern {
 public static void main(String[] args) {
 }
}


***********************************************************************


//Mediator模式例子

package pattern.c.mediator;

public interface Colleague {
    
    void setState(String state);
    
    String getState();
    
    void change();
    
    void action();
    
}

package pattern.c.mediator;

public class ConColleague1 implements Colleague {
    
    private String state = null;
    private Mediator mediator;
    
    public void change() {
        mediator.changeCol1();
    }
    
    public ConColleague1 (Mediator mediator) {
        this.mediator = mediator;
    }
    
    public void setState(String state) {
        this.state = state;
    }
    
    public String getState() {
        return state;
    }
    
    public void action() {
        System.out.println("this 2 and the state is " + state);
    }
}

package pattern.c.mediator;

public class ConColleague2 implements Colleague {
    
    private String state = null;
    private Mediator mediator;
    
    public ConColleague2 (Mediator mediator) {
        this.mediator = mediator;
    }    
    
    public void change() {
        mediator.changeCol2();
    }    
    
    public void setState(String state) {
        this.state = state;
    }
    
    public String getState() {
        return state;
    }
    
    public void action() {
        System.out.println("this 1 and the state is " + state);
    }    
}

package pattern.c.mediator;

public class ConMediator implements Mediator {
    
    private ConColleague1 con1;
    private ConColleague2 con2;
    
    public void setCon1(ConColleague1 con1) {
        this.con1 = con1;
    }
    
    public void setCon2(ConColleague2 con2) {
        this.con2 = con2;
    }
    
    public void changeCol1() {
        String state = con1.getState();
        con2.setState(state);
        con2.action();
    }
    
    public void changeCol2() {
        String state = con2.getState();
        con1.setState(state);
        con1.action();        
    }
    
}

package pattern.c.mediator;

public interface Mediator {
    
    void setCon1(ConColleague1 con1);
    
    void setCon2(ConColleague2 con2);
    
    void changeCol1();
    
    void changeCol2();
    
}

package pattern.c.mediator;

public class MediatorTest {
    
    public static void main(String[] args) {
        Mediator mediator = new ConMediator();
        
        ConColleague1 col1 = new ConColleague1(mediator);
        col1.setState("lq test in the MediatorTest main 18");
        ConColleague2 col2 = new ConColleague2(mediator);
        
        mediator.setCon1(col1);
        mediator.setCon2(col2);
        
        col1.change();
    }
    
}

***********************************************************************


//Iterator模式例子

package pattern.c.iterator;

interface Aggregate {
 MyIterator Iterator();
}

class ConAggregate {
 public MyIterator Iterator() {
  return new ConMyIterator();
 }
}

interface MyIterator {
 Object First();
 Object Last();
 boolean hasNext();
 Object Next();
}

class ConMyIterator implements MyIterator{
 Object[] objs = new Object[100];
 int index = 0;
 
 public Object First() {
  index = 0;
  return objs[index];
 }
 
 public Object Last() {
  index = objs.length - 1;
  return objs[index];
 }
 
 public boolean hasNext() {
  return index &lt; objs.length;
 }
 
 public Object Next() {
  if (index == objs.length - 1) {
   return null;
  } else {
   return objs[++index];
  }
 }
}

public class IteratorPattern {

 public static void main(String[] args) {
 }
}


***********************************************************************


// Template Method 模式例子

package pattern.c.template_method;

abstract class father {
 abstract void med0();
 
 abstract void med1();
 
 //operation为一个模板方法
 public void operation() {
  med0();
  med1();
  // and other logic
 }
}

class child extends father {
 public void med0() {
  System.out.println("the med0 method");
 }
 
 public void med1() {
  System.out.println("the med1 method");
 }
}

public class TemplateMethodPattern {

 public static void main(String[] args) {
 }
}


***********************************************************************


//Chain of Responsiblity模式例子
//将请求在链上传递
//如果是当前节点的请求就结束传递处理请求否则向下传递请求
//每个节点有另一个节点的引用 实现链状结构


package pattern.c.chain_of_responsiblity;

interface Handler{
 void handleRequest(int key);
}

class ConHandler1 implements Handler {
 private Handler handler;
 
 public ConHandler1(Handler handler) {
  this.handler = handler;
 }
 
 public void handleRequest(int key) {
  if (key == 1) {
   System.out.println("handle in 1");
   //handle something
  } else {
   handler.handleRequest(key);
  }
 }
}

class ConHandler2 implements Handler {
 private Handler handler;
 
 public ConHandler2(Handler handler) {
  this.handler = handler;
 }
 
 public void handleRequest(int key) {
  if (key == 2) {
   System.out.println("handle in 2");
   //handle something
  } else {
   handler.handleRequest(key);
  }
 }
}

class ConHandler3 implements Handler {
 private Handler handler;
 
 public ConHandler3(Handler handler) {
  this.handler = handler;
 }
 
 public void handleRequest(int key) {
  if (key == 3) {
   System.out.println("handle in 3");
   //handle something
  } else {
   handler.handleRequest(key);
  }
 }
}

public class ChainOfResponsiblityPattern {
 public static void main(String[] args) {
  Handler handler = new ConHandler2(new ConHandler1(new ConHandler3(null)));
  handler.handleRequest(3);
 }
}

***********************************************************************


//Interpreter模式例子
/*
 * Variable 表示变量 存储在上下文中
 * Constant 终结表达式
 * And 与的关系 双目
 * Not 反的关系 单目
 */

package pattern.c.interpreter;

import java.util.*;

class Context {
    private Map variables = new HashMap();
    
    public boolean lookUp(Variable name) {
        Boolean value = (Boolean) variables.get(name);
        if (value == null) {
            return false;
        }
        return value.booleanValue();
    }
    
    public void bind(Variable name, boolean value) {
        variables.put(name, new Boolean(value));
    }
}

interface Expression {
    boolean interpret(Context cont);
}

class Constant implements Expression {
    private boolean value;
    
    public Constant(boolean value) {
        this.value = value;
    }
    
    public boolean interpret(Context cont) {
        return value;
    }
}

class Variable implements Expression{
    private String name;
    
    public Variable(String name) {
        this.name = name;
    }
    
    public boolean interpret(Context cont) {
        return cont.lookUp(this);
    }
}

class And implements Expression {
    private Expression left;
    private Expression right;
    
    public And(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    } 
    
    public boolean interpret(Context cont) {
        return left.interpret(cont) &amp;&amp; right.interpret(cont);
    }
}

class Not implements Expression {
    private Expression expression;
    
    public Not(Expression expression) {
        this.expression = expression;
    }
    
    public boolean interpret(Context cont) {
        return ! expression.interpret(cont);
    }
}

public class InterpreterPattern {
    public static void main(String[] args) {
        Context cont = new Context();
        Variable variable = new Variable("parameter1");
        cont.bind(variable, true);
        Expression and = new And(new Not(new Constant(true)), new And(new Constant(false), new Variable("parameter1"))); 
        //  (!(true)) &amp;&amp; ((false)&amp;&amp;(true))
        and.interpret(cont);
    }
}


***********************************************************************


//Memento模式例子

package pattern.c.memento;

class Memento {
    String value1;
    int value2;
    
    public Memento(String value1, int value2) {
        this.value1 = value1;
        this.value2 = value2;
    }
}

class Originator {
    private String value1;
    private int value2;
    
    public Originator(String value1, int value2) {
        this.value1 = value1;
        this.value2 = value2;
    }
    
    public void setMemento(Memento memento) {
        value1 = memento.value1;
        value2 = memento.value2;
    }
    
    public Memento createMemento() {
        Memento memento = new Memento(value1, value2);
        return memento;
    }
 
    public void setValue1(String value1) {
        this.value1 = value1;
    }
 
    public void setValue2(int value2) {
        this.value2 = value2;
    }
}

class CareTaker {
    private Memento memento;
    
    public Memento retrieveMemento() {
        return memento;
    }
    
    public void saveMemento(Memento memento) {
        this.memento = memento;
    }
}

public class MementoPattern {
    public static void main(String[] args) {
        Originator originator = new Originator("test1", 1);
        CareTaker careTaker = new CareTaker();
        
        //保存状态
        careTaker.saveMemento(originator.createMemento());
        
        originator.setValue1("test2");
        originator.setValue2(2);
        
        //恢复状态
        originator.setMemento(careTaker.retrieveMemento());
    }
}
</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/237547#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Sep 2008 13:35:38 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/237547</link>
        <guid>http://heshencao.javaeye.com/blog/237547</guid>
      </item>
          <item>
        <title>java.lang.reflect.Field </title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/237542" style="color:red;">http://heshencao.javaeye.com/blog/237542</a>&nbsp;
          发表时间: 2008年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">package java.lang.reflect;

import sun.reflect.FieldAccessor;
import sun.reflect.Reflection;

/**
 * 
 * 表示属性对象
 *
 * comment by liqiang
 *
 * @author Kenneth Russell
 * @author Nakul Saraiya
 */
public final
class Field extends AccessibleObject implements Member {
 //定义此属性的类名
    private Class  clazz;
    private int   slot;
    //属性名
    private String  name;
    //属性类型
    private Class  type;
    //描述符
    private int   modifiers;
    private volatile FieldAccessor fieldAccessor;
    //copy出此对象的原始对象
    private Field               root;

    //与此属性关联的对象实例缓存,如果当前的对象与缓存对象不同则做安全检查
    private volatile Class      securityCheckTargetClassCache;

    //构造函数
    Field(Class declaringClass,
          String name,
          Class type,
          int modifiers,
          int slot)
    {
        this.clazz = declaringClass;
        this.name = name;
        this.type = type;
        this.modifiers = modifiers;
        this.slot = slot;
    }

    //通过当前类数据生成新的对象
    Field copy() {
     //生成新的属性对象
        Field res = new Field(clazz, name, type, modifiers, slot);
        //新对象指向老对象
        res.root = this;
        //新对象与老对象共用一个FieldAccessor
        res.fieldAccessor = fieldAccessor;
        return res;
    }

    //获得定义此属性的类
    public Class getDeclaringClass() {
 return clazz;
    }

    //获得属性名
    public String getName() {
 return name;
    }

    //获得属性描述符
    public int getModifiers() {
 return modifiers;
    }

    //返回属性类型
    public Class getType() {
 return type;
    }

    //判断obj对象是否与当前属性对象相等
    public boolean equals(Object obj) {
 if (obj != null &amp;&amp; obj instanceof Field) {//是属性对象
  //转型
     Field other = (Field)obj;
     //判断定义属性的类,属性名,属性类型
     return (getDeclaringClass() == other.getDeclaringClass())
                &amp;&amp; (getName() == other.getName())
  &amp;&amp; (getType() == other.getType());
 }
 
 //不等
 return false;
    }

    //返回hashCode
    public int hashCode() {
 return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
    }

    //返回字符串描述
    public String toString() {
 int mod = getModifiers();
 return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
     + getTypeName(getType()) + " "
     + getTypeName(getDeclaringClass()) + "."
     + getName());
    }

    /**
     * Returns the value of the field represented by this &lt;code&gt;Field&lt;/code&gt;, on
     * the specified object. The value is automatically wrapped in an
     * object if it has a primitive type.
     *
     * &lt;p&gt;The underlying field's value is obtained as follows:
     *
     * &lt;p&gt;If the underlying field is a static field, the &lt;code&gt;obj&lt;/code&gt; argument
     * is ignored; it may be null.
     *
     * &lt;p&gt;Otherwise, the underlying field is an instance field.  If the
     * specified &lt;code&gt;obj&lt;/code&gt; argument is null, the method throws a
     * &lt;code&gt;NullPointerException.&lt;/code&gt; If the specified object is not an
     * instance of the class or interface declaring the underlying
     * field, the method throws an &lt;code&gt;IllegalArgumentException&lt;/code&gt;.
     *
     * &lt;p&gt;If this &lt;code&gt;Field&lt;/code&gt; object enforces Java language access control, and
     * the underlying field is inaccessible, the method throws an
     * &lt;code&gt;IllegalAccessException&lt;/code&gt;.
     * If the underlying field is static, the class that declared the
     * field is initialized if it has not already been initialized. 
     *
     * &lt;p&gt;Otherwise, the value is retrieved from the underlying instance
     * or static field.  If the field has a primitive type, the value
     * is wrapped in an object before being returned, otherwise it is
     * returned as is.
     *
     * &lt;p&gt;If the field is hidden in the type of &lt;code&gt;obj&lt;/code&gt;,
     * the field's value is obtained according to the preceding rules.
     *
     * @param obj object from which the represented field's value is
     * to be extracted
     * @return the value of the represented field in object
     * &lt;tt&gt;obj&lt;/tt&gt;; primitive values are wrapped in an appropriate
     * object before being returned
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof).
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     */
    public Object get(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).get(obj);
    }

    /**
     * Gets the value of a static or instance &lt;code&gt;boolean&lt;/code&gt; field.
     *
     * @param obj the object to extract the &lt;code&gt;boolean&lt;/code&gt; value
     * from
     * @return the value of the &lt;code&gt;boolean&lt;/code&gt; field
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;boolean&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public boolean getBoolean(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getBoolean(obj);
    }

    /**
     * Gets the value of a static or instance &lt;code&gt;byte&lt;/code&gt; field.
     *
     * @param obj the object to extract the &lt;code&gt;byte&lt;/code&gt; value
     * from
     * @return the value of the &lt;code&gt;byte&lt;/code&gt; field
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;byte&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public byte getByte(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getByte(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;char&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;char&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;char&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;char&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;char&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see Field#get
     */
    public char getChar(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getChar(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;short&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;short&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;short&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;short&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;short&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public short getShort(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getShort(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;int&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;int&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;int&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;int&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;int&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public int getInt(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getInt(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;long&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;long&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;long&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;long&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;long&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public long getLong(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getLong(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;float&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;float&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;float&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;float&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;float&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see Field#get
     */
    public float getFloat(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getFloat(obj);
    }

    /**
     * Gets the value of a static or instance field of type
     * &lt;code&gt;double&lt;/code&gt; or of another primitive type convertible to
     * type &lt;code&gt;double&lt;/code&gt; via a widening conversion.
     *
     * @param obj the object to extract the &lt;code&gt;double&lt;/code&gt; value
     * from
     * @return the value of the field converted to type &lt;code&gt;double&lt;/code&gt;
     *
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not 
     *              an instance of the class or interface declaring the
     *              underlying field (or a subclass or implementor 
     *              thereof), or if the field value cannot be
     *              converted to the type &lt;code&gt;double&lt;/code&gt; by a 
     *              widening conversion.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#get
     */
    public double getDouble(Object obj)
 throws IllegalArgumentException, IllegalAccessException
    {
        return getFieldAccessor(obj).getDouble(obj);
    }

    /**
     * Sets the field represented by this &lt;code&gt;Field&lt;/code&gt; object on the
     * specified object argument to the specified new value. The new
     * value is automatically unwrapped if the underlying field has a
     * primitive type.
     *
     * &lt;p&gt;The operation proceeds as follows:
     *
     * &lt;p&gt;If the underlying field is static, the &lt;code&gt;obj&lt;/code&gt; argument is
     * ignored; it may be null.
     *
     * &lt;p&gt;Otherwise the underlying field is an instance field.  If the
     * specified object argument is null, the method throws a
     * &lt;code&gt;NullPointerException&lt;/code&gt;.  If the specified object argument is not
     * an instance of the class or interface declaring the underlying
     * field, the method throws an &lt;code&gt;IllegalArgumentException&lt;/code&gt;.
     *
     * &lt;p&gt;If this &lt;code&gt;Field&lt;/code&gt; object enforces Java language access control, and
     * the underlying field is inaccessible, the method throws an
     * &lt;code&gt;IllegalAccessException&lt;/code&gt;.
     *
     * &lt;p&gt;If the underlying field is final, the method throws an
     * &lt;code&gt;IllegalAccessException&lt;/code&gt;.
     *
     * &lt;p&gt;If the underlying field is of a primitive type, an unwrapping
     * conversion is attempted to convert the new value to a value of
     * a primitive type.  If this attempt fails, the method throws an
     * &lt;code&gt;IllegalArgumentException&lt;/code&gt;.
     *
     * &lt;p&gt;If, after possible unwrapping, the new value cannot be
     * converted to the type of the underlying field by an identity or
     * widening conversion, the method throws an
     * &lt;code&gt;IllegalArgumentException&lt;/code&gt;.
     *
     * &lt;p&gt;If the underlying field is static, the class that declared the
     * field is initialized if it has not already been initialized.
     *
     * &lt;p&gt;The field is set to the possibly unwrapped and widened new value.
     *
     * &lt;p&gt;If the field is hidden in the type of &lt;code&gt;obj&lt;/code&gt;,
     * the field's value is set according to the preceding rules.
     *
     * @param obj the object whose field should be modified
     * @param value the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     */
    public void set(Object obj, Object value)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).set(obj, value);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;boolean&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, zObj)&lt;/code&gt;,
     * where &lt;code&gt;zObj&lt;/code&gt; is a &lt;code&gt;Boolean&lt;/code&gt; object and 
     * &lt;code&gt;zObj.booleanValue() == z&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param z   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setBoolean(Object obj, boolean z)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setBoolean(obj, z);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;byte&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, bObj)&lt;/code&gt;,
     * where &lt;code&gt;bObj&lt;/code&gt; is a &lt;code&gt;Byte&lt;/code&gt; object and 
     * &lt;code&gt;bObj.byteValue() == b&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param b   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setByte(Object obj, byte b)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setByte(obj, b);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;char&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, cObj)&lt;/code&gt;,
     * where &lt;code&gt;cObj&lt;/code&gt; is a &lt;code&gt;Character&lt;/code&gt; object and 
     * &lt;code&gt;cObj.charValue() == c&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param c   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setChar(Object obj, char c)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setChar(obj, c);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;short&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, sObj)&lt;/code&gt;,
     * where &lt;code&gt;sObj&lt;/code&gt; is a &lt;code&gt;Short&lt;/code&gt; object and 
     * &lt;code&gt;sObj.shortValue() == s&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param s   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setShort(Object obj, short s)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setShort(obj, s);
    }

    /**
     * Sets the value of a field as an &lt;code&gt;int&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, iObj)&lt;/code&gt;,
     * where &lt;code&gt;iObj&lt;/code&gt; is a &lt;code&gt;Integer&lt;/code&gt; object and 
     * &lt;code&gt;iObj.intValue() == i&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param i   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setInt(Object obj, int i)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setInt(obj, i);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;long&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, lObj)&lt;/code&gt;,
     * where &lt;code&gt;lObj&lt;/code&gt; is a &lt;code&gt;Long&lt;/code&gt; object and 
     * &lt;code&gt;lObj.longValue() == l&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param l   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setLong(Object obj, long l)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setLong(obj, l);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;float&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, fObj)&lt;/code&gt;,
     * where &lt;code&gt;fObj&lt;/code&gt; is a &lt;code&gt;Float&lt;/code&gt; object and 
     * &lt;code&gt;fObj.floatValue() == f&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param f   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setFloat(Object obj, float f)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setFloat(obj, f);
    }

    /**
     * Sets the value of a field as a &lt;code&gt;double&lt;/code&gt; on the specified object.
     * This method is equivalent to
     * &lt;code&gt;set(obj, dObj)&lt;/code&gt;,
     * where &lt;code&gt;dObj&lt;/code&gt; is a &lt;code&gt;Double&lt;/code&gt; object and 
     * &lt;code&gt;dObj.doubleValue() == d&lt;/code&gt;.
     *
     * @param obj the object whose field should be modified
     * @param d   the new value for the field of &lt;code&gt;obj&lt;/code&gt;
     * being modified
     * 
     * @exception IllegalAccessException    if the underlying field
     *              is inaccessible.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof), 
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    public void setDouble(Object obj, double d)
 throws IllegalArgumentException, IllegalAccessException
    {
        getFieldAccessor(obj).setDouble(obj, d);
    }

    // Convenience routine which performs security checks
    private FieldAccessor getFieldAccessor(Object obj)
        throws IllegalAccessException
    {
        doSecurityCheck(obj);
        if (fieldAccessor == null) {
            acquireFieldAccessor();
        }
        return fieldAccessor;
    }

    //如果属性对象是由copy得来则属性对象与生成此对象的对象使用同一FieldAccessor
    private void acquireFieldAccessor() {
        FieldAccessor tmp = null;
        if (root != null) tmp = root.getFieldAccessor();
        if (tmp != null) {
            fieldAccessor = tmp;
            return;
        }
        
        //不是由copy得来 创建FieldAccessor对象
        tmp = reflectionFactory.newFieldAccessor(this);
        setFieldAccessor(tmp);
    }

    //获取FieldAccessor对象
    private FieldAccessor getFieldAccessor() {
        return fieldAccessor;
    }

    //设置FieldAccessor对象
    private void setFieldAccessor(FieldAccessor accessor) {
        fieldAccessor = accessor;
        
        if (root != null) {
            //如果有上级则递归设置
         root.setFieldAccessor(accessor);
        }
    }

    //做安全检查
    private void doSecurityCheck(Object obj) throws IllegalAccessException {
        if (!override) {//做安全检查
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class caller = Reflection.getCallerClass(4);
                
                Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
                                     ? clazz
                                     : obj.getClass());
                
                if (securityCheckCache != caller ||
                    targetClass != securityCheckTargetClassCache) {
                 
                    Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
                    securityCheckCache = caller;
                    securityCheckTargetClassCache = targetClass;
                }
            }
        }
    }

    //返回类的显示名字,如果不是数组则直接返回类名
    //如果是数组,则取出最底层元素的对象,显示为元素名+[]..([]个数为数组维数)
    static String getTypeName(Class type) {
 if (type.isArray()) {//类代表数组
     try {
  Class cl = type;
  //维数
  int dimensions = 0;
  //取得最底层的数组元素类型,并计算出维数
  while (cl.isArray()) {
      dimensions++;
      cl = cl.getComponentType();
  }
  
  StringBuffer sb = new StringBuffer();
  sb.append(cl.getName());
  for (int i = 0; i &lt; dimensions; i++) {
      sb.append("[]");
  }
  
  return sb.toString();
  
     } catch (Throwable e) {
      //异常
     }
 }
 
 //不代表数组则直接返回类名
 return type.getName();
    }

}

</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/237542#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Sep 2008 13:28:09 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/237542</link>
        <guid>http://heshencao.javaeye.com/blog/237542</guid>
      </item>
          <item>
        <title>java.lang.reflect.Constructor </title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/237541" style="color:red;">http://heshencao.javaeye.com/blog/237541</a>&nbsp;
          发表时间: 2008年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">package java.lang.reflect;

import sun.reflect.ConstructorAccessor;
import sun.reflect.Reflection;

/**
 * 表示构造函数的对象
 * 
 * comment by liqiang
 *
 * @author Kenneth Russell
 * @author Nakul Saraiya
 */
public final
class Constructor extends AccessibleObject implements Member {

 //声明此构造函数的类对象
    private Class  clazz;
    private int   slot;
    //参数列表数组
    private Class[]  parameterTypes;
    //异常数组
    private Class[]  exceptionTypes;
    //修饰符
    private int   modifiers;
    //真正实现功能的类,当前类只是它的代理
    private volatile ConstructorAccessor constructorAccessor;
    //由coyp的来的对象,回保留原对象的引用
    private Constructor         root;

    //包内的构造函数
    Constructor(Class declaringClass,
                Class[] parameterTypes,
                Class[] checkedExceptions,
                int modifiers,
                int slot)
    {
        this.clazz = declaringClass;
        this.parameterTypes = parameterTypes;
        this.exceptionTypes = checkedExceptions;
        this.modifiers = modifiers;
        this.slot = slot;
    }

    /**
     * 返回当前构造函数对象的一个拷贝
     */
    Constructor copy() {
     //用此对象的数据生成新的构造函数对象
        Constructor res = new Constructor(clazz, parameterTypes,
                                          exceptionTypes, modifiers, slot);
        //新构造函数的root指向自己
        res.root = this;
        //与新的构造函数对象共享ConstructorAccessor
        res.constructorAccessor = constructorAccessor;
        return res;
    }

    //返回定义此构造函数的类
    public Class getDeclaringClass() {
 return clazz;
    }

    //取得构造函数的名,它与类名一致
    public String getName() {
 return getDeclaringClass().getName();
    }

    //取得修饰符
    public int getModifiers() {
 return modifiers;
    }

    //取得此对象的参数列表
    public Class[] getParameterTypes() {
 return Method.copy(parameterTypes);
    }

    //返回此构造函数定义的异常列表,如果没有定义异常,则返回0长度数组
    public Class[] getExceptionTypes() {
 return Method.copy(exceptionTypes);
    }

    /**
     * 判断指定对象obj是否与当前构造函数对象相等
     */
    public boolean equals(Object obj) {
 if (obj != null &amp;&amp; obj instanceof Constructor) {//对象不为null,且为构造函数对象
  //转型
     Constructor other = (Constructor)obj;
     if (getDeclaringClass() == other.getDeclaringClass()) {
     //两对象的定义类相等,这是他们的名称也一定相等
      
  Class[] params1 = parameterTypes;
  Class[] params2 = other.parameterTypes;
  
  //比较参数列表
  if (params1.length == params2.length) {
      for (int i = 0; i &lt; params1.length; i++) {
   if (params1[i] != params2[i])
       return false;
      }
      return true;
  }
  
     }
 }
 
 //两个对象不等
 return false;
    }

    //返回hashCode
    public int hashCode() {
 return getDeclaringClass().getName().hashCode();
    }

    /**
     * 返回构造函数的字符串描述
     */
    public String toString() {
 try {
     StringBuffer sb = new StringBuffer();
     int mod = getModifiers();
     
     if (mod != 0) {
  //标志符
     sb.append(Modifier.toString(mod) + " ");
     }
     
     //注意它这里用的是Field方法中显示类的名字,这个方法显示数组类型跟Class.getName()不同
     //类名
     sb.append(Field.getTypeName(getDeclaringClass()));
     sb.append("(");
     
     //显示参数列表用","分隔
     Class[] params = parameterTypes; // avoid clone
     for (int j = 0; j &lt; params.length; j++) {
  sb.append(Field.getTypeName(params[j]));
  if (j &lt; (params.length - 1))
      sb.append(",");
     }
     sb.append(")");
     
     //显示异常列表用","分隔
     Class[] exceptions = exceptionTypes; // avoid clone
     if (exceptions.length &gt; 0) {
  sb.append(" throws ");  
  for (int k = 0; k &lt; exceptions.length; k++) {
      sb.append(exceptions[k].getName());
      if (k &lt; (exceptions.length - 1))
   sb.append(",");
  }
  
     }
     return sb.toString();
 } catch (Exception e) {
     return "&lt;" + e + "&gt;";
 }
    }

    /**
     * 此类最重要的方法
     * 构造一个类的实例,如果构造函数是无参的,传入的数组为null或长度为0,
     * 原始类型的参数需要封装成其包装类
     * 
     */
    public Object newInstance(Object[] initargs)
 throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        if (!override) {//做检查
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class caller = Reflection.getCallerClass(2);
                if (securityCheckCache != caller) {
                 //上一个通过的调用者的Class对象被缓存,如果与上次通过的不同,则进行安全检查
                    Reflection.ensureMemberAccess(caller, clazz, null, modifiers);
                    securityCheckCache = caller;
                }
            }
        }
        
        //检查acquireConstructorAccessor
        if (constructorAccessor == null) acquireConstructorAccessor();
        
        //Constructor只是代理类,实现创建对象的操作是在ConstructorAccessor中
        return constructorAccessor.newInstance(initargs);
    }

    private void acquireConstructorAccessor() {
        ConstructorAccessor tmp = null;
        //取得上层的ConstructorAccessor
        if (root != null) tmp = root.getConstructorAccessor();
        if (tmp != null) {
         //如果上层的ConstructorAccessor不为空,则将上层的
         //ConstructorAccessor付给当前的ConstructorAccessor,并返回
            constructorAccessor = tmp;
            return;
        }
        
        //上层没有则创建一个
        tmp = reflectionFactory.newConstructorAccessor(this);
        setConstructorAccessor(tmp);
    }

    //直接返回onstructorAccessor
    ConstructorAccessor getConstructorAccessor() {
        return constructorAccessor;
    }

    //设置当前的constructorAccessor对象,会是上次的constructorAccessor对象都改变
    void setConstructorAccessor(ConstructorAccessor accessor) {
        //将当前的constructorAccessor对象置为新的ConstructorAccessor对象
     constructorAccessor = accessor;
        
     //递归调用上层的设置ConstructorAccessor对象的方法
        if (root != null) {
            root.setConstructorAccessor(accessor);
        }
    }

    int getSlot() {
        return slot;
    }
}

</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/237541#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Sep 2008 13:26:06 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/237541</link>
        <guid>http://heshencao.javaeye.com/blog/237541</guid>
      </item>
          <item>
        <title>java.lang.reflect.Method </title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/237539" style="color:red;">http://heshencao.javaeye.com/blog/237539</a>&nbsp;
          发表时间: 2008年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">package java.lang.reflect;

import sun.reflect.MethodAccessor;
import sun.reflect.Reflection;

/**
 * 
 * 描述方法的类
 * 
 * 注意使用反射的方式是首先通过
 * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象
 * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得
 * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args)
 * 这里obj指调用方法的对象,args表示每个参数对应的值
 * 
 * 例子,一下两种方式的效果是一样的(当然性能不同)
 * String ost = "lqtest";
 * String nst = ost.substring(2,6);
 * 
 * String ost2 = "lqtest";
 * Class[] types = {int.class, int.class};
 * Method med = String.class.getMethod("substring", types);
 * Object[] values ={new Integer(2), new Integer(6)};
 * String nst2 = (String) med.invoke(ost2, values);
 * 
 * 使用反射一切都是变化的,类名,方法名,参数列表,都是变量,而不是写死的,他们
 * 在运行时才知道具体值,而不是编译期
 * 
 * comment by liqiang
 *
 * @author Kenneth Russell
 * @author Nakul Saraiya
 */
public final
class Method extends AccessibleObject implements Member {
 //定义此方法的类对象
    private Class  clazz;
    private int   slot;
    //方法名,从1.4开始它变成intern的形式
    private String  name;
    //返回类型
    private Class  returnType;
    //参数列表
    private Class[]  parameterTypes;
    //异常列表
    private Class[]  exceptionTypes;
    //方法的描述符
    private int   modifiers;
    //处理方法的实际对象
    private volatile MethodAccessor methodAccessor;
    //如果当前对象是通过拷贝得到的,则root指向拷贝前的对象
    private Method              root;

    //调用对象的安全检查的缓存,保存上一个通过检查的调用对象,如果当前的调用对象
    //不是上一个调用对象则做安全检查
    private volatile Class      securityCheckTargetClassCache;

    //构造函数
    Method(Class declaringClass,
           String name,
           Class[] parameterTypes,
           Class returnType,
           Class[] checkedExceptions,
           int modifiers,
           int slot)
    {
        this.clazz = declaringClass;
        this.name = name;
        this.parameterTypes = parameterTypes;
        this.returnType = returnType;
        this.exceptionTypes = checkedExceptions;
        this.modifiers = modifiers;
        this.slot = slot;
    }

    //通过本对象的数据生成一个新对象
    Method copy() {
     //通过本对象的数据生成一个新对象
        Method res = new Method(clazz, name, parameterTypes, returnType,
                                exceptionTypes, modifiers, slot);
        //新对象的root指向原对象
        res.root = this;
        //新对象与原对象公用一个MethodAccessor
        res.methodAccessor = methodAccessor;
        return res;
    }

    //返回声明此函数的类
    public Class getDeclaringClass() {
 return clazz;
    }

    //返回方法名
    public String getName() {
 return name;
    }

    //返回描述符
    public int getModifiers() {
 return modifiers;
    }

    //取得返回类型
    public Class getReturnType() {
 return returnType;
    }

    //返回参数列表
    public Class[] getParameterTypes() {
 return copy(parameterTypes);
    }

    //返回异常列表
    public Class[] getExceptionTypes() {
 return copy(exceptionTypes);
    }

    //判断obj是否与当前方法对象相等
    public boolean equals(Object obj) {
 if (obj != null &amp;&amp; obj instanceof Method) {//如果是方法对象
  //转型
     Method other = (Method)obj;
     
     //定义此方法的类和方法名相等
     if ((getDeclaringClass() == other.getDeclaringClass())
  &amp;&amp; (getName() == other.getName())) {
      
  /* Avoid unnecessary cloning */
  Class[] params1 = parameterTypes;
  Class[] params2 = other.parameterTypes;
  
  //比较参数列表
  if (params1.length == params2.length) {
      for (int i = 0; i &lt; params1.length; i++) {
   if (params1[i] != params2[i])
       return false;
      }
      return true;
  }
  
     }
 }
 return false;
    }

    //返回hashCode
    public int hashCode() {
 return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
    }

    //方法对象的字符串表示
    public String toString() {
 try {
     StringBuffer sb = new StringBuffer();
     int mod = getModifiers();
     if (mod != 0) {
     //标志符
  sb.append(Modifier.toString(mod) + " ");
     }
     //注意它这里用的是Field方法中显示类的名字,这个方法显示数组类型跟Class.getName()不同
     //添加返回类型
     sb.append(Field.getTypeName(getReturnType()) + " ");
     //添加类名
     sb.append(Field.getTypeName(getDeclaringClass()) + ".");
     //添加方法名
     sb.append(getName() + "(");    
     
     //参数列表
     Class[] params = parameterTypes; // avoid clone
     for (int j = 0; j &lt; params.length; j++) {
  sb.append(Field.getTypeName(params[j]));
  if (j &lt; (params.length - 1))
      sb.append(",");
     }
     sb.append(")");
     
     //异常列表
     Class[] exceptions = exceptionTypes; // avoid clone
     if (exceptions.length &gt; 0) {
  sb.append(" throws ");
  for (int k = 0; k &lt; exceptions.length; k++) {
      sb.append(exceptions[k].getName());
      if (k &lt; (exceptions.length - 1))
   sb.append(",");
  }
     }
     return sb.toString();
 } catch (Exception e) {
     return "&lt;" + e + "&gt;";
 }
    }

    /**
     * 
     * 注意使用反射的方式是首先通过
     * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象
     * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得
     * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args)
     * 如果调用的方法是static的则obj对象为null,如果方法没有参数,则args的长度为0或为null
     * 如果返回值是原始类型则返回它的封装类,如果返回值是void则返回null
     */
    public Object invoke(Object obj, Object[] args)
 throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
             //获得调用对象的Class对象
                Class caller = Reflection.getCallerClass(1);
                
                Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
                                     ? clazz
                                     : obj.getClass());
                //调用此操作的对象或方法调用作用的对象与缓存不同,则做安全检查
                if (securityCheckCache != caller ||
                    targetClass != securityCheckTargetClassCache) {
                    Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
                    securityCheckCache = caller;
                    //通过安全检查的调用对象,缓存它供下次调用时使用
                    securityCheckTargetClassCache = targetClass;
                }
            }
        }
        
        if (methodAccessor == null) acquireMethodAccessor();
        return methodAccessor.invoke(obj, args);
    }

    //如果此对象是由copy生成的,则对象与生成此对象的对象使用同一个MethodAccessor
    private void acquireMethodAccessor() {
        MethodAccessor tmp = null;
        
        if (root != null) tmp = root.getMethodAccessor();
        if (tmp != null) {
            methodAccessor = tmp;
            return;
        }
        
        //不是由copy得来创建MethodAccessor对象
        tmp = reflectionFactory.newMethodAccessor(this);
        setMethodAccessor(tmp);
    }

    //返回MethodAccessor对象
    MethodAccessor getMethodAccessor() {
        return methodAccessor;
    }

    //设置MethodAccessor对象
    void setMethodAccessor(MethodAccessor accessor) {
        methodAccessor = accessor;
        if (root != null) {//如果此对象是由copy的来
         //递归调用其上级
            root.setMethodAccessor(accessor);
        }
    }

    //生成一个新的Class数组并将原数组内容考到新数组中
    static Class[] copy(Class[] in) {
 int l = in.length;
 
 if (l == 0)
     return in;
 
 Class[] out = new Class[l];
 for (int i = 0; i &lt; l; i++)
     out[i] = in[i];
 
 return out;
    }
}

</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/237539#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Sep 2008 13:24:24 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/237539</link>
        <guid>http://heshencao.javaeye.com/blog/237539</guid>
      </item>
          <item>
        <title>常用正则表达式</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/230838" style="color:red;">http://heshencao.javaeye.com/blog/230838</a>&nbsp;
          发表时间: 2008年08月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>正则表达式用于字符串处理、表单验证等场合，实用高效。现将一些常用的表达式收集于此，以备不时之需。</p>
<p>匹配中文字符的正则表达式： [\u4e00-\u9fa5]<br />评注：匹配中文还真是个头疼的事，有了这个表达式就好办了</p>
<p>匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br />评注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p>
<p>匹配空白行的正则表达式：\n\s*\r<br />评注：可以用来删除空白行</p>
<p>匹配HTML标记的正则表达式：&lt;(\S*?)[^&gt;]*&gt;.*?&lt;/\1&gt;|&lt;.*? /&gt;<br />评注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力</p>
<p>匹配首尾空白字符的正则表达式：^\s*|\s*$<br />评注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br />评注：表单验证时很实用</p>
<p>匹配网址URL的正则表达式：[a-zA-z]+://[^\s]*<br />评注：网上流传的版本功能很有限，上面这个基本可以满足需求</p>
<p>匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$<br />评注：表单验证时很实用</p>
<p>匹配国内电话号码：\d{3}-\d{8}|\d{4}-\d{7}<br />评注：匹配形式如 0511-4405222 或 021-87888822</p>
<p>匹配腾讯QQ号：[1-9][0-9]{4,}<br />评注：腾讯QQ号从10000开始</p>
<p>匹配中国邮政编码：[1-9]\d{5}(?!\d)<br />评注：中国邮政编码为6位数字</p>
<p>匹配身份证：\d{15}|\d{18}<br />评注：中国的身份证为15位或18位</p>
<p>匹配ip地址：\d+\.\d+\.\d+\.\d+<br />评注：提取ip地址时有用</p>
<p>匹配特定数字：<br />^[1-9]\d*$　 　 //匹配正整数<br />^-[1-9]\d*$ 　 //匹配负整数<br />^-?[1-9]\d*$　　 //匹配整数<br />^[1-9]\d*|0$　 //匹配非负整数（正整数 + 0）<br />^-[1-9]\d*|0$　　 //匹配非正整数（负整数 + 0）<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$　　 //匹配正浮点数<br />^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$　 //匹配负浮点数<br />^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$　 //匹配浮点数<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$　　 //匹配非负浮点数（正浮点数 + 0）<br />^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$　　//匹配非正浮点数（负浮点数 + 0）<br />评注：处理大量数据时有用，具体应用时注意修正</p>
<p>匹配特定字符串：<br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串<br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串<br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串<br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串<br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串<br />评注：最基本也是最常用的一些表达式</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/230838#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Aug 2008 21:18:52 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/230838</link>
        <guid>http://heshencao.javaeye.com/blog/230838</guid>
      </item>
          <item>
        <title>如何使用Log4j</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/226767" style="color:red;">http://heshencao.javaeye.com/blog/226767</a>&nbsp;
          发表时间: 2008年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small;"><span><strong>1、 Log4j是什么？<br /></strong>&nbsp; Log4j可以帮助调试（有时候debug是发挥不了作 用的）和分析，要下载和了解更详细的内容，还是访问其官方网站吧：</span> </span><a href="http://jakarta.apache.org/log4j"><span style="font-size: small;"><span>http://jakarta.apache.org/log4j</span> </span></a><span style="font-size: small;"><span>。<br /><br /><strong>2、Log4j的概念</strong><br />&nbsp;&nbsp;<!--StartFragment --> Log4j中有三个主要的组件，它们分别是</span> </span><span style="font-size: small;"><span>Logger、Appender和Layout，L<!--StartFragment -->og4j 允许开发人员定义多个Logger，每个Logger拥有自己的名字，Logger之间通过名字来表明隶属关系。有一个Logger称为Root，它永远存在，且不能通过名字检索或引用，可以通过Logger.getRootLogger()方法获得，其它Logger通过 Logger.getLogger(String name)方法。<br />&nbsp;&nbsp; Appender则是用来指明将所有的log信息存放到什么地方，Log4j中支持多种appender，如<!--StartFragment --></span> </span><span style="font-size: small;">console、files、GUI components、NT Event Loggers等，一个Logger可以拥有多个Appender，也就是你既可以将Log信息输出到屏幕，同时存储到一个文件中。<br />&nbsp;&nbsp; Layout的作用是控制Log信息的输出方式，也就是格式化输出的信息。<br />&nbsp;&nbsp; Log4j中将要输出的Log信息定义了5种级别，依次为DEBUG、INFO、WARN、ERROR和FATAL，当输出时，只有级别高过配置中规定的级别的信息才能真正的输出，这样就很方便的来配置不同情况下要输出的内容，而不需要更改代码，这点实在是方便啊。<br /><br /><strong>3、Log4j的配置文件</strong><br />&nbsp; 虽然可以不用配置文件，而在程序中实现配置，但这种方法在如今的系统开发中显然是不可取的，能采用配置文件的地方一定一定要用配置文件。Log4j支持两种格式的配置文件：XML格式和Java的property格式，本人更喜欢后者，首先看一个简单的例子吧，如下：<br /><br /></span><span style="color: #614db3;"><span style="font-size: small;"><span>&nbsp; log4j.rootLogger=debug, <strong>stdout, R</strong><br />&nbsp; log4j.appender.<strong>stdout</strong>=org.apache.log4j.ConsoleAppender<br />&nbsp; log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br /><br />&nbsp; # Pattern to output the caller's file name and line number.<br />&nbsp; log4j.appender.stdout.layout.ConversionPattern=%5p [%t] <strong>(%F:%L)</strong> - %m%n<br /><br />&nbsp; log4j.appender.<strong>R</strong>=org.apache.log4j.RollingFileAppender<br />&nbsp; log4j.appender.R.File=example.log<br />&nbsp; log4j.appender.R.MaxFileSize=</span> </span><span><span style="font-size: small;"><strong>100KB<br /></strong><br />&nbsp; # Keep one backup file<br />&nbsp; log4j.appender.R.MaxBackupIndex=1<br /><br />&nbsp; log4j.appender.R.layout=org.apache.log4j.PatternLayout<br />&nbsp; log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br /></span></span><span style="color: #000000;"><span style="font-size: small;"><span>&nbsp; 首先，是设置root，格式为<!--StartFragment --> log4j.rootLogger=[level],appenderName,&nbsp;...，其中level就是设置需要输出信息的级别，后面是appender的输出的目的地，<!--StartFragment -->appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。</span> </span><span style="font-size: small;">配置日志信息输出目的地Appender，其语法为<br /></span><span style="font-size: small;"><span>&nbsp; log4j.appender.appenderName = fully.qualified.name.of.appender.class<br />&nbsp; log4j.appender.appenderName.option1 = value1<br />&nbsp; ...<br />&nbsp; log4j.appender.appenderName.option = valueN</span> <br /></span><span style="font-size: small;">Log4j提供的appender有以下几种：<br />&nbsp; org.apache.log4j.ConsoleAppender（控制台）<br />&nbsp; org.apache.log4j.FileAppender（文件）<br />&nbsp; org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件）<br />&nbsp; org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生新文件）<br />&nbsp; org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方）<br /></span></span></span><span style="color: #614db3;"><span style="color: #000000;"><span style="font-size: small;">配置日志信息的格式（布局），其语法为：<br /></span><span style="font-size: small;"><span>&nbsp; log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br />&nbsp; log4j.appender.appenderName.layout.option1 = value1<br />&nbsp; ....<br />&nbsp; log4j.appender.appenderName.layout.option = valueN</span> <br /></span><span style="font-size: small;">Log4j提供的layout有以下几种：<br />&nbsp; org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br />&nbsp; org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />&nbsp; org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />&nbsp; org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） <br /><br /></span></span></span><span style="color: #000000;"><span style="font-size: 10.5pt;"><span><span style="font-size: small;"><span lang="EN-US">Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，打印参数如下： %m 输出代码中指定的消息</span> </span></span></span></span></p>
<p><span style="color: #000000;"><span style="font-size: 10.5pt;"><span style="font-size: small;"><span>　　</span> </span><span lang="EN-US"><span style="font-size: small;"><span>%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL <br />　　%r 输出自应用启动到输出该log信息耗费的毫秒数 <br />　　%c 输出所属的类目，通常就是所在类的全名 <br />　　%t 输出产生该日志事件的线程名 <br />　　%n 输出一个回车换行符，Windows平台为&ldquo;\r\n&rdquo;，Unix平台为&ldquo;\n&rdquo; <br />　　%d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：</span> </span></span></span><span lang="EN-US" style="font-size: 10.5pt;"><span style="font-size: small;"><span>2002年10月18日</span> </span></span><span lang="EN-US" style="font-size: 10.5pt;"><span style="font-size: small;"><span>22：10：28，921 <br />　　%l 输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:10)</span> </span></span></span></p>
<p><br /><span style="color: #614db3;"><span style="color: #000000;"><span><br /><span style="font-size: small;"><strong>4、Log4j在程序中的使用</strong> </span></span></span></span><span style="color: #614db3;"><span style="color: #000000;"><br /></span><span style="color: #a0a0a0;"><span style="font-size: small;"><span style="color: #090909;">&nbsp; 要在自己的程序中使用Log4j，首先需要将commons-logging.jar和logging-log4j-1.2.9.jar导入到构建路径中。然后再将log4j.properties放到src根目录下。这样就可以在程序中使用log4j了。在类中使用log4j，</span> </span></span></span><span style="font-size: small;"><span style="color: #614db3;"><span style="color: #a0a0a0;"><span style="color: #090909;">首先声明一个静态变量</span> </span></span><span style="color: #614db3;"><span style="color: #a0a0a0;"><span style="color: #090909;">Logger logger=Logger.getLog("classname")；现在就可以使用了，用法如下：logger.debug("debug message")或者logger.info("info message")，看下面一个小例子：</span> </span></span></span><span style="color: #614db3;"><span style="color: #a0a0a0;"><br /></span><br /><span style="font-size: small;">&nbsp; import com.foo.Bar;<br />&nbsp; import org.apache.log4j.Logger;<br />&nbsp;&nbsp;import org.apache.log4j.PropertyConfigurator;<br />&nbsp;&nbsp;public class MyApp {<br />&nbsp; &nbsp; static Logger logger = Logger.getLogger(MyApp.class.getName());<br />&nbsp;&nbsp; &nbsp;public static void main(String[] args) {<br />&nbsp;&nbsp;&nbsp; &nbsp; // BasicConfigurator replaced with PropertyConfigurator.<br />&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;PropertyConfigurator.configure(args[0]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("Entering application.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar bar = new Bar();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar.doIt();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("Exiting application.");<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;}</span></span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/226767#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 11 Aug 2008 21:46:58 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/226767</link>
        <guid>http://heshencao.javaeye.com/blog/226767</guid>
      </item>
          <item>
        <title>狗的礼赞</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/226709" style="color:red;">http://heshencao.javaeye.com/blog/226709</a>&nbsp;
          发表时间: 2008年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong><span style="font-family: 宋体;"><span style="color: #000000;"><span style="font-size: small;">一个人在世上最好的朋友会和他反目，成为他的敌人。他悉心养育的儿女会不忠不孝。那些和我们最亲近的人，那些我们以幸福和美名信赖的人会背叛信义。一个人拥有的金钱会失去，也许就在他最需要的时候不翼而飞。一个人的名誉会由于瞬间的不当之举而丧失贻尽。那些当我们功成名就时跪拜向我们致敬的人也许是第一个在失败的阴云笼罩我们时对我们投石下井。在这个自私的世界里，一个人能有的最无私的，从不抛弃他，从不知恩不报，从不背信弃义的朋友是他的狗。 </span></span></span></strong></p>
<p style="line-height: 150%;"><strong><span style="font-family: 宋体;"><span style="color: #000000;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 无论富有或贫穷，无论健康或是患病，一个人的狗总佇立在主人身旁。如果能和主人在一起，它愿意睡在冰冷的地上，任凭寒风凛冽，朔雪飘零。它愿意亲吻没有食物奉送的手；它愿意舔抚艰难人世带来的创痕。它守卫着穷主人安睡如同守卫王子。当所有的朋友离去，它留驻。当财富不翼而飞，当名誉毁之贻尽，它仍然热爱着主人，如日当空，亘古不变。如果在命运驱使下，主人被世人抛弃，众叛亲离，无家可归，忠诚的狗仅仅要求能陪伴主人，守卫他免遭危险，去和他的敌人搏斗。 </span></span></span></strong></p>
<p style="line-height: 150%;"><span style="color: #000000;"><span style="font-size: small;"><span style="font-family: 宋体;"><strong>&nbsp;&nbsp;&nbsp; 当最后的时刻来临，死神拥抱着主人，他的驱体掩埋在冰冷的黄土之下，任凭所有的朋友风流云散，就在墓地旁你可以看见那高尚的狗，它的头伏在两爪之间，双眼神情悲伤，却警觉注视着，忠诚至死。</strong></span> </span></span></p>
<p style="line-height: 150%;"><span style="font-family: 宋体;"><strong></strong></span><span style="font-size: small; color: #000000;">&nbsp; </span></p>
<p style="line-height: 150%;"><span style="font-family: 宋体;"><strong></strong></span><span style="font-size: small; color: #000000;">&nbsp; </span></p>
<p style="line-height: 150%;"><span style="color: #000000;"><span style="font-size: small;"><span style="font-family: 宋体;"><strong>原文：</strong></span> </span></span></p>
<p style="line-height: 150%;"><span style="color: #000000;"><span style="font-size: small;"><span style="font-family: 宋体;"><strong>&nbsp;</strong></span> </span></span></p>
<p style="line-height: 150%;"><span lang="EN-US"><span style="font-family: 宋体;"><span style="font-size: small; color: #000000;"><strong>Gentlemen of the jury: </strong></span></span></span></p>
<p style="line-height: 150%;"><span lang="EN-US"><span style="font-family: 宋体;"><span style="font-size: small; color: #000000;"><strong>&nbsp; The best friend a man has in the world may turn against him and become his enemy. His son or daughter that he has reared with loving care may prove ungrateful. Those who are nearest and dearest to us, those whom we trust with our happiness and our good name may become traitors to their faith. The money that a man has, he may lose. It flies away from him, perhaps when he needs it most. A man's reputation may be sacrificed in a moment of ill-considered action. The people who are prone to fall on their knees to do us honor when success is with us may be the first to throw the stone of malice when failure settles its cloud upon our heads. The one absolutely unselfish friend that man can have in this selfish world, the one that never deserts him, the one that never proves ungrateful or treacherous is his dog. </strong></span></span></span></p>
<p style="line-height: 150%;"><span style="color: #000000;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: 宋体;"><strong>&nbsp; A man's dog stands by him in prosperity and in poverty, in health and in sickness. He will sleep on the cold ground, where the wintry winds blow and the snow drives fiercely, if only he may be near his master's side. He will kiss the hand that has no food to offer; he will lick the wounds and sores that come in an encounter with the roughness of the world. He guards the sleep of his pauper master as if he were a prince. When all other friends desert, he remains.&nbsp;</strong></span></span> </span></span></p>
<p style="line-height: 150%;"><span style="color: #000000;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: 宋体;"><strong>&nbsp; When riches take wings, and reputation falls to pieces, he is as constant in his love as the sun in its journey through the heavens. If fortune drives the master forth an outcast in the world, friendless and homeless, the faithful dog asks no higher privilege than that of accompanying him, to guard him against danger, to fight against his enemies. </strong></span></span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'Times New Roman';"><strong>&nbsp; And when the last scene of all comes, and death takes his master in its embrace and his body is laid away in the cold ground, no matter if all other friends pursue their way, there by the graveside will the noble dog be found, his head between his paws, his eyes sad, but open in alert watchfulness, faithful and true even in death. </strong></span></span></span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/226709#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 11 Aug 2008 18:31:27 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/226709</link>
        <guid>http://heshencao.javaeye.com/blog/226709</guid>
      </item>
          <item>
        <title>hibernate的各种保存方式的区别 (save,persist,update,saveOrUpd</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/226693" style="color:red;">http://heshencao.javaeye.com/blog/226693</a>&nbsp;
          发表时间: 2008年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>hibernate的保存<br />hibernate对于对象的保存提供了太多的方法，他们之间有很多不同，这里细说一下，以便区别：<br />一、预备知识：<br />在所有之前，说明一下，对于hibernate，它的对象有三种状态，transient、persistent、detached<br />下边是常见的翻译办法：<br />transient：瞬态或者自由态<br />persistent：持久化状态<br />detached：脱管状态或者游离态</p>
<p>脱管状态的实例可以通过调用save()、persist()或者saveOrUpdate()方法进行持久化。<br />持久化实例可以通过调用 delete()变成脱管状态。通过get()或load()方法得到的实例都是持久化状态的。<br />脱管状态的实例可以通过调用 update()、0saveOrUpdate()、lock()或者replicate()进行持久化。</p>
<p>save()和persist()将会引发SQL的INSERT，delete()会引发SQLDELETE，<br />而update()或merge()会引发SQLUPDATE。对持久化（persistent）实例的修改在刷新提交的时候会被检测到，<br />它也会引起SQLUPDATE。saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE</p>
<p>二、save 和update区别<br />把这一对放在第一位的原因是因为这一对是最常用的。<br />save的作用是把一个新的对象保存<br />update是把一个脱管状态的对象保存</p>
<p>三,update 和saveOrUpdate区别<br />这个是比较好理解的，顾名思义，saveOrUpdate基本上就是合成了save和update<br />引用hibernate reference中的一段话来解释他们的使用场合和区别<br />通常下面的场景会使用update()或saveOrUpdate()： <br />程序在第一个session中加载对象 <br />该对象被传递到表现层 <br />对象发生了一些改动 <br />该对象被返回到业务逻辑层 <br />程序调用第二个session的update()方法持久这些改动 </p>
<p>saveOrUpdate()做下面的事: <br />如果对象已经在本session中持久化了，不做任何事 <br />如果另一个与本session关联的对象拥有相同的持久化标识(identifier)，抛出一个异常 <br />如果对象没有持久化标识(identifier)属性，对其调用save() <br />如果对象的持久标识(identifier)表明其是一个新实例化的对象，对其调用save() <br />如果对象是附带版本信息的（通过&lt;version&gt;或&lt;timestamp&gt;） 并且版本属性的值表明其是一个新实例化的对象，save()它。 <br />否则update() 这个对象 </p>
<p>四,persist和save区别<br />这个是最迷离的一对，表面上看起来使用哪个都行，在hibernate reference文档中也没有明确的区分他们.<br />这里给出一个明确的区分。（可以跟进src看一下，虽然实现步骤类似，但是还是有细微的差别）<br />这里参考<a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-1682">http://opensource.atlassian.com/projects/hibernate/browse/HHH-1682</a>中的一个说明：<br />---------------------------------------------------------------------------------<br />I found that a lot of people have the same doubt. To help to solve this issue <br />I'm quoting Christian Bauer:<br />"In case anybody finds this thread...</p>
<p>persist() is well defined. It makes a transient instance persistent. However, <br />it doesn't guarantee that the identifier value will be assigned to the persistent <br />instance immediately, the assignment might happen at flush time. The spec doesn't say <br />that, which is the problem I have with persist().</p>
<p>persist() also guarantees that it will not execute an INSERT statement if it is <br />called outside of transaction boundaries. This is useful in long-running conversations <br />with an extended Session/persistence context.A method like persist() is required.</p>
<p>save() does not guarantee the same, it returns an identifier, and if an INSERT <br />has to be executed to get the identifier (e.g. "identity" generator, not "sequence"), <br />this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context."</p>
<p>---------------------------------------------------------------------------------<br />简单翻译一下上边的句子的主要内容：<br />1，persist把一个瞬态的实例持久化，但是并"不保证"标识符被立刻填入到持久化实例中，标识符的填入可能被推迟<br />到flush的时间。</p>
<p>2，persist"保证"，当它在一个transaction外部被调用的时候并不触发一个Sql Insert，这个功能是很有用的，<br />当我们通过继承Session/persistence context来封装一个长会话流程的时候，一个persist这样的函数是需要的。</p>
<p>3，save"不保证"第2条,它要返回标识符，所以它会立即执行Sql insert，不管是不是在transaction内部还是外部</p>
<p><br />五,saveOrUpdateCopy,merge和update区别<br />首先说明merge是用来代替saveOrUpdateCopy的，这个详细见这里<br /><a href="http://www.blogjava.net/dreamstone/archive/2007/07/28/133053.html">http://www.blogjava.net/dreamstone/archive/2007/07/28/133053.html</a><br />然后比较update和merge<br />update的作用上边说了，这里说一下merge的<br />如果session中存在相同持久化标识(identifier)的实例，用用户给出的对象的状态覆盖旧有的持久实例 <br />如果session没有相应的持久实例，则尝试从数据库中加载，或创建新的持久化实例,最后返回该持久实例 <br />用户给出的这个对象没有被关联到session上，它依旧是脱管的 <br />重点是最后一句：<br />当我们使用update的时候，执行完成后，我们提供的对象A的状态变成持久化状态<br />但当我们使用merge的时候，执行完成，我们提供的对象A还是脱管状态，hibernate或者new了一个B，或者检索到<br />一个持久对象B，并把我们提供的对象A的所有的值拷贝到这个B，执行完成后B是持久状态，而我们提供的A还是托管状态</p>
<p>六,flush和update区别<br />这两个的区别好理解<br />update操作的是在脱管状态的对象<br />而flush是操作的在持久状态的对象。<br />默认情况下，一个持久状态的对象是不需要update的，只要你更改了对象的值，等待hibernate flush就自动<br />保存到数据库了。hibernate flush发生再几种情况下：<br />1，调用某些查询的时候<br />2，transaction commit的时候<br />3，手动调用flush的时候 </p>
<p>七,lock和update区别<br />update是把一个已经更改过的脱管状态的对象变成持久状态<br />lock是把一个没有更改过的脱管状态的对象变成持久状态<br />对应更改一个记录的内容，两个的操作不同：<br />update的操作步骤是：<br />（1）更改脱管的对象-&gt;调用update<br />lock的操作步骤是：<br />(2)调用lock把对象从脱管状态变成持久状态--&gt;更改持久状态的对象的内容--&gt;等待flush或者手动flush</p>
<p>参考内容：<br /><a href="http://www.blogjava.net/iamtin/archive/2006/03/06/33910.aspx">http://www.blogjava.net/iamtin/archive/2006/03/06/33910.aspx</a><br /><a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-1682">http://opensource.atlassian.com/projects/hibernate/browse/HHH-1682</a><br /><a href="http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/objectstate.html">http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/objectstate.html</a></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/226693#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 11 Aug 2008 17:49:41 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/226693</link>
        <guid>http://heshencao.javaeye.com/blog/226693</guid>
      </item>
          <item>
        <title>java的30个学习目标</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/220378" style="color:red;">http://heshencao.javaeye.com/blog/220378</a>&nbsp;
          发表时间: 2008年07月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <ol>
<li>你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式.你应该十分了解UML,尤其是class,object,interaction以及statediagrams.</li>
<li>你需要学习JAVA 语言的基础知识以及它的核心类库 (collections,serialization,streams,networking,multithreading,reflection,event,handling,NIO,localization, 以及其他).</li>
<li>你应该了解JVM,classloaders,classreflect,以及垃圾回收的基本工作机制等.你应该有能力反编译一个类文件并且明白一些基本的汇编指令.<br />
</li>
<li>如果你将要写客户端程序,你需要学习WEB的小应用程序(applet),必需掌握GUI设计的思想和方法,以及桌面程序的SWING,AWT,SWT.你还应该对UI部件的JAVABEAN组件模式有所了解.JAVABEANS也被应用在JSP中以把业务逻辑从表现层中分离出来.<br />
</li>
<li>你需要学习java数据库技术,如JDBCAPI并且会使用至少一种persistence/ORM构架,例如Hibernate,JDO,CocoBase,TopLink,InsideLiberator(国产JDO红工厂软件)或者iBatis.你还应该了解对象关系的阻抗失配的含义,以及它是如何影响业务对象的与关系型数据库的交互,和它的运行结果,还需要掌握不同的数据库产品运用,比如:oracle,mysql,mssqlserver.<br />
</li>
<li>你需要学习JAVA的沙盒安全模式(classloaders,bytecodeverification,managers,policyandpermissions,<br />
codesigning,digitalsignatures,cryptography,certification,Kerberos,以及其他)还有不同的安全/认证API, 例如 JAAS(JavaAuthenticationandAuthorizationService),JCE(JavaCryptographyExtension),JSSE(JavaSecureSocketExtension), 以及JGSS(JavaGeneralSecurityService).<br />
</li>
<li>你需要学习Servlets,JSP,以及JSTL(StandardTagLibraries)和可以选择的第三方TagLibraries.<br />
</li>
<li>你需要熟悉主流的网页框架,例如JSF,Struts,Tapestry,Cocoon,WebWork,以及他们下面的涉及模式,如MVC/MODEL2.<br />
</li>
<li>你需要学习如何使用及管理WEB服务器,例如tomcat,resin,Jrun,并且知道如何在其基础上扩展和维护WEB程序.<br />
</li>
<li>你需要学习分布式对象以及远程API,例如RMI和RMI/IIOP.<br />
</li>
<li>你需要掌握各种流行中间件技术标准和与java结合实现,比如Tuxedo、CROBA,当然也包括javaEE本身.<br />
</li>
<li>你需要学习最少一种的XMLAPI,例如JAXP(JavaAPIforXMLProcessing),JDOM(JavaforXMLDocumentObjectModel),DOM4J,或JAXR(JavaAPIforXMLRegistries).<br />
</li>
<li>你应该学习如何利用JAVAAPI和工具来构建WebService.例如JAX- RPC(JavaAPIforXML/RPC),SAAJ(SOAPwithAttachmentsAPIforJava),JAXB(JavaArchitectureforXMLBinding),JAXM(JavaAPIforXMLMessaging),JAXR(JavaAPIforXMLRegistries), 或者JWSDP(JavaWebServicesDeveloperPack).<br />
</li>
<li>你需要学习一门轻量级应用程序框架,例如Spring,PicoContainer,Avalon,以及它们的IoC/DI风格(setter,constructor,interfaceinjection).<br />
</li>
<li>你需要熟悉不同的J2EE技术,例如 JNDI(JavaNamingandDirectoryInterface),JMS(JavaMessageService),JTA/JTS(JavaTransactionAPI /JavaTransactionService),JMX(JavaManagementeXtensions),以及JavaMail.<br />
</li>
<li>你需要学习企业级JavaBeans(EJB)以及它们的不同组件模式：Stateless/StatefulSessionBeans,EntityBeans(包含Bean- ManagedPersistence[BMP]或者Container-ManagedPersistence[CMP]和它的EJB-QL),或者 Message-DrivenBeans(MDB).<br />
</li>
<li>你需要学习如何管理与配置一个J2EE应用程序服务器,如WebLogic,JBoss等,并且利用它的附加服务,例如簇类,连接池以及分布式处理支援.你还需要了解如何在它上面封装和配置应用程序并且能够监控、调整它的性能.<br />
</li>
<li>你需要熟悉面向方面的程序设计以及面向属性的程序设计(这两个都被很容易混淆的缩写为AOP),以及他们的主流JAVA规格和执行.例如AspectJ和AspectWerkz.<br />
</li>
<li>你需要熟悉对不同有用的API和framework等来为你服务.例如 Log4J(logging/tracing),Quartz(scheduling),JGroups(networkgroupcommunication),JCache(distributedcaching),Lucene(full- textsearch),JakartaCommons等等.<br />
</li>
<li>如果你将要对接或者正和旧的系统或者本地平台,你需要学习JNI(JavaNativeInterface)andJCA(JavaConnectorArchitecture).<br />
</li>
<li>你需要熟悉JINI技术以及与它相关的分布式系统,比如掌握CROBA.<br />
</li>
<li>你需要JavaCommunityProcess(JCP)以及他的不同JavaSpecificationRequests(JSRs),例如Portlets(168),JOLAP(69),DataMiningAPI(73),等等.<br />
</li>
<li>你应该熟练掌握一种JAVAIDE例如sunOne,netBeans,IntelliJIDEA或者Eclipse.(有些人更喜欢VI或EMACS来编写文件.随便你用什么了：))<br />
</li>
<li>JAVA(精确的说是有些配置)是冗长的,它需要很多的人工代码(例如EJB),所以你需要熟悉代码生成工具,例如XDoclet.<br />
</li>
<li>你需要熟悉一种单元测试体系(JNunit),并且学习不同的生成、部署工具(Ant,Maven).<br />
</li>
<li>你需要熟悉一些在JAVA开发中经常用到的软件工程过程.例如RUP(RationalUnifiedProcess)andAgilemethodologies.<br />
</li>
<li>你需要能够深入了解加熟练操作和配置不同的操作系统,比如GNU/linux,sunsolaris,macOS等,做为跨平台软件的开发者.<br />
</li>
<li>你还需要紧跟java发展的步伐,比如现在可以深入的学习javaME,以及各种java新规范,技术的运用,如新起的web富客户端技术.<br />
</li>
<li>你必需要对opensource有所了解,因为至少java的很多技术直接是靠开源来驱动发展的,如java3D技术.&nbsp;</li>
</ol>
          <br/><br/>
          <span style="color:red;">
            <a href="http://heshencao.javaeye.com/blog/220378#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 28 Jul 2008 11:50:04 +0800</pubDate>
        <link>http://heshencao.javaeye.com/blog/220378</link>
        <guid>http://heshencao.javaeye.com/blog/220378</guid>
      </item>
          <item>
        <title>动态代理类</title>
        <author>heshencao</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://heshencao.javaeye.com">heshencao</a>&nbsp;
                    链接：<a href="http://heshencao.javaeye.com/blog/218755" style="color:red;">http://heshencao.javaeye.com/blog/218755</a>&nbsp;
          发表时间: 2008年07月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span lang="EN-US" style="font-size: 12pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Java</span><span style="font-size: 12pt; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">动态代理类位于</span><span lang="EN-US" style="font-size: 12pt;">Java.lang.reflect</span><span style="font-size: 12pt; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">包下，一般主要涉及到以下两个类：</span><span lang="EN-US" style="font-size: 12pt;"></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US" style="font-size: 12pt;">(1). Interface InvocationHandler</span><span style="font-size: 12pt; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">：该接口中仅定义了一个方法</span><span lang="EN-U