Java 教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java 与 C++
- JVM - Java 虚拟机
- Java - JDK 与 JRE 与 JVM
- Java - Hello World 程序
- Java - 环境设置
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode 系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期和时间
Java 控制语句
- Java - 循环控制
- Java - 决策制定
- Java - If-else
- Java - Switch
- Java - For 循环
- Java - For-Each 循环
- Java - While 循环
- Java - do-while 循环
- Java - Break
- Java - Continue
面向对象编程
- Java - OOPs 概念
- Java - 对象和类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造函数
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态
- Java - 重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造函数
- Java - 枚举字符串
Java 内置类
Java 文件处理
Java 错误和异常
- Java - 异常
- Java - try-catch 块
- Java - try-with-resources
- Java - 多重 catch 块
- Java - 嵌套 try 块
- Java - Finally 块
- Java - throw 异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java 多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 合并线程
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java 同步
Java 网络
- Java - 网络
- Java - Socket 编程
- Java - URL 处理
- Java - URL 类
- Java - URLConnection 类
- Java - HttpURLConnection 类
- Java - Socket 类
- Java - 泛型
Java 集合
Java 接口
Java 数据结构
Java 集合算法
高级 Java
- Java - 命令行参数
- Java - Lambda 表达式
- Java - 发送电子邮件
- Java - Applet 基础
- Java - Javadoc 注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像 API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional 类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64 编码解码
- Java - Switch 表达式
- Java - Teeing 收集器
- Java - 微基准测试
- Java - 文本块
- Java - 动态 CDS 归档
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 紧凑数字格式化
- Java - 垃圾回收
- Java - JIT 编译器
Java 杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - Process API 改进
- Java - Stream API 改进
- Java - 增强的 @Deprecated 注释
- Java - CompletableFuture API 改进
- Java - 流
- Java - Datetime Api
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 和框架
Java 类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用资源
Java - 泛型
如果我们可以编写一个单一的排序方法,该方法可以对 Integer 数组、String 数组或任何支持排序类型的数组中的元素进行排序,那就太好了。
为什么在 Java 中使用泛型?
泛型用于创建这样的类、接口和方法,这些类、接口和方法具有可以同时操作不同数据类型的参数。此功能是在 Java 5 中引入的。
Java - 泛型
Java 泛型方法和泛型类使程序员能够分别使用单个方法声明指定一组相关方法,或者使用单个类声明指定一组相关类型。
泛型还提供编译时类型安全,允许程序员在编译时捕获无效类型。
使用 Java 泛型概念,我们可以编写一个用于对对象数组进行排序的泛型方法,然后使用 Integer 数组、Double 数组、String 数组等调用泛型方法,对数组元素进行排序。
Java 泛型的优势
- 不牺牲类型安全
- 不需要类型转换
- 编译时检查
- 代码重用性和改进的性能
Java 泛型的类型
泛型方法
您可以编写一个可以调用不同类型参数的单个泛型方法声明。根据传递给泛型方法的参数类型,编译器会适当地处理每个方法调用。
定义泛型方法的规则
以下是定义泛型方法的规则:
所有泛型方法声明都具有一个由尖括号(< 和 >)分隔的类型参数部分,该部分位于方法的返回类型之前(在下一个示例中为 < E >)。
每个类型参数部分包含一个或多个用逗号分隔的类型参数。类型参数,也称为类型变量,是一个标识符,用于指定泛型类型名称。
类型参数可用于声明返回类型,并用作传递给泛型方法的参数类型的占位符,这些参数称为实际类型参数。
泛型方法的主体像任何其他方法一样声明。请注意,类型参数只能表示引用类型,不能表示基本类型(如 int、double 和 char)。
Java 泛型方法示例
以下示例说明了如何使用单个泛型方法打印不同类型的数组:
public class GenericMethodTest { // generic method printArray public static < E > void printArray( E[] inputArray ) { // Display array elements for(E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String args[]) { // Create arrays of Integer, Double and Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println("Array integerArray contains:"); printArray(intArray); // pass an Integer array System.out.println("\nArray doubleArray contains:"); printArray(doubleArray); // pass a Double array System.out.println("\nArray characterArray contains:"); printArray(charArray); // pass a Character array } }
输出
Array integerArray contains: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
有界类型参数
有时您可能希望限制允许传递给类型参数的类型的种类。例如,对数字进行操作的方法可能只希望接受 Number 或其子类的实例。这就是有界类型参数的用途。
要声明有界类型参数,请列出类型参数的名称,后跟 extends 关键字,后跟其上界。
有界类型参数示例
以下示例说明了 extends 如何以一般意义上表示“扩展”(如类)或“实现”(如接口)。此示例是返回三个 Comparable 对象中最大的泛型方法:
public class MaximumTest { // determines the largest of three Comparable objects public static <T extends Comparable<T>> T maximum(T x, T y, T z) { T max = x; // assume x is initially the largest if(y.compareTo(max) > 0) { max = y; // y is the largest so far } if(z.compareTo(max) > 0) { max = z; // z is the largest now } return max; // returns the largest object } public static void main(String args[]) { System.out.printf("Max of %d, %d and %d is %d\n\n", 3, 4, 5, maximum( 3, 4, 5 )); System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n", 6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 )); System.out.printf("Max of %s, %s and %s is %s\n","pear", "apple", "orange", maximum("pear", "apple", "orange")); } }
输出
Max of 3, 4 and 5 is 5 Max of 6.6,8.8 and 7.7 is 8.8 Max of pear, apple and orange is pear
泛型类
泛型类声明看起来像非泛型类声明,只是类名后跟一个类型参数部分。
与泛型方法一样,泛型类的类型参数部分可以包含一个或多个用逗号分隔的类型参数。这些类称为参数化类或参数化类型,因为它们接受一个或多个参数。
泛型类示例
以下示例说明了如何定义泛型类:
public class Box<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); Box<String> stringBox = new Box<String>(); integerBox.add(new Integer(10)); stringBox.add(new String("Hello World")); System.out.printf("Integer Value :%d\n\n", integerBox.get()); System.out.printf("String Value :%s\n", stringBox.get()); } }
输出
Integer Value :10 String Value :Hello World