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

Java 为什么不使用字符串的静态数组?,java,standards,Java,Standards,遇到这样的情况: 不要使用字符串的静态数组 此建议的原因是什么?数组是可变容器。没有内置同步的全局可变容器是等待发生的多线程恐惧。您可以将对该数组的引用存储在某些本地上下文中,然后在您不知道的情况下随时更改其内容。反之亦然,您可以假设这是一个方便的全局状态,但是每个客户机都必须知道将其访问同步到该状态的确切正确方法。有人会忘记,bug就会诞生。这种方式破坏了面向对象的范例。此外,这是一个安全漏洞,因为final关键字只保证参考值,并且使内容易于更改。其中一些是任意的。例如,拥有一条返回语句是一个

遇到这样的情况:

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


此建议的原因是什么?

数组是可变容器。没有内置同步的全局可变容器是等待发生的多线程恐惧。您可以将对该数组的引用存储在某些本地上下文中,然后在您不知道的情况下随时更改其内容。反之亦然,您可以假设这是一个方便的全局状态,但是每个客户机都必须知道将其访问同步到该状态的确切正确方法。有人会忘记,bug就会诞生。

这种方式破坏了面向对象的范例。此外,这是一个安全漏洞,因为
final
关键字只保证参考值,并且使内容易于更改。

其中一些是任意的。例如,拥有一条返回语句是一个风格问题(可能与过去无法处理多条返回路径的某些分析工具有关?)

有些已经过时了。就像关于StringBuilding的那个

我假设这些是旧的性能建议和样式指南的混合体。我认为字符串静态数组一属于后一类,也许有一点暗示了其他人所说的与引入枚举的可能联系(也许这就是为什么字符串特别重要)

当您尝试将它们应用于现代框架时,其中一些实际上是完全不可行的:“不要使用开关根据对象类型进行调用”。例如,它是Akka Java(onReceive)方法的核心,通常在Java中的任何类型的模式匹配中都是如此


虽然我承认这很奇怪,但我想说这可能与他们过去使用的某些特定工具或提及的枚举可能性有关。但这只是我的观点,不是一个明确的答案。

我相信这是由于开发人员使用
字符串作为枚举的替代(很可能是无意的),而
静态字符串[]
是对这些类型进行分组的一种方式


它可能是针对在撰写本文时常见的设计缺陷 据我们所知,本文的目标可能是Java4代码库

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

为什么甲骨文会执行这样一个神秘的原则? 我不认为这与全球国家有关,因为我确信单身会被提及(作为全球国家的顶峰)

我怀疑并发性是个问题,因为本文没有提到关于跨线程共享数据,甚至使用多线程的任何其他内容。你可以假设他们提到了一些关于线程环境的东西

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;
    //...
}
使用数组可以轻松循环(就像使用
Enum.values()
一样)

不赞成使用
String
作为枚举:

  • 这不是类型安全的。如果
    MAGE
    可以传递给一个方法,那么任何
    String
    都可以传递到它的位置。这导致我们

  • 错误更容易犯。打字错误可能会被忽略,这对于一般开发人员来说可能很小,但对于拥有大量代码库和许多用户(如Oracle)的企业来说可能是灾难性的。例如:隐藏的输入错误会导致比较返回false。这会阻止服务启动。缺少此服务会导致错误。如果在用户注意到错误之前未找到,则可能导致漏洞攻击

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

    abstract class CardType {
    
    }
    
    class Hearts extends CardType {
    
    }
    
    ....
    

    枚举卡片类型{ 心,钻石。。。; }

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


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


    是的,上面的示例没有使用正确的常量(缺少
    最终值
    )。但是,尽管常数应该是首选的,但它们不需要从这种设计中受益(能够使用
    字符串
    获取类型信息),也不需要这种设计。由于人们可能并不总是使用常量,因此他们可能出于此目的而忽略了
    final
    或“常量数组”。

    其中一些技巧主要用于可读性目的。我想可能您会使用带有字符串值的枚举或类似于这些行的枚举?原因可能仅在本文所指的Oracle零售应用程序的上下文中有效,但可能是为了对抗错误样式,如过度使用静态变量(字符串可能是最常见的情况).现在,这份文件中的许多建议都很可疑。最明显的是“不要连接字符串,而是使用StringBuilder”。@Cricket我认为原因可能是这早于1.5(我相信是在添加枚举时)。@VinceEmigh这可能是预期的上下文。但我发现这个