你的位置:首页 > Java教程

[Java教程]java学习笔记—实现一个类MyInputStream(28)

1 实现一个类MyInputStream读取文件,且不能抛出异常

public class TestDemo {  public static void main(String[] args) throws Exception {    InputStream in = new MyInputStream("d:/a/a.txt");    byte[] b = new byte[1024];    int len = 0;    while((len=in.read(b))!=-1){      String s = new String(b,0,len);      System.err.print(s);    }    in.close();  }}

 

class MyInputStream extends InputStream { //成为inputstream的子类,即is a.  private InputStream in;   public MyInputStream(String fileName) {    try {      in = new FileInputStream(fileName);    } catch (FileNotFoundException e) {      e.printStackTrace();    }  }  public int read(byte[] b){    int len=-1;    try {      len = in .read(b);    } catch (IOException e) {      e.printStackTrace();    }    return len;  }  public void close(){    try {      in.close();    } catch (IOException e) {      e.printStackTrace();    }  }  @Override  public int read() throws IOException {    return 0;  }}

2 以下通过包装[W1] 实现对close方法的修改,以回收连接

   1:实现Connection接口,拥有一个Connection的成员。

 2:修改close方法。

 3:其他的方法都调用成员变量的connection。

public class MyDataSource implements DataSource {  private LinkedList<Connection> pool = new LinkedList<Connection>();  public MyDataSource() {    try {      Class.forName("com.mysql.jdbc.Driver");      String url = "jdbc:mysql:///db909?characterEncoding=UTf8";      for (int i = 0; i < 3; i++) {         //创建原生的连接,// com.mysql.jdbc.JDBC4Connection@8888        Connection con = DriverManager.getConnection(url, "root",            "1234");        //声明包装类        MyConn conn = new MyConn(con);         pool.add(conn);//将包装类添加到池中去      }    } catch (Exception e) {      e.printStackTrace();    }  }  //此方法来自于datasource,用于返回一个连接  public Connection getConnection() throws SQLException {    synchronized (pool) {      if (pool.size() == 0) {        try {          pool.wait();        } catch (InterruptedException e) {          e.printStackTrace();        }        return getConnection();      }      Connection con = pool.removeFirst();      System.err.println("siize:" + pool.size());      return con;    }  }

以下包装connection

class MyConn implements Connection {    // 声明被包装类的成员    private Connection conn; //com.mysql.jdbc.Jdbc4Connection@1111    // 通过构造接收MySql的connection的对象JDBC4Connection@8888    public MyConn(Connection con) {      this.conn = con;    }     //关闭连接    public void close() throws SQLException {      synchronized (pool) {        //有人调用了关闭方法,不能关        System.err.println("有人还连接了。。。。"+this);        pool.add(this);        pool.notify();      }    }}

 3、用包装处理get方式的乱码

package cn.itcast.utils;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;public class BaseServlet extends HttpServlet {  @Override  public void service(HttpServletRequest req, HttpServletResponse resp)      throws ServletException, IOException {    req.setCharacterEncoding("UTF-8");    String methodName = req.getParameter("cmd");    try{      Method mm = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);      //声明包装类      MyRequest mr = new MyRequest(req);      mm.invoke(this,mr,resp);    }catch(Exception e){      e.printStackTrace();    }  }}//包装requestclass MyRequest extends HttpServletRequestWrapper{  private HttpServletRequest req;  public MyRequest(HttpServletRequest request) {    super(request);    this.req=request;  }  //修改getparameter方法  @Override  public String getParameter(String name) {    String value = req.getParameter(name);    if(req.getMethod().equals("GET")){      System.err.println("转码");      try{        value = new String(value.getBytes("ISO-8859-1"),"UTF-8");      }catch(Exception e){      }    }    return value;  }}

总结:

1:代理或是包装都是对某个类的方法进行增强。

              代理:必须要根据给定的接口,在内存中创建这个接口的子类。$Proxy0。

              包装:不需要接口,但声明声明一个类,变成被包装类的子类,同时拥有一个被包装类的成员。

2:代理基本代码:

       Object proxyedObj =

              Proxy.newProxyInstance(ClassLoader,

                                                  New class[]{被代理的类的接口数组.class},

                                                 New InvocationHandler(){//执行句柄

                                                        Public Object invode(Object 代理,Method 方法反射,object[] args){

                                                               Reutrn method.invode(被代理类,args);

}

}

3:包装:

       如果一个类是某个类的包装类,则:

       A extends B{

              Privet B b;   

}

      

4:什么情况下,使用包装,什么情况下使用代理

       如果官方(SUN)提供了包装类适配器,则应该优先使用包装。如HttpServletRequest,它的包装类就是HtpServletRequestWraper.

       如果官方没有提供包装类的适配器,则可以使用动态代理。如Connection。