|
| 1 | +package cool.scx.function; |
| 2 | + |
| 3 | +/// 设计哲学与背景说明: |
| 4 | +/// |
| 5 | +/// 1. 函数式接口的存在是 Java 语言的一个 "不得已而为之" 的产物. |
| 6 | +/// Java 本身对函数作为一等公民的支持远不如一些函数式语言, |
| 7 | +/// 因此需要通过函数式接口来模拟函数行为. |
| 8 | +/// 本接口力求在这种限制下尽可能的还原 "函数" 的本质. |
| 9 | +/// |
| 10 | +/// 2. 命名哲学: |
| 11 | +/// 函数式接口的命名, 要么做到 "具体业务语义明确", |
| 12 | +/// 要么做到 "绝对中立且结构统一". |
| 13 | +/// JDK 自带的 Supplier, Consumer, Function 等接口, |
| 14 | +/// 既不够具体, 又不够中立, 命名语义模糊, 使用时需要人为推断含义, 增加了认知负担. |
| 15 | +/// 本接口选择保持绝对中立, 仅表达 "参数个数" 和 "返回值有无". |
| 16 | +/// |
| 17 | +/// 3. 关于异常传播: |
| 18 | +/// JDK 的函数式接口不支持抛出受检异常 (Checked Exception), |
| 19 | +/// 这导致实际开发中, 处理受检异常会非常繁琐, 需要手动捕获或者强行转换为 RuntimeException. |
| 20 | +/// 本接口通过泛型参数 X extends Throwable 支持异常泛型, |
| 21 | +/// 让函数式接口能自然传播受检异常 避免异常封装与侵入式捕获. |
| 22 | +/// 这其实还原了 "函数" 的最本质的概念. |
| 23 | +/// |
| 24 | +/// 4. 关于基本类型特化: |
| 25 | +/// 虽然基本类型特化 (如 IntFunction) 可以避免装箱拆箱的性能损耗, |
| 26 | +/// 但全面特化所有参数和返回值, 会导致类的数量呈指数级爆炸, 达到不可维护的规模 (理论上亿级别). |
| 27 | +/// 经过权衡, 我们放弃全面特化. |
| 28 | +/// 当然随着 Java 未来的发展, 可能会引入基本类型的泛型支持 (如 Project Valhalla). |
| 29 | +/// 届时本接口也能够自然支持, 无需做任何改动. |
| 30 | +/// |
| 31 | +/// 5. 命名规则说明: |
| 32 | +/// - 接口名称采用统一格式: Function + 参数个数 + (Void 表示无返回值) |
| 33 | +/// 例如 Function2 表示两个参数有返回值的函数, Function3Void 表示三个参数无返回值的函数. |
| 34 | +/// - 泛型参数统一按字母顺序排列 (A, B, C, D...), 异常类型统一为 X extends Throwable. |
| 35 | +/// - 方法名固定为 apply, 保持接口简洁一致. |
| 36 | +/// |
| 37 | +/// 6. 相比 Java 自带接口的优势: |
| 38 | +/// - 命名与结构完全中立, 仅表示 "函数" 这一概念, 避免了含糊不清的命名. |
| 39 | +/// - 支持受检异常传播, 提升异常处理能力. |
| 40 | +/// - 命名结构统一, 便于快速识别和使用. |
| 41 | +/// - 放弃不必要的类型特化, 保持代码库轻量. |
| 42 | +@FunctionalInterface |
| 43 | +public interface Function1<A, R, X extends Throwable> { |
| 44 | + |
| 45 | + R apply(A a) throws X; |
| 46 | + |
| 47 | +} |
0 commit comments