java学习笔记—实现一个类MyInputStream(28)

9/6/2015来源:Java教程人气:1581

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以下通过包装实现对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。