繁体   English   中英

JAVA接口中实例变量的公共静态最终声明

[英]Public static final declaration of an instance variables in JAVA Interfaces

为什么我们在Java接口中使用实例变量的public static final声明?
所有变量都是Java接口中的隐式public static final
在常量变量中使用public static final是一种很好的编码实践,尽管它是在Interface中声明的。

例如 :

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;

}

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

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

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

我不这么认为。 所有接口变量都是隐式公共静态final,所以没有意义将它们标记为相同。

来自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
}

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

IMO,Interface是一份合同。 一旦声明或定义了变量,它们就不会改变。 这就是为什么我们通常会将它们作为public static final

可读性是使声明冗余的另一个因素。

不可否认,这是多余的。 通常人们只是不知道他们是隐含的public static final并且无论如何都要宣告它。 同上,例如声明:

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

通常它只是归结为一个事实,即人们不知道,他们没有宣布它的一种方式或其他。 我曾经和某个人(他是一个经验丰富的程序员)交谈,认为switchdefault情况是必需的,否则它将无法编译。

话虽如此,添加它们的唯一理由是它们澄清了它们的实际可见性和实际情况。 这是一个可读性和澄清的问题,是否包含它们或注意它们在实际行为方面是无关紧要的。

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

你是对的:这是多余的。 我不喜欢随时添加冗余语法。 然而,这种做法确实有其信徒。 有些人还喜欢在返回表达式周围添加括号,这是因为它有点像'if'语句; 额外的括号,以“澄清”三年级学生会理解的算术表达式; 它是生活丰富多彩的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM