我见过这样的例子:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
假设我可以有一个Constants类来包装常量,并将它们声明为静态final。我几乎不知道Java,我想知道这是否是创建常量的最佳方式。
我见过这样的例子:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
假设我可以有一个Constants类来包装常量,并将它们声明为静态final。我几乎不知道Java,我想知道这是否是创建常量的最佳方式。
当前回答
有一定的观点来回答这个问题。首先,java中的常量通常被声明为public、static和final。原因如下:
public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change
我永远不会为CONSTANTS访问器/对象使用接口,因为接口通常是需要实现的。这看起来是不是很有趣:
String myConstant = IMyInterface.CONSTANTX;
相反,我会在一些不同的方法中进行选择,基于一些小的权衡,所以这取决于你需要什么:
1. Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor
2. Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'
3. Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe
4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe
其他回答
那么枚举呢?
有什么不同
1.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
2.
public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
和使用 MyGlobalConstants。TIMEOUT_IN_SECS,我们需要这个常量。我认为两者是一样的。
这是一个坏习惯,非常可怕 引用约书亚·布洛赫的话,却不理解基本的原教旨主义。
我也没读过约书亚·布洛赫的书
他是个糟糕的程序员 或者迄今为止我发现引用他的人(约书亚是一个男孩的名字,我猜)只是把他的材料作为宗教脚本来证明他们的软件是宗教放纵的。
在圣经原教旨主义中,所有的圣经律法都可以总结为
全心全意地爱根本身份 爱邻居如爱自己
所以类似的软件工程原教旨主义可以总结为
全身心地投入到编程的基础知识中 像对待自己一样,为你的程序员同事的优秀而努力。
此外,在圣经原教旨主义的圈子中,一个强有力的合理的推论被得出
首先爱自己。因为如果你不爱自己,那么“像爱自己一样爱邻居”的概念就没有多大分量,因为“你有多爱自己”是你爱别人的基准线。
类似地,如果你不尊重自己作为一个程序员,只是接受一些编程大师的声明和预言,而不质疑基本原理,你对Joshua Bloch的引用和依赖是毫无意义的。因此,你实际上不尊重你的程序员同事。
软件编程的基本法则
懒惰是优秀程序员的美德 你要让你的编程生活尽可能简单,尽可能懒惰,因此尽可能有效 你要让你的编程结果和内脏尽可能简单,尽可能懒惰,因此对你的邻居程序员来说是尽可能有效的,他们和你一起工作,捡起你的编程内脏。
接口模式常量是个坏习惯??
在基本有效和负责任的编程法律下,这一宗教法令属于什么?
只要看看维基百科上关于接口模式常数的文章(https://en.wikipedia.org/wiki/Constant_interface),以及它针对接口模式常数的愚蠢借口。
Whatif-No IDE? Who on earth as a software programmer would not use an IDE? Most of us are programmers who prefer not to have to prove having macho aescetic survivalisticism thro avoiding the use of an IDE. Also - wait a second proponents of micro-functional programming as a means of not needing an IDE. Wait till you read my explanation on data-model normalization. Pollutes the namespace with variables not used within the current scope? It could be proponents of this opinion are not aware of, and the need for, data-model normalization Using interfaces for enforcing constants is an abuse of interfaces. Proponents of such have a bad habit of not seeing that "constants" must be treated as contract. And interfaces are used for enforcing or projecting compliance to a contract. It is difficult if not impossible to convert interfaces into implemented classes in the future. Hah .... hmmm ... ??? Why would you want to engage in such pattern of programming as your persistent livelihood? IOW, why devote yourself to such an AMBIVALENT and bad programming habit ?
无论借口是什么,当涉及到从根本上有效的软件工程时,都没有合理的借口来反对或通常不鼓励接口常量的使用。
制定美国宪法的国父们的初衷和精神状态如何并不重要。我们可以讨论开国元勋们的初衷,但我关心的是美国宪法的书面声明。每一个美国公民都有责任利用美国宪法中书面的文学原教旨主义,而不是不成文的立国意图。
Similarly, I do not care what the "original" intents of the founders of the Java platform and programming language had for the interface. What I care are the effective features the Java specification provides, and I intend to exploit those features to the fullest to help me fulfill the fundamental laws of responsible software programming. I don't care if I am perceived to "violate the intention for interfaces". I don't care what Gosling or someone Bloch says about the "proper way to use Java", unless what they say does not violate my need to EFFECTIVE fulfilling fundamentals.
基础是数据模型规范化
数据模型是如何托管或传输的并不重要。如果您不理解数据模型规范化的需求和过程,那么无论您使用接口、枚举还是其他什么,关系sql还是非sql。
我们必须首先定义并规范化一组流程的数据模型。当我们有一个一致的数据模型时,只有这样我们才能使用其组件的流程流来定义应用程序的领域或领域的功能行为和流程块。只有这样,我们才能定义每个功能流程的API。
甚至EF Codd提出的数据规范化方面现在也受到了严重的挑战。例如,他关于1NF的声明被批评为模棱两可、错位和过于简化,他的其他声明也是如此,特别是在现代数据服务、回购技术和传输的出现方面。在我看来,应该完全抛弃EF Codd语句,并设计一套新的数学上更合理的语句。
EF Codd的一个突出缺陷及其与有效的人类理解不一致的原因是,他相信人类可感知的多维、可变维度数据可以通过一组零碎的2维映射有效地感知。
数据规范化的基础
EF Codd未能表达的。
在每个连贯的数据模型中,这些是要实现的数据模型连贯的顺序递增顺序。
The Unity and Identity of data instances. design the granularity of each data component, whereby their granularity is at a level where each instance of a component can be uniquely identified and retrieved. absence of instance aliasing. i.e., no means exist whereby an identification produces more than one instance of a component. Absence of instance crosstalk. There does not exist the necessity to use one or more other instances of a component to contribute to identifying an instance of a component. The unity and identity of data components/dimensions. Presence of component de-aliasing. There must exist one definition whereby a component/dimension can be uniquely identified. Which is the primary definition of a component; where the primary definition will not result in exposing sub-dimensions or member-components that are not part of an intended component; Unique means of component dealiasing. There must exist one, and only one, such component de-aliasing definition for a component. There exists one, and only one, definition interface or contract to identify a parent component in a hierarchical relationship of components. Absence of component crosstalk. There does not exist the necessity to use a member of another component to contribute to the definitive identification of a component. In such a parent-child relationship, the identifying definition of a parent must not depend on part of the set of member components of a child. A member component of a parent's identity must be the complete child identity without resorting to referencing any or all of the children of a child. Preempt bi-modal or multi-modal appearances of a data-model. When there exists two candidate definitions of a component, it is an obvious sign that there exists two different data-models being mixed up as one. That means there is incoherence at the data-model level, or the field level. A field of applications must use one and only one data-model, coherently. Detect and identify component mutation. Unless you have performed statistical component analysis of huge data, you probably do not see, or see the need to treat, component mutation. A data-model may have its some of its components mutate cyclically or gradually. The mode may be member-rotation or transposition-rotation. Member-rotation mutation could be distinct swapping of child components between components. Or where completely new components would have to be defined. Transpositional mutation would manifest as a dimensional-member mutating into an attribute, vice versa. Each mutation cycle must be identified as a distinct data-modal. Versionize each mutation. Such that you can pull out a previous version of the data model, when perhaps the need arise to treat an 8 year old mutation of the data model.
在相互服务的组件应用程序的字段或网格中,必须有且只有一个一致的数据模型,或者存在数据模型/版本标识自身的方法。
我们还在问是否可以使用接口常量吗?真的吗?
有一些数据规范化问题比这个平凡的问题更重要。如果您不解决这些问题,那么您认为接口常量所引起的混乱相对来说是微不足道的。无价值之物。
根据数据模型归一化,然后将组件确定为变量、属性和契约接口常数。
然后确定哪些是值注入、属性配置占位符、接口、最终字符串等等。
如果您不得不以需要定位组件为借口,以便根据接口常量进行指示,这意味着您没有实践数据模型规范化的坏习惯。
也许你希望将数据模型编译成一个风险投资版本。您可以提取数据模型的明确可识别版本。
在接口中定义的值完全保证是不可变的。和共享。当你所需要的只是一组常量时,为什么要从另一个类加载一组最终字符串到你的类中呢?
那么为什么不发布一个数据模型契约呢?我的意思是,如果你能连贯地管理和规范它,为什么不呢?...
public interface CustomerService {
public interface Label{
char AssignmentCharacter = ':';
public interface Address{
String Street = "Street";
String Unit= "Unit/Suite";
String Municipal = "City";
String County = "County";
String Provincial = "State";
String PostalCode = "Zip"
}
public interface Person {
public interface NameParts{
String Given = "First/Given name"
String Auxiliary = "Middle initial"
String Family = "Last name"
}
}
}
}
现在我可以引用我的应用程序的合同标签的方式,如
CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
这会混淆jar文件的内容?作为一个Java程序员,我不关心jar的结构。
这给osgi驱动的运行时交换带来了复杂性?Osgi是一种非常有效的方法,可以让程序员继续他们的坏习惯。有比osgi更好的替代方案。
或者为什么不是这个?没有私人常数泄漏到公开的合同。所有私有常量都应该分组到一个名为“constants”的私有接口中,因为我不想不得不搜索常量,而且我懒得重复键入“私有最终字符串”。
public class PurchaseRequest {
private interface Constants{
String INTERESTINGName = "Interesting Name";
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
甚至可能是这样:
public interface PurchaseOrderConstants {
public interface Properties{
default String InterestingName(){
return something();
}
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
接口常量唯一值得考虑的问题是何时实现接口。
这不是接口的“初衷”吗?就像我关心国父们制定美国宪法的“初衷”,而不是最高法院如何解释美国宪法的书面条文??
毕竟,我生活在自由的土地上,荒野和勇敢者的家园。勇敢、自由、狂野——使用界面。如果我的程序员同事拒绝使用高效和懒惰的编程方式,我是否有义务按照黄金法则降低我的编程效率以与他们保持一致?也许我应该,但那不是理想的情况。
I use static final to declare constants and go with the ALL_CAPS naming notation. I have seen quite a few real life instances where all constants are bunched together into an interface. A few posts have rightly called that a bad practice, primarily because that's not what an interface is for. An interface should enforce a contract and should not be a place to put unrelated constants in. Putting it together into a class that cannot be instantiated (through a private constructor) too is fine if the constant semantics don't belong to a specific class(es). I always put a constant in the class that it's most related to, because that makes sense and is also easily maintainable.
枚举是表示一组值的好选择,但是如果您要存储强调绝对值的独立常量(例如。TIMEOUT = 100 ms)你可以直接使用静态的final方法。
我强烈建议不要只使用一个常量类。这在当时看起来是一个好主意,但是当开发人员拒绝记录常量,并且类增长到包含500个以上彼此完全不相关的常量(与应用程序的完全不同方面相关)时,通常会导致常量文件完全不可读。而不是:
If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+. If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant) If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.