zoukankan      html  css  js  c++  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 以下通过包装实现对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();
            }
        }
    }
    //包装request
    class 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。

  • 相关阅读:
    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
    解决 vim 报错:the imp module is deprecated in favour of importlib
    SIFT了解,哪些方法可以在现在的AI算法中借鉴?
    CLAHE
    实际算法项目工程上手日志C/C++
    OS X 切换gcc版本
    opencv3.4.2 cmake错误:in-source builds are not allowed
    C++ opencv 计算两张图像的PSNR相似度
    如何在OS X 中使用markdown + latex混合记笔记?
    给anaconda 换源
  • 原文地址:https://www.cnblogs.com/zhenghongxin/p/4401921.html
Copyright © 2011-2022 走看看