泛型格式和用法

什么是泛型?

泛型就是定义一种规范,这种规范规定了类、接口、方法中可以接受的数据类型。它允许类、接口和方法在定义时使用参数化类型。这样可以在不确定具体类型的情况下编写通用的代码,并在实际使用时指定具体的类型参数。

泛型的格式

在Java中,泛型的基本格式包括在类、接口或方法名后面使用尖括号(<>)来声明泛型参数。

泛型类: 在类名后面使用尖括号(<>)声明泛型参数。例如:

public class Box<T> {
    private T value;
​
    public T getValue() {
        return value;
    }
​
    public void setValue(T value) {
        this.value = value;
    }
}
  • 在上面的例子中,Box<T> 中的 <T> 是泛型参数的声明,它表明这个类可以存储任意类型的数据。在类的实例化时,可以具体指定 T 的类型,例如 Box<Integer>Box<String>

  • 也可以public class Box<T extends Object> 通过extends Object 来限制泛型只能接收Object类及其子类

泛型方法: 在方法的返回类型前使用尖括号(<>)声明泛型参数。例如:

public <T> T genericMethod(T t) {
    // 方法体
    return t;
}
  • 在上面的例子中,<T> 声明了一个泛型参数 T,并将其用于方法的参数类型和返回类型中。这使得 genericMethod 方法可以接受任意类型的参数并返回相同的类型。

  • 也可以public <T extends Object> T method(T t) 通过extends Object 来限制泛型只能接收Object类及其子类

多个泛型参数: 如果需要在类、接口或方法中使用多个泛型参数,可以用逗号分隔它们。例如:

public class Pair<K, V> {
    private K key;
    private V value;
​
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
​
    public K getKey() {
        return key;
    }
​
    public V getValue() {
        return value;
    }
}
  • 在上面的例子中,Pair<K, V> 定义了两个泛型参数 KV,分别表示键和值的类型。在实例化 Pair 对象时,需要指定具体的类型,例如 Pair<String, Integer>

为什么要有泛型?

使用泛型的主要目的是提高代码的重用性、类型安全性和可读性。

  • 重用性: 泛型使得代码可以独立于特定的数据类型,可以被多种类型重复使用。

  • 类型安全性: 在编译时会进行类型检查,避免了在运行时出现类型转换错误。

  • 可读性: 泛型代码通常更加清晰和易于理解,因为它表达了代码的意图和约束。

当使用泛型时,有时我们希望限制泛型参数只能是特定的类或其子类。这种需求可以通过泛型的通配符和泛型的上界来实现。

泛型通配符 ?

泛型通配符 ? 表示未知类型,可以用于限制方法或类接受特定的类型。例如,我们有一个方法希望接受 Box 类型的对象,但是不关心具体是哪种类型:

public void printBox(Box<?> box) {
    System.out.println(box.getValue());
}

在上面的例子中,printBox 方法接受一个 Box<?> 类型的参数 box,表示这个方法可以接受任意类型的 Box 对象。? 表示通配符,可以接受任何类型。

使用具体类型参数 Box<T>

当使用具体类型参数 Box<T> 定义方法时,你需要明确指定 Box 的类型参数 T,并且方法只能接受这种具体类型的 Box 对象作为参数。例如,定义方法如下:

public void printBox(Box<Integer> box) {
    System.out.println("Box value: " + box.getValue());
}

这个方法 printBox 只能接受 Box<Integer> 类型的对象作为参数,不能接受 Box<String> 或其他类型的 Box。这种方式限制了方法的适用范围,但也提供了类型安全的保证。

区别和适用场景
  • 灵活性和通用性:

    • 使用 <?> 泛型通配符更加灵活,可以接受多种类型的 Box 对象,适用于对泛型参数不敏感的情况。

    • 使用具体类型参数 Box<T> 更具体,用于确切知道需要什么类型的 Box 对象的情况。

  • 类型安全性:

    • <?> 通配符在编译时无法获取具体类型信息,但可以安全地对泛型对象进行操作。

    • 具体类型参数 Box<T> 在编译时可以确保方法只能接受特定类型的 Box 对象,提供更严格的类型检查和安全性。

  • 适用场景:

    • 使用 <?> 通配符适合于能够接受和处理任何类型的泛型对象的情况,例如打印、遍历等操作。

    • 使用具体类型参数 Box<T> 适合于需要针对特定类型执行特定操作的情况,例如对整数 Box 进行特定的数学计算。

泛型的上界

通过使用泛型的上界,可以限制泛型参数必须是某个类的子类。例如,我们希望泛型参数必须是 Number 类或其子类:

public class Box<T extends Number> {
    private T value;
​
    public T getValue() {
        return value;
    }
​
    public void setValue(T value) {
        this.value = value;
    }
}

在上面的例子中,Box<T extends Number> 表示 T 必须是 Number 类或其子类。这样,就可以确保在 Box 类中只能存储 Number 类型的数据。

泛型方法的上界

类似地,对于泛型方法,也可以使用泛型的上界来限制方法的泛型参数。例如,我们有一个方法希望接受 Comparable 接口的实现类作为参数:

public <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}

在上面的例子中,<T extends Comparable<T>> 声明了一个泛型方法 compare,它要求 T 必须是实现了 Comparable<T> 接口的类。这样,就可以在方法中使用 compareTo 方法来比较泛型参数 obj1obj2

通过泛型的通配符 ? 和泛型的上界,可以有效地限制泛型参数的类型,使得代码更加类型安全和灵活。通配符 ? 可以接受任意类型,而泛型的上界则可以确保泛型参数必须是指定类或其子类。这些技术在Java中非常常见,用于提高代码的健壮性和可维护性。

实战

写一个compare()方法,可以比较两个对象的大小,由于不同对象的比较规则不同,所以需要传入一个比较方法。

每个对象的比较方法不同,我们可以设计一个接口,让每个对象实现这个接口。

public interface MyCompare<T> {
    boolean compare(T t1,T t2);
}
public class Main<T> {
    /**
     * 写一个compare方法,参数为要比较的对象以及比较的方式
     */
​
    public boolean compare(T o1, T o2,MyCompare<T> myCompare){
        return myCompare.compare(o1,o2);
    }
​
    public static void main(String[] args) {
        Main<Integer> main = new Main<>();
        //lambda表达式
        boolean ret = main.compare(1,2,(first,second)->first>second);
        //匿名内部类
        boolean ret1 = main.compare(1, 2, new MyCompare<Integer>() {
            @Override
            public boolean compare(Integer t1, Integer t2) {
                return t1>t2;
            }
        });
        System.out.println(ret+"  "+ ret1);
    }
}

匿名内部类和Lambda表达式-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知、508

你的鼓励实我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值