【问题标题】:Java 8: When the use of Interface static methods becomes a bad practice?Java 8:何时使用接口静态方法成为一种不好的做法?
【发布时间】:2026-01-03 05:40:01
【问题描述】:

从 Java 8 开始,我们可以在接口中使用默认方法和静态方法。

常量接口模式是对被称为常量接口反模式的接口的不良使用。

>Effective Java,第 17 项:

常量接口模式是接口使用不当。一个类在内部使用一些常量是一个实现细节。 实现一个常量接口会导致这个实现细节 泄漏到类的导出 API 中。对它没有任何影响 一个类的用户认为该类实现了一个常量接口。在 事实上,它甚至可能使他们感到困惑。更糟糕的是,它代表了一种承诺:如果 在未来的版本中,该类被修改,使其不再需要 要使用常量,它仍然必须实现接口以确保 二进制兼容性。如果一个非final类实现了一个常量 接口,它的所有子类的命名空间都会被污染 通过接口中的常量。

java平台库中有几个常量接口, 例如 java.io.ObjectStreamConstants。这些接口应该是 视为异常,不应仿效。

如果使用常量接口是一种不好的做法,那么何时使用接口静态方法可能会成为一种不好的做法?

【问题讨论】:

    标签: java interface


    【解决方案1】:

    常量接口的主要问题不是接口包含很多常量。

    当类实现该接口以便他们可以更轻松地访问常量时:

    public interface Foo {
        public static final int CONSTANT = 1;
    }
    
    public class NotOkay implements Foo {
        private int value = CONSTANT;
    }
    
    public class Okay {
        private int value = Foo.CONSTANT;
    }
    

    NotOkay 类不仅在接口Foo 和它自己之间创建了一个虚假的关系(那里真的没有什么可以实现的),而且常量值成为其公共 API 的一部分。

    (在 Java 5 中引入 static imports 之前,这种做法更为普遍。)

    对于静态接口方法,实现接口确实没有意义,因为您不能以相同的方式访问它们:静态接口方法不会被继承。

    【讨论】:

    • 我不明白为什么有人会为此实现接口而不是指定Foo.CONSTANTimport static Foo.CONSTANT;(如果可行的话),但是是的,我明白为什么这是一个坏习惯。
    • @EpicPandaForce 这种不好的做法在引入静态导入之前很普遍(在 Java 5 中)。
    • 啊……这很有道理。 Java 在 1.5 之前就是地狱。
    • @EpicPandaForce 它甚至被用于 JDK。例如。看看 SwingConstants 界面。
    • @biziclop 这就是我要说的。这是罪魁祸首link的链接
    【解决方案2】:

    什么时候使用接口静态方法可能成为一种不好的做法?

    专家告诉我(我认为是 Angelika Langer 和 Klaus Kreft 在 Java 用户组活动中),当您有一些静态方法时,通常可以在界面中使用它们(参见 Stream ),但是如果它们中有很多,那么最好将它们放在实用程序类中(请参阅Collectors)。否则将很难看到接口的实际方法。

    这似乎是有道理的,并且是一个很好的经验法则。

    【讨论】:

      最近更新 更多