泛型方法与有界通配符:提升代码灵活性与安全性
立即解锁
发布时间: 2025-08-18 00:25:49 订阅数: 4 

### 泛型方法与有界通配符:提升代码灵活性与安全性
#### 1. 泛型方法介绍
泛型方法与泛型类一样,能带来诸多好处,尤其是静态工具方法,非常适合进行泛型化。集合类中的许多“算法”方法,如`binarySearch`和`sort`,都已经实现了泛型化。
下面是一个返回两个集合并集的方法示例:
```java
// Uses raw types - unacceptable!
public static Set union(Set s1, Set s2) {
Set result = new HashSet(s1);
result.addAll(s2);
return result;
}
```
这个方法虽然能编译,但会产生两个警告。为了消除警告并确保类型安全,需要修改方法声明,引入类型参数来表示三个集合(两个参数和返回值)的元素类型。
```java
// Generic method
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
Set<E> result = new HashSet<E>(s1);
result.addAll(s2);
return result;
}
```
修改后的方法编译时不会产生警告,并且提供了类型安全和易用性。以下是一个简单的测试程序:
```java
// Simple program to exercise generic method
public static void main(String[] args) {
Set<String> guys = new HashSet<String>(
Arrays.asList("Tom", "Dick", "Harry"));
Set<String> stooges = new HashSet<String>(
Arrays.asList("Larry", "Moe", "Curly"));
Set<String> aflCio = union(guys, stooges);
System.out.println(aflCio);
}
```
运行该程序,会输出两个集合的并集。不过,`union`方法有一个限制,即三个集合的类型必须相同。可以使用有界通配符类型来提高方法的灵活性。
泛型方法的一个显著特点是,在调用时无需像调用泛型构造函数那样显式指定类型参数的值。编译器会通过检查方法参数的类型来推断类型参数的值,这个过程称为类型推断。
#### 2. 利用泛型方法简化实例创建
在创建参数化类型的实例时,调用泛型构造函数需要显式传递类型参数的值,这会导致代码冗余。可以编写泛型静态工厂方法来消除这种冗余。
```java
// Parameterized type instance creation with constructor
Map<String, List<String>> anagrams =
new HashMap<String, List<String>>();
// Generic static factory method
public static <K,V> HashMap<K,V> newHashMap() {
return new HashMap<K,V>();
}
// Parameterized type instance creation with static factory
Map<String, List<String>> anagrams = newHashMap();
```
使用泛型静态工厂方法可以使代码更加简洁。
#### 3. 泛型单例工厂模式
有时需要创建一个不可变但适用于多种不同类型的对象。由于泛型是通过类型擦除实现的,可以使用一个对象来满足所有所需的类型参数化,但需要编写一个静态工厂方法来为每个请求的类型参数化重复提供该对象。
以下是一个泛型单例工厂模式的示例:
```java
public interface UnaryFunction<T> {
T apply(T arg);
}
// Generic singleton factory pattern
private static UnaryFunction<Object> IDENTITY_FUNCTION =
new UnaryFunction<Object>() {
public Object apply(Object arg) { return arg; }
};
// IDENTITY_FUNCTION is stateless and its type parameter is
// unbounded so it's safe to share one instance across all types.
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> identityFunction() {
return (UnaryFunction<T>) IDENTITY_FUNCTION;
}
// Sample program to exercise generic singleton
public static void main(String[] args) {
String[] strings = { "jute", "hemp", "nylon" };
UnaryFunction<String> sameString = identityFunction();
for (String s : strings)
System.out.println(sameString.apply(s));
Number[] numbers = { 1, 2.0, 3L };
UnaryFunction<Number> sameNumber = identityFunction();
for (Number n : numbers)
System.out.println(sameNumber.apply(n));
}
```
虽
0
0
复制全文
相关推荐









