zoukankan      html  css  js  c++  java
  • Java基础加强

    *0 泛型设计
    a)泛型只是在源码级别上(.java)一个约束,字节码级别上(.class)该约束“擦除”
    b)对于多个Dao在编码上非常类似
    c)写一个BaseDao类,让具体类扩展其对应的方法,但在BaseDao中不能引入任何与具体类型的变量
    d)可以通过构造方法为实例变量赋值

    *1 反射泛型
    //取得BaseDao的字节码对象
    Class baseDaoClass = this.getClass();
    //取得BaseDao的泛型类型
    Type type = (Type) baseDaoClass.getGenericSuperclass();
    //将Type转发ParameterizedType,即取得BaseDao<Type>的参数化类型
    ParameterizedType pt = (ParameterizedType) type;
    //取得参数化类型中的实例参数类型,即Type
    this.clazz = (Class) pt.getActualTypeArguments()[0];
    int index = this.clazz.getName().lastIndexOf(".");
    //表名
    this.tableName = this.clazz.getName().substring(index+1).toLowerCase();

    BaseDao<T>泛型类型
    BaseDao<Type>参数化类型


    2 Annotation(注解@)
    a)// /**/ /** */javadoc 注释给程序员看,注解是给编译器看。
    b)JDK中有三个基本的注解
    @Override(检测是否覆盖父类的方法)
    @Deprecated(标识该方法已过时)
    @SuppressWarnings("unchecked")(压制编译器不要警告)

    @SuppressWarnings(value={"unchecked"})(压制编译器不要警告)
    c)注解:
    普通注解: 修饰方法的注解。
    元注解 : 修饰注解的注解。
    *3 自定义注解和反射注解
    a)定义注解格式如下:
    //自定义注解
    public @interface MyAnnotation {
    //属性
    String who();
    int age();
    String gender();
    //注解无方法
    }

    //注解使用
    @MyAnnotation(who="merry", age=20, gender="man")

    b)设置注解的默认值
    public @interface YouAnnotation {
    String who() default "marry";
    int age() default 22;
    String gender() default "female";
    }

    //注解使用
    @YouAnnotation
    or
    @YouAnnotation(who="sisi", age=21, gender="male") //覆盖所有默认属性
    or
    @YouAnnotation(who="sisi") //覆盖部分默认属性
    c)数组情况:
    public @interface TheyAnnotation {
    String[] value(); //value是个特殊的属性,可以省略value名字
    }
    //注解使用
    @TheyAnnotation(value={"电视","洗衣机","电脑"})
    or
    @TheyAnnotation({"电视","洗衣机","电脑"})

    d)反射注解:注解可以在一定程度上替代参数,属性文件,XML文件

    code:
    //Annotation类
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Role {
    String username() default "jack";
    String password() default "123456";
    }

    //使用注解类
    public class AnnotationDemo {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    Boolean flag = isOk("merry", "123");
    System.out.println(flag);
    flag = isOk("jack", "123456");
    System.out.println(flag);

    }

    @Role
    private static Boolean isOk(String username, String password) throws NoSuchMethodException, SecurityException {
    //反射注解
    Class clazz = AnnotationDemo.class;
    Method method = clazz.getDeclaredMethod("isOk", String.class, String.class);
    Role role = method.getAnnotation(Role.class);
    String annUsername = role.username();
    String annPassword = role.password();
    if (username.equals(annUsername) && password.equals(annPassword)) return true;
    return false;
    }
    }

    e)注解的策略[@Retention]
    1)RetentionPolicy.SOURCE:源码级别上可见,在字节码级别和运行时不可见,无法反射
    2)RetentionPolicy.CLASS:(默认)字节码级别上可见,在运行时不可见,无法反射
    3)RetentionPolicy.RUNTIME:运行时可见,可以反射,即在SOURCE和CLASS级别上都有

    f)标识注解可以使用的位置[@Target]
    ElementType.TYPE、ElementType.FIELD、ElementType.METHOD、ElementType.PARAMETER、ElementType.CONSTRUCTION、ElementType.LOCAL_VARIABLE

    g)写入文档[@Documented]
    被该元Annotation修饰的Annation类将被javadoc工具提取成文档。

    h)增加继承性[@Inherited]
    被它修饰的Annotation类将具有继承性。即:
    如果某个类使用了@Inherited修饰的Annotation类,那么被注解的类的子类也继承父类所对应的注解。
    注意:元注解可以修饰其它注解,元注解本身也可由其它元注解或其本身所修饰


    *4 代理
    a)静态代理 (一个代理类唯一代理一个对象)
    为什么会有代理?
    阻止对目标对象的直接访问
    如何代理?
    在代理对象中,写一个与目标对象一样的业务方法
    code:
    //明星接口
    public interface Star {
    public void sing();
    }
    //明星Jack
    public class StarJack implements Star {

    @Override
    public void sing() {
    System.out.println("唱歌");
    }
    }
    //明星Jack经纪人
    public class JackProxy implements Star{
    private StarJack jack = new StarJack();
    @Override
    public void sing() {
    jack.sing();
    }
    //得到明星Jack实体
    public Star getProxy() {
    return jack;
    }
    }
    //歌迷
    public class Fans {
    public static void main(String[] args) {
    //得到明星Jack的经纪人
    JackProxy proxy = new JackProxy();
    //通过代理人得到Jack对象
    StarJack jack = (StarJack) proxy.getProxy();
    //jack唱歌
    jack.sing();
    }
    }

    b)动态代理 (一个代理类可以代理多个对象)
    代理类的开发步骤:
    1)写一个普通类,无需任何继承或实现
    2)写一个实例变量,为代理的目标实例对象
    3)使用构造方法为实例变量赋值
    4)写一个普通方法,该方法的返回值是接口,该接口是目标对象的实现接口
    code:
    //明星接口
    public interface Star {
    public String sing(Integer money);
    public void dance(Integer money, String name);
    public void run(Integer money);
    }

    //明星Jack
    public class StarJack implements Star{
    @Override
    public String sing(Integer money) {
    System.out.println("唱歌");
    return "谢谢";
    }

    @Override
    public void dance(Integer money, String name) {
    System.out.println("jack 跳舞:" + name);
    }

    @Override
    public void run(Integer money) {
    System.out.println("跑步!");
    }
    }


    //Jack经纪人
    public class JackProxy {

    private StarJack jack = new StarJack();

    //参数一:代理类的类加载器
    //参数二:代理的目标类的接口
    //参数三:表示动态代理对象的拦截类,每次调用目标对象都会执行此类的invoke()方法。
    public Star getProxy() {
    //invoke()方法的三个参数的含义
    //参数一:动态产生的代理对象本身,此处为JackProxy实例对象proxy
    //参数二:method表示调用的方法
    //参数三:args表示调用方法的参数
    //***返回值: 作为代理的类的方法的返回值。
    Star star = (Star) Proxy.newProxyInstance(
    JackProxy.class.getClassLoader(),
    jack.getClass().getInterfaces(),
    new InvocationHandler() {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // System.out.println(method.getName());//sing
    // System.out.println(args[0]);//200
    Integer money = (Integer) args[0];
    if ( money< 200) {
    System.out.println("钱不够!");
    } else {
    if ("sing".equals(method.getName())) {
    String returnValue = (String) method.invoke(jack, args);
    System.out.println(returnValue);//谢谢!
    } else if ("dance".equals(method.getName())) {
    method.invoke(jack, args);
    } else if ("run".equals(method.getName())) {
    System.out.println("今天有事,不跑步了!");
    }
    }
    return null;
    }
    });
    return star;
    }
    }

    //歌迷
    public class Fans {
    public static void main(String[] args) {
    JackProxy proxy = new JackProxy();
    Star star = proxy.getProxy();
    star.sing(180);//钱不够!
    star.sing(200);//唱歌 谢谢
    star.dance(200, "恰恰舞");//jack 跳舞:恰恰舞
    star.run(200);//今天有事,不跑步了!
    }
    }


    5 动态代理案例
    1)解决网站POST和GET的统一编码问题
    code:
    //jsp
    GET方式:<a href="${pageContext.request.contextPath}/login?username=<%=URLEncoder.encode("杰克", "utf-8")%>&password=123456" >登录</a>
    <hr />
    POST方式:
    <form method="POST" action="${pageContext.request.contextPath}/login">
    <input type="text" name="username" /><br/>
    <input type="password" name="password"/> <br/>
    <input type="submit" vlaue="提交">
    </form>

    //Filter
    public class EncoderFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    RequestProxy proxy = new RequestProxy(request);
    chain.doFilter(proxy.getProxy(), response);
    }
    @Override
    public void destroy() {
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

    }

    //Proxy

    public class RequestProxy {

    private HttpServletRequest request;

    public RequestProxy(ServletRequest request) {
    this.request = (HttpServletRequest) request;
    }

    public HttpServletRequest getProxy() { //返回值必须是接口
    return (HttpServletRequest) Proxy.newProxyInstance(RequestProxy.class.getClassLoader(),
    request.getClass().getInterfaces(),
    new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String funMethod = method.getName();
    if ("getParameter".equals(funMethod)) {
    String requestMethod = request.getMethod();
    if ("GET".equals(requestMethod)) {
    String data = request.getParameter((String) args[0]);
    byte[] userBuf = data.getBytes("ISO8859-1");
    data = new String(userBuf, "UTF-8");
    return data;//此返回值,即为被代理的对象调用方法的返回值。
    } else {
    request.setCharacterEncoding("UTF-8");
    return method.invoke(request, args);
    }
    } else {
    return method.invoke(request, args);
    }
    }
    });
    }

    }


    //Servlet
    public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    System.out.println(username + " : " + password);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    System.out.println(username + " : " + password);
    }
    }

    2)解决网站输出流压缩的问题
    code:
    3)解决网站中返回Connection对象的代理问题
    code:
    //自定义连接池
    public class Pool {
    private static LinkedList<Connection> linkedList = new LinkedList<Connection>();
    static{
    //在加载Pool类时,创建10个连接,并加入到连接池中
    for(int i=0;i<10;i++){
    try {
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bbs","root","root");
    linkedList.addLast(conn);
    } catch (Exception e) {
    }
    }
    }
    //取得连接池中连接的个数
    public int getSize() {
    return linkedList.size();
    }
    /*取得一个空闲的连接,只能返回Connection的动态代理对象
    public Connection getConnection() {
    final Connection conn = linkedList.removeFirst();
    return (Connection) Proxy.newProxyInstance(
    Pool.class.getClassLoader(),
    conn.getClass().getInterfaces(),
    new InvocationHandler(){
    public Object invoke(
    Object proxy,
    Method method,
    Object[] args) throws Throwable {
    //如果调用的是close()方法
    if("close".equals(method.getName())){
    //将连接放回连接池
    linkedList.addLast(conn);
    //返回null
    return null;
    }else{
    return method.invoke(conn,args);
    }
    }
    });
    }
    */
    public Connection getConnection() {
    Connection conn = linkedList.removeFirst();
    return conn;//返回真Connection
    }
    }


    6 了解类加载的特点
    Java的类加载器有三层:
    1)BootStrap加载核心类库(最先), 即:加载jre/lib/rt.jar
    2)ExtClassLoader加载非核心的辅助类库(其次) ,即:加载jre/lib/ext/ *.jar
    3)AppClassLoader加载每个应用自已的类库(最后),即:加载classpath指定的所有jar和目录
    每个Java程序运行都需要启用上述三个类加载器


    a)全盘负责
    当加载一个非核心非辅助的类库时,如果涉及到其他的非核心非辅助类,都由该AppClassLoader全盘负责加载

    b)委托机制
    当加载一个类时,首先由父加载器依次加载,如果所有的父加载器都加载不到,最后再由自已加载

    c)缓存机制
    当加载一个类时,如果事先缓存中有对应的字节码,则直接取来用;如果没有,再临时加载,完成后依然放入到缓存中,以
    使下次重用

    7 URL和HttpURLConnection的使用
    1)服务端[GET]->手机
    (1)手机先发送请求,再接收服务端的响应
    (2)在服务端写到GET方式中
    code:

    2)手机->服务端[POST]
    (1)在服务端写到POST方式中
    code:

    3)对于中文方式:
    (1)通过URLEncoder进行URL编码,
    String username = "杰克";
    username = URLEncoder.encode(username,"UTF-8");
    (2)在服务端进行编码设置:
    request.setCharacterEncoding("UTF-8");
    (3)必须确保URL编码和解析一致

  • 相关阅读:
    百度地图根据经纬度计算瓦片行列号
    【完全开源】百度地图Web service API C#.NET版,带地图显示控件、导航控件、POI查找控件
    TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
    重中之重:委托与事件
    可复用代码:组件的来龙去脉
    [史上最全]C#(VB.NET)中位运算符工作过程剖析(译)
    物以类聚:对象也有生命
    导入导出Android手机文件
    Android修改system只读权限
    SSHDroid(SSH Server for Android)通过PC或命令连接android
  • 原文地址:https://www.cnblogs.com/SkyGood/p/4276188.html
Copyright © 2011-2022 走看看