掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

java泛型中通配符有哪些 java泛型中?和T的区别

Java 泛型是一种强大的工具,使开发者能够在编译时检查类型安全,减少运行时类型转换错误。泛型中的通配符和类型参数(如 T)在实际编程中扮演着重要角色。本文将详细介绍 Java 泛型中的通配符以及 T 和 ? 的区别,并探讨它们的使用场景和注意事项。

一、Java 泛型中的通配符

  1. 什么是通配符

在 Java 泛型中,通配符是一种特殊的类型参数,用于表示未知类型。通配符通常用于方法签名、变量声明和方法调用中,以增加方法的灵活性和通用性。Java 中主要有三种通配符:无界通配符、上界通配符和下界通配符。

  1. 无界通配符

无界通配符使用 ? 表示,表示任何类型。它是最简单的通配符形式,可以用于任何类型的操作,但无法执行涉及类型的具体操作。

import java.util.List;
public class WildcardExample {
    // 无界通配符方法:打印列表中的元素
    public static void printList(List<?> list) {
        for (Object element : list) {
            System.out.println(element);
        }
    }
    public static void main(String[] args) {
        List<Integer> intList = List.of(1, 2, 3, 4);
        List<String> stringList = List.of("Hello", "World");
        printList(intList); // 输出整数
        printList(stringList); // 输出字符串
    }
}

在这个示例中,printList 方法接受一个 List<?> 类型的参数,可以处理任何类型的列表。虽然我们不能向列表中添加元素(因为类型未知),但我们可以在方法内部遍历和读取列表中的元素。

  1. 上界通配符

上界通配符使用 ? extends T 表示,表示类型 T 或其子类型。上界通配符主要用于读取操作,可以确保方法不会向列表中添加不兼容的元素。

import java.util.List;
public class UpperBoundExample {
    // 上界通配符方法:计算列表中元素的总和
    public static int sumOfNumbers(List<? extends Number> list) {
        int sum = 0;
        for (Number number : list) {
            sum += number.intValue(); // 只能读取,不能写入
        }
        return sum;
    }
    public static void main(String[] args) {
        List<Integer> intList = List.of(1, 2, 3, 4);
        List<Double> doubleList = List.of(1.5, 2.5, 3.5, 4.5);
        System.out.println("Sum of integers: " + sumOfNumbers(intList)); // 输出 10
        System.out.println("Sum of doubles: " + sumOfNumbers(doubleList)); // 输出 12.0
    }
}

在这个示例中,sumOfNumbers 方法接受一个 List<? extends Number> 类型的参数,可以处理任何 Number 及其子类型的列表。我们可以在方法内部遍历和读取列表中的元素,但不能向列表中添加新元素(因为类型未知)。

  1. 下界通配符

下界通配符使用 ? super T 表示,表示类型 T 或其父类型。下界通配符主要用于写入操作,可以确保方法不会从列表中读取不兼容的元素。

import java.util.List;
public class LowerBoundExample {
    // 下界通配符方法:填充列表
    public static void fillList(List<? super Integer> list) {
        for (int i = 1; i <= 5; i++) {
            list.add(i); // 只能写入,不能读取
        }
    }
    public static void main(String[] args) {
        List<Object> objList = new ArrayList<>();
        List<Integer> intList = new ArrayList<>();
        fillList(objList); // 可以填充 Object 类型的列表
        fillList(intList); // 可以填充 Integer 类型的列表
        System.out.println("Filled object list: " + objList); // 输出 [1, 2, 3, 4, 5]
        System.out.println("Filled integer list: " + intList); // 输出 [1, 2, 3, 4, 5]
    }
}

在这个示例中,fillList 方法接受一个 List<? super Integer> 类型的参数,可以处理任何 Integer 及其父类型的列表。我们可以在方法内部向列表中添加新元素,但不能从列表中读取元素(因为类型未知)。

二、Java 泛型中的 T 和 ? 的区别

1) T 的含义

T 是类型参数的一种,表示某种类型。T 通常用于定义泛型类、泛型方法和泛型接口。通过使用 T,我们可以编写通用的代码,适用于多种数据类型。

import java.util.List;
public class GenericClassExample {
    // 泛型类:定义一个简单的栈
    public static class Stack<T> {
        private List<T> elements;
        public Stack() {
            elements = new ArrayList<>();
        }
        public void push(T item) {
            elements.add(item);
        }
        public T pop() {
            if (elements.isEmpty()) {
                throw new IllegalStateException("Stack is empty");
            }
            return elements.remove(elements.size() - 1);
        }
    }
    public static void main(String[] args) {
        Stack<Integer> intStack = new Stack<>();
        intStack.push(1);
        intStack.push(2);
        System.out.println("Popped from integer stack: " + intStack.pop()); // 输出 2
        Stack<String> stringStack = new Stack<>();
        stringStack.push("Hello");
        stringStack.push("World");
        System.out.println("Popped from string stack: " + stringStack.pop()); // 输出 World
    }
}

在这个示例中,Stack<T> 是一个泛型类,T 表示栈中存储的元素类型。我们可以通过实例化 Stack<Integer> 和 Stack<String> 来创建整数栈和字符串栈。

2)? 的含义

? 是通配符的一种,表示未知类型。? 通常用于方法签名、变量声明和方法调用中,以增加方法的灵活性和通用性。? 不能用于创建对象或实例化泛型类。

import java.util.List;
public class WildcardExample {
    // 无界通配符方法:打印列表中的元素
    public static void printList(List<?> list) {
        for (Object element : list) {
            System.out.println(element);
        }
    }
    public static void main(String[] args) {
        List<Integer> intList = List.of(1, 2, 3, 4);
        List<String> stringList = List.of("Hello", "World");
        printList(intList); // 输出整数
        printList(stringList); // 输出字符串
    }
}

在这个示例中,printList 方法接受一个 List<?> 类型的参数,可以处理任何类型的列表。虽然我们不能向列表中添加元素(因为类型未知),但我们可以在方法内部遍历和读取列表中的元素。

3)T 和 ? 的主要区别

  1. 类型参数 vs 通配符:T 是类型参数,表示某种具体的类型;? 是通配符,表示未知类型。

  2. 类型安全:T 提供了更强的类型安全,可以在方法内部进行具体的类型操作;? 主要用于方法的输入和输出,不能进行具体的类型操作。

  3. 实例化对象:T 可以用于实例化泛型类或泛型方法;? 不能用于实例化对象,只能用于方法签名和变量声明。

  4. 使用场景:T 适用于定义泛型类、泛型方法和泛型接口;? 适用于方法签名、变量声明和方法调用中,以增加方法的灵活性和通用性。

java泛型中通配符有哪些 java泛型中?和T的区别

通过本文的探讨,我们深入理解了 Java 泛型中的通配符以及 T 和 ? 的区别,并探讨了它们的使用场景和注意事项。通配符和类型参数在实际编程中扮演着重要角色,能够显著提高代码的复用性和可读性。在实际开发中,开发者应根据具体需求选择合适的泛型类型,编写高质量、可维护的代码。希望本文的内容能够帮助读者更好地理解和运用 Java 泛型,提升编程技能。

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • 全球天气预报

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

  • 购物小票识别

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

  • 涉农贷款地址识别

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

  • 人脸四要素

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

  • 个人/企业涉诉查询

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

0512-88869195
数 据 驱 动 未 来
Data Drives The Future