10

为什么我们public static final在 Java 接口中使用实例变量的声明?
所有变量都隐含public static final在 Java 接口中。尽管在接口中声明了常量变量,但在常量变量
中使用它是一种好的编码习惯吗?public static final

例如 :

public interface TestInterface{

public static final String EX_CONSTANT = "ABC";
public static final int EX_INT_CONSTANT = 5;
public static final double EX_DOUBLE = 5.0;
public static final Integer EX_INTEGER = 10;

}
4

7 回答 7

11

在类和接口中使用统一的语法可以简化重构。

您可能希望将来将您的字段转换interfaceclass某个地方,或者将这些字段移动到一个类中,如果您忽略了一些未定义的字段,您将获得语义上的差异public static final(当然,我们有重构工具,但仍然如此)。

我认为这与 Java 6 中引入的接口中声明的方法实现的注释支持是一样的@Overriden——它在当前形式中是多余的,但在重构的情况下可能会变得有用。

于 2012-09-20T18:49:43.763 回答
5

我不这么认为。所有接口变量都是隐式的 public static final 因此没有意义将它们标记为相同。

于 2012-09-20T18:45:33.687 回答
4

来自 JOshua Bloch 的《Effective java》一书

第 19 条:只使用接口来定义类型

当一个类实现一个接口时,该接口充当一种可用于引用该类实例的类型。因此,一个类实现了一个接口应该说明客户端可以对类的实例做什么。为任何其他目的定义接口是不合适的。

一种未通过此测试的接口是所谓的常量接口。这样的接口不包含任何方法;它仅由静态最终字段组成,每个字段都导出一个常量。使用这些常量的类实现接口以避免使用类名来限定常量名。这是一个例子:

// Constant interface antipattern - do not use!
public interface PhysicalConstants {
    // Avogadro's number (1/mol)
    static final double AVOGADROS_NUMBER = 6.02214199e23;
    // Boltzmann constant (J/K)
    static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    // Mass of the electron (kg)
    static final double ELECTRON_MASS = 9.10938188e-31;
}

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

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

如果要导出常量,有几种合理的选择。如果常量与现有的类或接口紧密相关,则应将它们添加到类或接口中。例如,所有装箱的数值基元类(如 Integer 和 Double)都导出 MIN_VALUE 和 MAX_VALUE 常量。如果最好将常量视为枚举类型的成员,则应该使用枚举类型导出它们(第 30 条)。否则,您应该使用不可实例化的实用程序类(第 4 项)导出常量。这是上面 PhysicalConstants 示例的实用程序类版本:

// Constant utility class
package com.effectivejava.science;

public class PhysicalConstants {
    private PhysicalConstants() {
    } // Prevents instantiation

    public static final double AVOGADROS_NUMBER = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS = 9.10938188e-31;
}

通常,实用程序类要求客户端使用类名来限定常量名,例如 PhysicalConstants.AVOGADROS_NUMBER。如果您大量使用实用程序类导出的常量,则可以通过使用 1.5 版中引入的静态导入工具来避免使用类名限定常量:

// Use of static import to avoid qualifying constants
import static com.effectivejava.science.PhysicalConstants.*;
public class Test {
    double atoms(double mols) {
        return AVOGADROS_NUMBER * mols;
    }
...
// Many more uses of PhysicalConstants justify static import
}

总之,接口应该只用于定义类型。它们不应该用于导出常量。

于 2013-07-18T10:29:13.180 回答
3

IMO,接口是一份合同。一旦变量被声明或定义,它们就不会改变。这就是我们通常制作它们的原因public static final

可读性是使声明变得多余的另一个因素。

于 2012-09-20T18:44:28.813 回答
2

诚然,这是多余的。通常人们只是不知道他们是隐含public static final的并且无论如何都要声明它。与声明类似:

public abstract interface Test { // Interfaces are always abstract
    public void testMethod(); // Interface methods are always public
    abstract void anotherTestMethod(); // Also redundant
}

通常归结为人们不知道他们不必一种或另一种方式声明它。我曾经和一个人(他是一位经验丰富的程序员)交谈过,他认为这个default案例switch是必需的,否则它不会编译。

话虽这么说,添加它们的唯一论据是它们阐明了它们的实际可见性和实际上是什么。这是一个可读性和澄清性的问题,是否包含它们与它的实际行为方式无关。

于 2012-09-20T18:45:52.523 回答
2

当您在一个程序员团队中工作时,您会发现初级程序员不知道默认情况下接口中的变量是public static final的事实,并且看到以这种方式声明的变量将为他们提供有关接口的额外信息和使用它的变量。

于 2012-09-20T19:07:41.087 回答
1

你是对的:它是多余的。我不喜欢随时添加多余的语法。然而,这种做法确实有它的拥护者。有些人还喜欢在 return 表达式周围添加括号,理由是它就像一个“if”语句。额外的括号来“澄清”三年级学生可以理解的算术表达式;等等。这都是丰富的生活挂毯的一部分。

于 2012-09-20T23:31:49.230 回答