Java泛型本质思考

65 阅读1分钟
  • Java泛型引起的问题:
    • 桥接方法
    • 不支持泛型数组
    • 无法在泛型类或泛型方法中使用new T、new T[]、instanceOf
    • 泛型类型变量不能是基本类型
    • 无法像C++一样提供实例化声明、模版特例化、模版重载、引用折叠
package com.example.lib;

import java.util.ArrayList;
import java.util.Comparator;

/**
 * Java泛型哲学:泛型擦除的本质:通过TypeVariable创建的对象会被擦除为Object类型,在使用时通过泛型推导在外部完成强制转换,这是为了兼容历史代码
 * GenericArrayType、ParameterizedType、TypeVariable、WildcardType
 */
public class GenericTest {

    public static void main(String[] args) {
        // Test 1
        Integer[] ia = {1, 2, 3};
        Integer[] ret = merge(ia);

        // Test 2
        GenericTest2<String> genericTest2 = new GenericTest2();
        genericTest2.setT("hello");
        String s = genericTest2.getT();
        // 下面这行报错,不能创建ParameterizedType数组,因为数组支持协变
        // 转换为Object[]之后,可以添加任何类型,破坏了泛型类型校验
        // ArrayList<String>[] arrayLists = new ArrayList<String>[3]; 
    }

    public static <T> ArrayList<? extends Comparable<T>> merge(ArrayList<? extends Comparable<T>> a,
                                                               ArrayList<? extends Comparable<T>> b) {
        return null;
    }

    public static <T> ArrayList<T> merge(ArrayList<T> a, ArrayList<T> b, Comparator<T> comparator, ArrayList<T>[] arrayLists) {
        new ArrayList<T>(3);
        
        return null;
    }

    public static <T> void merge(T[] a, T[] b, T[] ret, Comparator<T> comparator) {
        ret[0] = a[0];
        T[] tl = (T[]) new Object[10];
    }

    public static <T> T[] merge(T[] a) {
        Object[] obj = new Object[]{2, 4, 6};
        return (T[]) obj;
    }
}


class GenericTest2<T> {
    T t;

    public void setT(T t) {
        this.t = t;
    }

    public T getT() {
        return t;
    }
}