zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Smali语法
    css 实现垂直水平居中常用方法
    css border实现三角形
    vue-router学习笔记
    vuex状态管理
    es6 reduce的用法
    vue学习笔记
    chrome调式工具
    前端需要了解的http知识
    underscore.js and moment.js
  • 原文地址:https://www.cnblogs.com/diegodu/p/7308493.html
Copyright © 2011-2022 走看看