为什么不使用字符串的静态数组?

Zac*_*ack 17 java standards

来自Oracle的这个编码标准:

不要使用静态字符串数组.

这个建议的原因是什么?

Vin*_*igh 2

我相信这是由于开发人员使用String枚举作为替代(很可能是无意的),并且这static String[]是对这些类型进行分组的一种方法。


它可能针对撰写文章时常见的设计缺陷

据我们所知,本文可能针对 Java 4 代码库。

并不是说这是在 Java 4 期间编写的,而是说当时存在的大多数生产代码可能是用 Java 4 编写的。缺乏自动装箱陷阱(这很常见)并且没有提及泛型(原始类型)使我相信这一点。

为什么甲骨文要强制执行这样一个神秘的原则?

我不认为这与全局状态有关,因为我确信会提到单例(作为全局状态的顶峰)。

我怀疑并发性是问题所在,因为本文没有提到有关跨线程共享数据甚至使用多个线程的任何其他内容。您可能会认为他们会提到一些有关线程环境的内容。

滥用String类型枚举的目的在当时很常见,所以我确信这个声明(如果与我认为的相关)在当时更容易理解。我觉得这个说法在当时同样神秘,但没有人愿意质疑它,导致在深入研究时缺乏谷歌结果,这是相当牵强的。

我的答案

迄今为止,开发人员仍然滥用String类型信息。由于缺乏枚举,我可以看到开发人员可能会想做以下事情:

class Card {
    static String HEARTS = "HEARTS";
    static String DIAMONDS = "DIAMONDS";
    static String CLUBS = "CLUBS";
    static String SPADES = "SPADES";

    static String[] CARD_TYPE = {
        HEARTS, DIAMONDS, CLUBS, SPADES
    };

    private String type;
    //...
}
Run Code Online (Sandbox Code Playgroud)

使用数组进行轻松循环(就像使用 一样Enum.values())。

使用Stringas 枚举是不受欢迎的:

  1. 它不是类型安全的。如果MAGE可以传递给方法,则String可以将 ANY 传递到它的位置。这导致我们...

  2. 更容易犯错误。拼写错误可能会被忽视,这对于普通开发人员来说似乎很小,但对于拥有大量代码库和许多消费者的企业(例如 Oracle)来说可能是灾难性的。例如:隐藏的拼写错误会导致比较返回 false。这会阻止服务启动。缺少此服务会导致错误。如果在用户注意到该错误之前未发现该错误,则可能会导致漏洞利用。

这可以通过使用 Java 的内置类型系统来解决:

abstract class CardType {

}

class Hearts extends CardType {

}

....
Run Code Online (Sandbox Code Playgroud)

或者

枚举 CardType { 红心,钻石,...; }

这不仅不易出错,而且允许您使用多态性,从而无需检查值即可触发特定行为。该行为可以包含在类型本身中。


尽管我不能保证这是正确的答案,但这似乎是唯一不依赖于声明中未提及的修饰符的使用的答案。

是的,上面的示例没有使用正确的常量(缺少final)。但是,尽管常量应该是首选,但它们并不需要从这种设计中受益(能够用于String类型信息),设计也不要求它起作用。由于人们可能并不总是为此使用常量,因此他们可以为此目的省略final常量数组”。