• java 泛型--桥方法


    因为 java 在编译源码时, 会进行 类型擦除, 导致泛型类型被替换限定类型(无限定类型就使用 Object). 因此为保持继承和重载的多态特性, 编译器会生成 桥方法.

    本文最后附录所有源码.

    Pair 是个泛型类, 它具有泛型方法 setSecond(T second),
    在经过编译时的 类型擦除 后变为 setSecond(Object second).

    DateInterval 是 Pair<LocalDate> 的实例化子类, 它具有方法 setSecond(LocalDate second).

    在 Main.main 中, 我们新建 DateInterval 对象, 并用基类 Pair<LocalDate> 来引用它,
    此时调用基类的 setSecond 方法时, 我们希望它能够实现多态, 即调用 DateInterval.setSecond(LocalDate) 方法.
    事实上, java 编译器通过插入 桥方法 的方式, 帮助我们实现了该功能.

    反编译 DateInterval.class 会发现它具有两个 setSecond 方法:

    1. void setSecond(LocalDate);
    2. void setSecond(Object).

    并且, 在 void setSecond(Object) 中会调用 void setSecond(LocalDate), 这就是所谓的桥方法.

    附: DateInterval.class 反编译后的代码:

    Compiled from "DateInterval.java"
    public class com.book.chapter8.DateInterval extends com.book.chapter8.Pair<java.time.LocalDate> {
      public com.book.chapter8.DateInterval();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method com/book/chapter8/Pair."<init>":()V
           4: return
    
      public void setSecond(java.time.LocalDate);
        Code:
           0: aload_1
           1: aload_0
           2: invokevirtual #2                  // Method getFirst:()Ljava/lang/Object;
           5: checkcast     #3                  // class java/time/chrono/ChronoLocalDate
           8: invokevirtual #4                  // Method java/time/LocalDate.compareTo:(Ljava/time/chrono/ChronoLocalDate;)I
          11: iflt          19
          14: aload_0
          15: aload_1
          16: invokespecial #5                  // Method com/book/chapter8/Pair.setSecond:(Ljava/lang/Object;)V
          19: return
    
      public void setSecond(java.lang.Object);
        Code:
           0: aload_0
           1: aload_1
           2: checkcast     #6                  // class java/time/LocalDate
           5: invokevirtual #7                  // Method setSecond:(Ljava/time/LocalDate;)V
           8: return
    }

    附: 其他所有源码:

    Pair.java:

    package com.book.chapter8;
    
    /**
     * Created by zhixiao.mzx on 2016/11/5.
     */
    public class Pair<T> {
        private T first;
        private T second;
    
        public Pair() {
            first = null;
            second = null;
        }
    
        public Pair(T first, T second) {
            this.first = first;
            this.second = second;
        }
    
        public T getFirst() {
            return first;
        }
    
        public void setFirst(T first) {
            this.first = first;
        }
    
        public T getSecond() {
            return second;
        }
    
        public void setSecond(T second) {
            this.second = second;
        }
    }

    DateInterval.java:

    package com.book.chapter8;
    
    import java.time.LocalDate;
    
    /**
     * Created by zhixiao.mzx on 2016/11/5.
     */
    public class DateInterval extends Pair<LocalDate> {
        public void setSecond(LocalDate second) {
            if (second.compareTo(getFirst()) >= 0) {
                super.setSecond(second);
            }
        }
    }

    Main.java:

    package com.book.chapter8;
    
    import java.time.LocalDate;
    
    /**
     * Created by zhixiao.mzx on 2016/11/5.
     */
    public class Main {
        public static void main(String[] args) {
            DateInterval interval = new DateInterval();
            Pair<LocalDate> pair = interval;
            pair.setFirst(LocalDate.now());
            pair.setSecond(LocalDate.now());
        }
    }
     
    分类: java
  • 相关阅读:
    Java字符串跟ASCII码互转
    java 一款可以与ssm框架完美整合的web报表控件
    使用<c:set>标签配置项目路径
    Linux下部署tomcat及tomcat war包应用程序
    支付宝app支付服务端流程
    文本数据增量导入到mysql
    java 读取mysql中数据 并取出
    实现读取文本数据,在将数据导入mysql
    给一个整形数组,给出一个值,当这个值是数组某些数字的和,求出数组下标的值
    文本数据和mysql 里面的数据比较
  • 原文地址:https://www.cnblogs.com/diegodu/p/7308493.html
Copyright © 2020-2023  润新知