Java编程中的函数对象、嵌套类与泛型使用指南
立即解锁
发布时间: 2025-08-18 00:25:49 阅读量: 1 订阅数: 4 

# Java编程中的函数对象、嵌套类与泛型使用指南
## 1. 使用函数对象表示策略
### 1.1 函数指针与策略模式
在一些编程语言中,支持函数指针、委托、lambda表达式等功能,这些功能允许程序存储和传递调用特定函数的能力。以C标准库中的`qsort`函数为例,它接受一个比较器函数的指针,用于比较待排序的元素。比较器函数接受两个参数,根据元素的大小关系返回负整数、零或正整数,通过传递不同的比较器函数可以实现不同的排序顺序,这就是策略模式的一个示例,比较器函数代表了元素排序的策略。
### 1.2 Java中的函数对象
Java没有提供函数指针,但可以使用对象引用来达到类似的效果。定义一个只导出一个方法的类的实例,这个实例实际上就相当于该方法的指针,这样的实例被称为函数对象。例如:
```java
class StringLengthComparator {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
```
这个类的`compare`方法根据字符串的长度对字符串进行比较,`StringLengthComparator`对象的引用就相当于这个比较器的“函数指针”,可以对任意字符串对进行调用。
### 1.3 单例模式优化
由于`StringLengthComparator`类是无状态的,所有实例在功能上是等价的,因此可以将其实现为单例模式以节省不必要的对象创建成本:
```java
class StringLengthComparator {
private StringLengthComparator() { }
public static final StringLengthComparator
INSTANCE = new StringLengthComparator();
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
```
### 1.4 策略接口的定义
为了能够传递不同的比较策略,需要定义一个`Comparator`接口,并让`StringLengthComparator`类实现该接口:
```java
// Strategy interface
public interface Comparator<T> {
public int compare(T t1, T t2);
}
class StringLengthComparator implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
```
### 1.5 匿名类的使用
可以使用匿名类来创建函数对象,例如对字符串数组按长度排序:
```java
Arrays.sort(stringArray, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
```
但每次调用都会创建一个新的实例,如果需要多次使用,建议将函数对象存储在一个私有静态常量字段中并重复使用。
### 1.6 具体策略的导出
可以通过一个“宿主类”来导出具体策略,将具体策略类作为私有嵌套类,通过宿主类的公共静态字段或静态工厂方法来提供策略接口类型的对象:
```java
// Exporting a concrete strategy
class Host {
private static class StrLenCmp
implements Comparator<String>, Serializable {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
// Returned comparator is serializable
public static final Comparator<String>
STRING_LENGTH_COMPARATOR = new StrLenCmp();
// Bulk of class omitted
}
```
### 1.7 总结
函数指针的主要用途之一是实现策略模式。在Java中,通过声明一个接口来表示策略,为每个具体策略实现一个类。当具体策略只使用一次时,通常使用匿名类声明和实例化;当具体策略需要重复使用时,一般实现为私有静态成员类,并通过公共静态常量字段导出。
## 2. 优先使用静态成员类而非非静态成员类
### 2.1 嵌套类的分类
嵌套类是定义在另一个类中的类,主要有四种类型:静态成员类、非静态成员类、匿名类和局部类。除了静态成员类,其他三种都被称为内部类。
### 2.2 静态成员类
静态成员类是最简单的嵌套类,类似于普通类,只是声明在另一个类内部,并且可以访问外部类的所有成员,包括私有成员。它遵循与其他静态成员相同的可访问性规则。例如,一个描述计算器操作的枚举可以作为计算器类的公共静态成员类:
```mermaid
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(定义Calculator类):::process
B --> C(定义Operation枚举作为公共静态成员类):::process
C --> D(客户端通过Calculator.Operation访问操作
```
0
0
复制全文
相关推荐










