【Java】泛型 之 编写泛型

写泛型类比普通类要复杂。通常来说,泛型类一般用在集合类中,例如ArrayList<T>,我们很少需要编写泛型类。

如果我们确实需要编写一个泛型类,那么,应该如何编写它?

可以按照以下步骤来编写一个泛型类。

首先,按照某种类型,例如:String,来编写类:

java 复制代码
public class Pair {
    private String first;
    private String last;
    public Pair(String first, String last) {
        this.first = first;
        this.last = last;
    }
    public String getFirst() {
        return first;
    }
    public String getLast() {
        return last;
    }
}

然后,标记所有的特定类型,这里是String

java 复制代码
public class Pair {
    private String first;
    private String last;
    public Pair(String first, String last) {
        this.first = first;
        this.last = last;
    }
    public String getFirst() {
        return first;
    }
    public String getLast() {
        return last;
    }
}

最后,把特定类型String替换为T,并申明<T>

java 复制代码
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() {
        return first;
    }
    public T getLast() {
        return last;
    }
}

熟练后即可直接从T开始编写。

静态方法

编写泛型类时,要特别注意,泛型类型<T>不能用于静态方法。例如:

java 复制代码
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // 对静态方法使用<T>:
    public static Pair<T> create(T first, T last) {
        return new Pair<T>(first, last);
    }
}

上述代码会导致编译错误,我们无法在静态方法create()的方法参数和返回类型上使用泛型类型T。

有些同学在网上搜索发现,可以在static修饰符后面加一个<T>,编译就能通过:

java 复制代码
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // 可以编译通过:
    public static <T> Pair<T> create(T first, T last) {
        return new Pair<T>(first, last);
    }
}

但实际上,这个<T>Pair<T>类型的<T>已经没有任何关系了。

对于静态方法,我们可以单独改写为"泛型"方法,只需要使用另一个类型即可。对于上面的create()静态方法,我们应该把它改为另一种泛型类型,例如,<K>

java 复制代码
public class Pair<T> {
    private T first;
    private T last;
    public Pair(T first, T last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public T getLast() { ... }

    // 静态泛型方法应该使用其他类型区分:
    public static <K> Pair<K> create(K first, K last) {
        return new Pair<K>(first, last);
    }
}

这样才能清楚地将静态方法的泛型类型和实例类型的泛型类型区分开。

多个泛型类型

泛型还可以定义多种类型。例如,我们希望Pair不总是存储两个类型一样的对象,就可以使用类型<T, K>:

java 复制代码
public class Pair<T, K> {
    private T first;
    private K last;
    public Pair(T first, K last) {
        this.first = first;
        this.last = last;
    }
    public T getFirst() { ... }
    public K getLast() { ... }
}

使用的时候,需要指出两种类型:

java 复制代码
Pair<String, Integer> p = new Pair<>("test", 123);

Java标准库的Map<K, V>就是使用两种泛型类型的例子。它对Key使用一种类型,对Value使用另一种类型。

小结

编写泛型时,需要定义泛型类型<T>

静态方法不能引用泛型类型<T>,必须定义其他类型(例如<K>)来实现静态泛型方法;

泛型可以同时定义多种类型,例如Map<K, V>

相关推荐
island13146 分钟前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构 Stream 调度机制
c语言·开发语言·神经网络
云姜.8 分钟前
线程和进程的关系
java·linux·jvm
是码龙不是码农10 分钟前
支付防重复下单|5 种幂等性设计方案(从初级到架构级)
java·架构·幂等性
曹牧10 分钟前
Spring Boot:如何在Java Controller中处理POST请求?
java·开发语言
heartbeat..10 分钟前
JVM 性能调优流程实战:从开发规范到生产应急排查
java·运维·jvm·性能优化·设计规范
浅念-13 分钟前
C++入门(2)
开发语言·c++·经验分享·笔记·学习
WeiXiao_Hyy14 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
User_芊芊君子19 分钟前
CANN010:PyASC Python编程接口—简化AI算子开发的Python框架
开发语言·人工智能·python
苏渡苇20 分钟前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
团子的二进制世界26 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法