常量集合是否应该放置在类或接口中?

发布于 2024-08-03 07:07:01 字数 456 浏览 4 评论 0原文

如果我有一个静态常量集合,我想集中声明它们,以便将它们放入类或接口(Java)中,以便可以在各个项目之间共享它们。

在过去,我看到它们大多放在一个类中,但我开始认为,由于类不会也不应该被实例化,也许它们在接口中会更好,但话又说回来,接口不应该由任何类实现,例如

public class ErrorCodes {
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";
}

或者

public interface ErrorCodes {
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";
}

If I have a collection of static constants that I want to declare centrally so that they can be shared among various projects should they be put in a class or interface (Java).

In the past I have seen them mostly put in a class but I started thinking that since the class will not and should not be instantiated maybe they would be better in an interface, but then again the interface should not be implemented by any classes, e.g.

public class ErrorCodes {
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";
}

or

public interface ErrorCodes {
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

幼儿园老大 2024-08-10 07:07:01

如果它们具有很强的连接,那么我会将它们放入枚举中:

public enum Error {
  ERROR_1("-1", "foo went wrong"),
  ERROR_2("-2", "bar went wrong");

  private final String id;
  private final String message;

  Error(String id, String message) {
    this.id=id;
    this.message=message;
  }

  public String getId() {
    return id;
  }

  public String getMessage() {
    return message;
  }
}

优点是您可以在代码中实现类型安全,并且可以轻松添加基于 id 的查找(通过构建 HashMap 在构造函数中或通过简单地循环 values())。

If they have strong connections, then I'd put them in an enum:

public enum Error {
  ERROR_1("-1", "foo went wrong"),
  ERROR_2("-2", "bar went wrong");

  private final String id;
  private final String message;

  Error(String id, String message) {
    this.id=id;
    this.message=message;
  }

  public String getId() {
    return id;
  }

