简体   繁体   English

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

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

Why we use public static final declaration of instance variables in a Java Interface? 为什么我们在Java接口中使用实例变量的public static final声明?
All the variables are implicitly public static final in a Java Interface. 所有变量都是Java接口中的隐式public static final
Is it a good coding practice to use public static final in constant variable although it is declared inside an Interface. 在常量变量中使用public static final是一种很好的编码实践,尽管它是在Interface中声明的。

For example : 例如 :

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;

}

Use of uniform syntax in both classes and interfaces simplifies refactoring. 在类和接口中使用统一语法简化了重构。

You may want to turn your interface into a class somewhere in future, or move these fields into a class, and you'll get a semantical difference if you overlook some fields defined without public static final (of course, we have tools for refactoring, but nonetheless). 您可能希望将来将interface转换为某个class ,或者将这些字段移动到一个类中,如果忽略一些没有public static final定义的字段,您将获得语义差异(当然,我们有重构工具,但尽管如此)。

I think it's the same thing as support of @Overriden annotation for implementations of methods declared in interfaces that was introduced in Java 6 - it's redundant in its current form, but may become useful in case of refactoring. 我认为与支持@Overriden注释以支持在Java 6中引入的接口中声明的方法的实现相同 - 它在当前形式中是多余的,但在重构的情况下可能会变得有用。

I don't think so. 我不这么认为。 All interface variables are implicitly public static final so no meaning to mark them same. 所有接口变量都是隐式公共静态final,所以没有意义将它们标记为相同。

From the book Effective java by JOshua Bloch 来自JOshua Bloch的Effective java一书

Item 19: Use interfaces only to define types 第19项:仅使用接口来定义类型

When a class implements an interface, the interface serves as a type that can be used to refer to instances of the class. 当类实现接口时,接口充当可用于引用类实例的类型。 That a class implements an interface should therefore say something about what a client can do with instances of the class. 因此,类实现接口应该说明客户端可以对类的实例做什么。 It is inappropriate to define an interface for any other purpose. 为任何其他目的定义接口是不合适的。

One kind of interface that fails this test is the so-called constant interface. 一种未通过此测试的接口是所谓的常量接口。 Such an interface contains no methods; 这样的接口不包含任何方法; it consists solely of static final fields, each exporting a constant. 它仅由静态最终字段组成,每个字段都输出一个常量。 Classes using these constants implement the interface to avoid the need to qualify constant names with a class name. 使用这些常量的类实现接口,以避免使用类名限定常量名称。 Here is an example: 这是一个例子:

// 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;
}

The constant interface pattern is a poor use of interfaces. 常量接口模式是接口的不良使用。 That a class uses some constants internally is an implementation detail. 类在内部使用一些常量是一个实现细节。 Implementing a constant interface causes this implementation detail to leak into the class's exported API. 实现常量接口会导致此实现细节泄漏到类的导出API中。 It is of no consequence to the users of a class that the class implements a constant interface. 类的用户实现一个常量接口并不重要。 In fact, it may even confuse them. 事实上,它甚至可能使他们感到困惑。 Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. 更糟糕的是,它代表了一种承诺:如果在将来的版本中修改了类以便它不再需要使用常量,它仍然必须实现接口以确保二进制兼容性。 If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface. 如果非最终类实现了一个常量接口,那么它的所有子类的命名空间都会受到接口中常量的污染。

There are several constant interfaces in the Java platform libraries, such as java.io.ObjectStreamConstants. Java平台库中有几个常量接口,例如java.io.ObjectStreamConstants。 These interfaces should be regarded as anomalies and should not be emulated. 这些接口应视为异常,不应模拟。

If you want to export constants, there are several reasonable choices. 如果要导出常量,有几个合理的选择。 If the constants are strongly tied to an existing class or interface, you should add them to the class or interface. 如果常量与现有类或接口紧密相关,则应将它们添加到类或接口。 For example, all of the boxed numerical primitive classes, such as Integer and Double, export MIN_VALUE and MAX_VALUE constants. 例如,所有带框的数字基本类(如Integer和Double)都会导出MIN_VALUE和MAX_VALUE常量。 If the constants are best viewed as members of an enumerated type, you should export them with an enum type (Item 30). 如果常量最好被视为枚举类型的成员,则应使用枚举类型(第30项)导出它们。 Otherwise, you should export the constants with a noninstantiable utility class (Item 4). 否则,您应该使用不可实例化的实用程序类导出常量(第4项)。 Here is a utility class version of the PhysicalConstants example above: 这是上面的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;
}

Normally a utility class requires clients to qualify constant names with a class name, for example, PhysicalConstants.AVOGADROS_NUMBER. 通常,实用程序类要求客户端使用类名限定常量名称,例如PhysicalConstants.AVOGADROS_NUMBER。 If you make heavy use of the constants exported by a utility class, you can avoid the need for qualifying the constants with the class name by making use of the static import facility, introduced in release 1.5: 如果大量使用实用程序类导出的常量,则可以通过使用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
}

In summary, interfaces should be used only to define types. 总之,接口应仅用于定义类型。 They should not be used to export constants. 它们不应该用于导出常量。

IMO, Interface is a contract. IMO,Interface是一份合同。 Once variables are declared or defined they are not going to change. 一旦声明或定义了变量,它们就不会改变。 That's why generally we make them public static final . 这就是为什么我们通常会将它们作为public static final

Readability is another factor which makes declaration redundant. 可读性是使声明冗余的另一个因素。

Admittedly, it's redundant. 不可否认,这是多余的。 Usually people just don't know that they're implicitly public static final and declare it anyway. 通常人们只是不知道他们是隐含的public static final并且无论如何都要宣告它。 Ditto with things like declaring: 同上,例如声明:

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

Usually it just boils down to the fact that people don't know that they don't have to declare it one way or the other. 通常它只是归结为一个事实,即人们不知道,他们没有宣布它的一种方式或其他。 I once talked to someone (who was a seasoned programmer) that thought the default case in switch is required or it won't compile. 我曾经和某个人(他是一个经验丰富的程序员)交谈,认为switchdefault情况是必需的,否则它将无法编译。

That being said, the only argument to be made for adding them is that they clarify what their actual visibility and whatnot actually is. 话虽如此,添加它们的唯一理由是它们澄清了它们的实际可见性和实际情况。 It's a matter of readability and clarification, and whether or note to include them is irrelevant in terms of how it actually behaves. 这是一个可读性和澄清的问题,是否包含它们或注意它们在实际行为方面是无关紧要的。

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

You are correct: it is redundant. 你是对的:这是多余的。 I don't like to add redundant syntax at any time. 我不喜欢随时添加冗余语法。 However the practice does has its adherents. 然而,这种做法确实有其信徒。 Some also like to add parentheses around return-expressions, on the fallacious grounds that it's like an 'if' statement; 有些人还喜欢在返回表达式周围添加括号,这是因为它有点像'if'语句; extra parentheses to 'clarify' arithmetic expressions that a third-grader would understand; 额外的括号,以“澄清”三年级学生会理解的算术表达式; etc. It's all part of the rich tapestry of life. 它是生活丰富多彩的一部分。

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

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