接口私有方法
写过 JDK 8 的默认方法吗?一定遇到过这个问题:
几个默认方法里有重复逻辑,想提取成私有方法,但接口里不能定义 private 方法。
到了 JDK 9,这个限制解除了。
解决的问题
在 JDK 8 中,默认方法里如果有重复代码,你只能:
java
// JDK 8:没法提取公共私有方法
public interface Logger {
default void logInfo(String message) {
// 公共逻辑
String formatted = "INFO: " + format(message);
System.out.println(formatted);
logToFile(formatted);
}
default void logError(String message) {
// 同样的公共逻辑
String formatted = "ERROR: " + format(message);
System.out.println(formatted);
logToFile(formatted);
}
// ❌ 报错:Interface cannot have private methods
// private String format(String message) {
// return "[" + LocalDateTime.now() + "] " + message;
// }
}结果:要么代码重复,要么把公共逻辑抽取到一个独立的工具类里。
JDK 9 的方案
JDK 9 允许接口定义 private 方法:
java
public interface Logger {
default void logInfo(String message) {
String formatted = format("INFO", message);
save(formatted);
}
default void logError(String message) {
String formatted = format("ERROR", message);
save(formatted);
}
// ✅ JDK 9+:私有方法
private String format(String level, String message) {
return "[" + level + "] " + LocalDateTime.now() + ": " + message;
}
// ✅ 私有静态方法也可以
private static void save(String message) {
// 保存到日志文件
System.out.println("Saving: " + message);
}
}完整示例
java
public class LoggerDemo {
interface Logger {
default void info(String message) {
log("INFO", message);
}
default void warn(String message) {
log("WARN", message);
}
default void error(String message) {
log("ERROR", message);
}
default void error(String message, Throwable t) {
log("ERROR", message + " - " + t.getMessage());
}
// 私有方法:公共格式化逻辑
private String log(String level, String message) {
String formatted = format(level, message);
print(formatted);
return formatted;
}
// 私有静态方法
private static String format(String level, String message) {
return String.format("[%s] %s - %s",
LocalDateTime.now(),
level,
message
);
}
// 私有静态方法:打印到不同目的地
private static void print(String message) {
System.out.println(message);
// 实际场景可能是写入文件、发送到日志服务器等
}
}
// 使用默认实现
static class SimpleLogger implements Logger {}
public static void main(String[] args) {
Logger logger = new SimpleLogger();
logger.info("应用启动");
logger.warn("内存使用率 80%");
logger.error("连接数据库失败");
logger.error("处理请求异常", new RuntimeException("timeout"));
}
}私有方法的规则
可以是实例方法
java
interface Calculator {
// 私有实例方法
private int compute(int x) {
return x * x + 2 * x + 1; // x² + 2x + 1
}
default int evaluate(int x) {
return compute(x);
}
}可以是静态方法
java
interface StringUtils {
// 私有静态方法
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
static String process(String input) {
if (isBlank(input)) {
return "N/A";
}
return input.toUpperCase();
}
}不能被继承或实现
java
interface Parent {
private void helper() {
System.out.println("parent helper");
}
default void useHelper() {
helper(); // ✅ 可以调用自己的私有方法
}
}
interface Child extends Parent {
// ❌ 不能调用 Parent 的私有方法
// helper();
}
class Impl implements Child {
// ❌ 也不能调用
}
new Impl().useHelper(); // ✅ 输出 "parent helper"不能是 protected
java
interface Example {
// ❌ 报错:Modifier 'protected' not allowed
// protected void helper() {}
// ✅ 只能是 private
private void helper() {}
}常见使用场景
场景一:多个默认方法共享验证逻辑
java
public interface Validator {
default boolean validateEmail(String email) {
return validate(email, "^[\\w.-]+@[\\w.-]+\\.\\w+$");
}
default boolean validatePhone(String phone) {
return validate(phone, "^\\d{11}$");
}
default boolean validateId(String id) {
return validate(id, "^[A-Z]\\d{6,10}$");
}
// 私有方法提取公共验证逻辑
private boolean validate(String value, String regex) {
if (value == null || value.isBlank()) {
return false;
}
return value.matches(regex);
}
}场景二:复杂的默认方法拆解
java
public interface DataProcessor {
default void process(List<String> data) {
List<String> cleaned = clean(data);
List<String> transformed = transform(cleaned);
save(transformed);
}
private List<String> clean(List<String> data) {
return data.stream()
.filter(s -> !s.isBlank())
.map(String::trim)
.toList();
}
private List<String> transform(List<String> data) {
return data.stream()
.map(String::toUpperCase)
.toList();
}
private void save(List<String> data) {
System.out.println("Saving " + data.size() + " items");
}
}场景三:状态检查
java
public interface StateMachine {
default void handleEvent(String event) {
if (isActive()) {
processEvent(event);
} else {
handleInactive(event);
}
}
private boolean isActive() {
return true; // 实际场景中可能是复杂的状态检查
}
private void processEvent(String event) {
System.out.println("Processing: " + event);
}
private void handleInactive(String event) {
System.out.println("Ignoring (inactive): " + event);
}
}小结
接口私有方法是 JDK 9 的一个小功能,但解决了实际问题:
| JDK 版本 | 能力 |
|---|---|
| JDK 8 | 默认方法 + 静态方法(必须是 public) |
| JDK 9+ | 新增 私有实例方法 + 私有静态方法 |
什么时候用它:
- 多个默认方法有重复逻辑 → 提取成私有方法
- 不想让实现类看到内部实现 → 私有方法隐藏细节
- 简化默认方法的复杂度 → 拆成多个私有方法逐步处理
记住:私有方法只能在接口内部使用,不能被实现类继承或调用。