  public String getMessage() {
    return message;
  }
}

The advantage is that you can have type safety in your code and that you can easily add id-based lookup (either by building a HashMap<String,Error> in the constructor or by simply looping over values()).

唠甜嗑 2024-08-10 07:07:01

有些人认为常量接口是一种反模式(http://en.wikipedia.org/wiki/Constant_interface< /a>) 。

Some people consider constant-interface an anti-pattern (http://en.wikipedia.org/wiki/Constant_interface) .

云巢 2024-08-10 07:07:01

你应该在课堂上做。

接口是类用户可以访问的可用方法、属性等的描述 - 通过实现接口,您可以保证接口中声明的成员可供用户使用。

另一方面,类是对象的描述,或者(如果您对 OO 原则不是太严格的话……)静态成员的占位符。我个人发现在某些项目中在 Settings 类中存储一堆常量非常有用,因此我不必在整个项目中查找定义。我认为这种方法也是您所追求的。

You should do it in a class.

An Interface is a description of available methods, properties etc that class users can access - by implementing an interface, you guarantee that the members declared in the interface are available to the user.

A class, on the other hand, is a description of an object or (if you're not too hard on the OO principles...) a placeholder for static members. I personally find it very useful in some projects to store away a bunch of constants in a Settings class, so I don't have to look around in the entire project for the definitions. I think this approach is what you're after, too.

南汐寒笙箫 2024-08-10 07:07:01

之前已经讨论过

您不希望接口中的常量的原因是它会诱使客户端类“实现”该接口(以便访问常量而不用接口名称作为前缀)。不过,您不应该这样做 - 该接口实际上并不是对象功能的接口,而是类外部类型中根深蒂固的编译时便利性。

曾经有一段时间,“常量接口”非常方便,但它一直是“错误的”,而且现在我们有了 import static 语句,甚至懒惰都不能成为使用它的借口。

编辑:尽管我必须同意,对于您问题中提出的场景,枚举更合适。

This has been discussed before:

The reason why you don't want the constants in an interface is that it entices client classes to "implement" that interface (in order to access the constants without prefixing them with the interface name). You shouldn't, though - the interface isn't actually an interface to the object's capabilities, but a compile-time convenience ingrained in the class' external type.

There was a time when the "constant interface" was very convenient, but it has always been "wrong" and not even laziness is an excuse to use it now that we have import static statements.

Edit: Although I must agree that for the scenario presented in your question, enums are more appropriate.

明媚如初 2024-08-10 07:07:01

应考虑使用静态导入此处(用于导入类中定义的常量),或 类型安全枚举

来自 常量接口

在 Java 早期,将常量​​放入接口中是一种流行的技术,但现在许多人认为这是一种令人厌恶的接口使用方式,因为接口应该处理对象提供的服务,而不是其数据.
同样,类使用的常量通常是实现细节,但将它们放在接口中会将它们提升为类的公共 API。


The use of static import should be considered here (for importing constants defined in a class), or type-safe Enum.

From Interface for constants

Placing constants in an interface was a popular technique in the early days of Java, but now many consider it a distasteful use of interfaces, since interfaces should deal with the services provided by an object, not its data.
As well, the constants used by a class are typically an implementation detail, but placing them in an interface promotes them to the public API of the class.

高跟鞋的旋律 2024-08-10 07:07:01

您应该将它们放在带有私有构造函数的类中。

public class ErrorCodes {
    private ErrorCodes() {} // prevents instantiation
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";

或者

更好的是,使用类型安全的枚举。

You should put them on the class with a private constructor.

public class ErrorCodes {
    private ErrorCodes() {} // prevents instantiation
    public static final String ERROR_1 = "-1";
    public static final String ERROR_2 = "-2";

}

Or better yet, use a typesafe enum.

云胡 2024-08-10 07:07:01

我建议结合使用静态导入和常量接口。

如果 Java 接口具有常量字段声明,请记住它们隐式是公共的、静态的和最终的(请参阅 Java 语言规范,Section 9.3。)因此,您始终可以省略这些修饰符,只留下类型,你的常量界面将如下所示:

public interface Constants {
    int AGE = 0x23;
    String NAME = "Andrew";
    boolean IGNORE = true;
}

当然,这应该按如下方式使用:

import static Constants.*;

public Whatever {
    public String method() {
        return String.format("%s is %d%c", NAME, AGE, IGNORE ? '?' : '!');
    }
}

我在我的生产代码中使用这种样式没有任何问题,并且感觉它会导致非常整洁,紧凑的常量集合,可以处理枚举无法处理的各种类型的常量,并且可以根据需要进行扩展,这与枚举不同。

另一种可能性(并非所有人都会同意)是在父接口中嵌套接口(甚至枚举类型),从而允许您对常量进行分组。这:

interface MoreConstants {
    int MAGIC = 0xCAFEBABE;
    interface PROPERTIES {
        String NAME = "name";
    }
    enum ERRORS {
        ON_FIRE, ASLEEP, BROKEN, UNSURE;
    }
}

并像这样访问它们,假设静态导入 MoreConstants 接口:

if (!PROPERTIES.NAME.equals(value)) {
    return ERRORS.UNSURE;
}

当然,这些接口永远不应该被实现,我认为这是不好的做法。然而,确保这一点的唯一方法是严格的代码审查......

I recommend a combination of static imports and interfaces for constants.

If a Java interface has constant field declarations, bear in mind that these are implicitly public, static and final (see the Java Language Specification, Section 9.3.) You can therefore always omit these modifiers, leaving only the type, and your constant interface would look like this:

public interface Constants {
    int AGE = 0x23;
    String NAME = "Andrew";
    boolean IGNORE = true;
}

This should, of course, only ever be used as follows:

import static Constants.*;

public Whatever {
    public String method() {
        return String.format("%s is %d%c", NAME, AGE, IGNORE ? '?' : '!');
    }
}

I have no issues using this style in my production code, and feel it leads to a very neat, compact constants collection, and can cope with various types of constant, which an enum couldn't, as well as being able to be extended if requred, unlike an enum.

Another possibility, which not everyone will approve of, is to nest interfaces (or even enum types) in your parent interface, allowing you to group your constants. This :

interface MoreConstants {
    int MAGIC = 0xCAFEBABE;
    interface PROPERTIES {
        String NAME = "name";
    }
    enum ERRORS {
        ON_FIRE, ASLEEP, BROKEN, UNSURE;
    }
}

and access them like this, assuming a static import of the MoreConstants interface:

if (!PROPERTIES.NAME.equals(value)) {
    return ERRORS.UNSURE;
}

Of course, these interfaces should never be implemented, which I would consider bad practice. The only way to ensure this, however, is strict code reviews...

伴我老 2024-08-10 07:07:01

使用常量接口是一个很好的实践。但您不想实现该接口来使用常量。但使用静态导入如下。

package com.data.job.spark;

public interface Constants {

    /** base api url string literal. */
    public static final String BASE_API_URL = "/api/v1";
        /** message string literal. */
    public static final String MESSAGE = "message";

    /** exception string literal. */
    public static final String EXCEPTION = "exception";
}
=================================
import static com.data.job.spark.Constants.EXCEPTION;

@Component("user360ToScyllaDbLoader")
public class TestConstants implements Serializable{


    private static final long serialVersionUID = 1L;
}

Using Interface for constants is a good practice. But you do not want to implement that interface to use the constants. But use static import as below.

package com.data.job.spark;

public interface Constants {

    /** base api url string literal. */
    public static final String BASE_API_URL = "/api/v1";
        /** message string literal. */
    public static final String MESSAGE = "message";

    /** exception string literal. */
    public static final String EXCEPTION = "exception";
}
=================================
import static com.data.job.spark.Constants.EXCEPTION;

@Component("user360ToScyllaDbLoader")
public class TestConstants implements Serializable{


    private static final long serialVersionUID = 1L;
}
慈悲佛祖 2024-08-10 07:07:01

我个人认为,出于与上述相同的原因,应该在类中定义常量。特别是因为一些开发人员通过在想要使用它们的类中实现接口来使用这些常量。当该接口包含大量常量时,您不想再查看该特定类的 javadoc,因为它充斥着对该类可能甚至不使用的常量的描述。

I personally feel that the constants should be defined in a class for the same reasons as described here above. Especially because some developers use these constants by implementing the interface in the class that wants to use them. When that interface contains a lot of constants you do not want to look at the javadoc of that specific class anymore because it is littered with descriptions of constants that are probably not even used by that class.

分开我的手 2024-08-10 07:07:01

简短的回答是,这取决于。上下文是什么,即用例是什么?

你首先需要做的是问问题:

  • 有多少个常数?如果有数百个,那么我会喜欢接口或静态缓存机制,即使接口是反模式。

我在一些代码中看到了数百个常量中的一个常量类,它变得很笨拙。有些常量的名称很相似,因此很难保持它们的正确性和维护性。此外,我会更深入地研究为什么你首先会有这么多常量。但是,我还使用此用例开发了一个自定义报告应用程序,并且他们为此使用了静态缓存,因此,它再次指出了您在用例中试图完成的任务。

  • 它们需要通过实现类来共享吗?支持接口,但它又取决于上下文,即常量的数量,并且类都需要共享所有常量吗?
  • 它们彼此有关联吗?他们是同一类型吗?枚举指定分配给类型的常量值列表,但如果仅特定类需要它们,则将它们设置为 private static final 并将它们放入该类中。
  • 您需要枚举或覆盖它们吗?使用枚举。
  • 常量是否将整数表示为字符串代码?使用枚举。

总而言之,我相信这里的正确答案应该基于您尝试使用代码完成的任务。

The short answer is, it depends. What is the context, i.e. the use case?

What you need to do first is ask questions:

  • How many constants will there be? If there are hundreds of them, then I would favor an interface or a static caching mechanism, even though the interface would be an anti-pattern.

I saw a constants class in some code once of hundreds of constants and it got unwieldy. Some of the names of the constants were similar, so it was hard to keep them straight and maintain them. Moreover, I would take a deeper look into why you would have that many constants in the first place. However, I have also worked on a custom reporting app with this use case and they used a static cache for this, so again, it points back to what you are trying to accomplish in your use case.

  • Will they need to be shared by implementing classes? Favor an interface, but again it can depend on the context i.e. the number of the constants and do the classes all need to share all the constants?
  • Are they related to each other? Are they the same type? An enum specifies a list of constant values assigned to a type, but if they are only needed for a specific class, then make them private static final and put them in that class.
  • Will you need to enumerate or use override on them? Use enums.
  • Are the constants representing integers as string codes? Use enums.

To summarize I believe the correct answer here should be based on what you are trying to accomplish with the code.

若水微香 2024-08-10 07:07:01

始终使用接口仅定义合约,使用类定义实现状态(变量和常量)和行为(方法实现)

在接口或类中定义常量

阅读这篇文章,它解释了在类中定义常量与接口中定义常量的优点

Always use Interface to define only contract and Class to define implementation state (variable and constant) and behavior (method implementation)

Define Constants in Interface or Class

Read this article which explains advantages of defining constants in the class vs interface

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文