Java泛型

1.元组

创建一个对象,用它来持有想返回的多个对象,这个概念称为元组。
它是将一组对象直接打包存储于其中的一个单一对象,这个容器对象允许读取其中元素,但是不允许向其中存放新的对象。(这个概念也称为数据传递对象)。
通常,元组可以具有任意长度,同时,元组中的对象可以是任意不同的类型。

/**
 * @Author ZhangGJ
 * @Date 2020/11/28 07:48
 */
public class TwoTuple<A, B> {
    public final A first;
    public final B second;

    public TwoTuple(A a, B b) {
        first = a;
        second = b;
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ")";
    }
}

2.泛型类、方法

当使用泛型类时,必须在创建对象的时候指定类型参数的值,而使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型,这称为类型参数推断。

3.擦除

考虑如下情况:

public class ErasedTypeEquivalence {
    public static void main(String[] args) {
        Class c1 = new ArrayList<String>().getClass();
        Class c2 = new ArrayList<Integer>().getClass();
        System.out.println(c1 == c2);
    }
}

Result:

true

你可能很疑惑为什么是true,没错,在泛型代码内部,无法获得任何有关泛型参数类型的信息。
Java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象,因此List<String>List<Integer>在运行时实际上是相同的类型,这两种形式都被擦除成为它们的“原生”类型,即List。

4.边界

如下代码无法编译:

/**
 * @Author ZhangGJ
 * @Date 2020/11/28 08:27
 */
class Manipulator<T> {

    private T obj;

    public Manipulator(T x) {
        obj = x;
    }

    /**
     * Error: cannot find symbol: method f():
     */
    public void manipulate() {
//        obj.f();  // error!
    }
}


public class Manipulation {
    public static void main(String[] args) {
        HasF hf = new HasF();
        Manipulator<HasF> manipulator = new Manipulator<HasF>(hf);
        manipulator.manipulate();
    }
}

由于有了擦除,Java编译器无法将manipulate()方法必须能够在obj上调用f() 这一需求映射到HasF拥有f()这一事实,为了能够调用f(),我们必须协助泛型类,给定泛型类的边界,代码如下:

/**
 * @Author ZhangGJ
 * @Date 2020/11/28 08:36
 */
public class Manipulator2<T extends HasF> {
    private T obj;

    public Manipulator2(T x) {
        obj = x;
    }

    public void manipulate() {
        obj.f();
    }
}

边界<T extends HasF>声明T必须具有类型HasF或者从HasF导出的类型。
泛型类型参数将擦除到它的第一个边界。

interface HasColor {
    Color getColor();
}


class Colored<T extends HasColor> {
    T item;

    Colored(T item) {
        this.item = item;
    }

    T getItem() {
        return item;
    }

    java.awt.Color color() {
        return item.getColor();
    }
}


class Dimension {
    public int x, y, z;
}


class ColoredDimension<T extends Dimension & HasColor> {
    T item;

    ColoredDimension(T item) {
        this.item = item;
    }

    T getItem() {
        return item;
    }

    java.awt.Color color() {
        return item.getColor();
    }

    int getX() {
        return item.x;
    }

    int getY() {
        return item.y;
    }

    int getZ() {
        return item.z;
    }
}


interface Weight {
    int weight();
}


class Solid<T extends Dimension & HasColor & Weight> {
    T item;

    Solid(T item) {
        this.item = item;
    }

    T getItem() {
        return item;
    }

    java.awt.Color color() {
        return item.getColor();
    }

    int getX() {
        return item.x;
    }

    int getY() {
        return item.y;
    }

    int getZ() {
        return item.z;
    }

    int weight() {
        return item.weight();
    }
}


class Bounded extends Dimension implements HasColor, Weight {

    @Override
    public Color getColor() {
        return null;
    }

    @Override
    public int weight() {
        return 0;
    }
}


/**
 * @Author ZhangGJ
 * @Date 2020/11/28 09:38
 */
public class BasicBounds {
    public static void main(String[] args) {
        Solid<Bounded> solid = new Solid<Bounded>(new Bounded());
        solid.color();
        solid.getY();
        solid.weight();
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值