为什么Java类库仍然使用String常量代替枚举

我正在使用一些Java类,如javax.Mail.SessionMessageDigest用于我正在构建的工具。

我注意到很难为它们分配属性,因为它们正在使用String常量。

例如,对于Session对象,您必须在Property实例中分配String键值对,然后用于创建Session 。 因此,如果您希望会话记录调试消息,请在Property实例中指定"smtp.mail.debug""true" 。 同样,如果您希望MessageDigest使用SHA ,请将MessageDigest实例创建为MessageDigest.getInstance("SHA")

如果我想使用MD5 / RC4等实现MessageDigest ,或者向Session对象添加另一个属性,我还没弄清楚要做什么以及从哪里获取信息。

如果公共枚举被这些各自的类公开以分配属性,那会不会更好?

至少可以为程序员节省大量的搜索时间。

我可以看到两个主要原因:

向后兼容性

在Java 1.5中引入enum之前,您提供的两个示例已经是API的一部分。 还有更多像这样的案例。

可扩展性

看看例如MessageDigest 。 javadoc指定:

需要Java平台的每个实现来支持以下标准MessageDigest算法:

•MD5
•SHA-1
•SHA-256

这使得其他java.security.Provider库为其他算法提供MessageDigest实现,而不是API最低要求的算法。 仅在API级别的限制性enum列出默认值将限制可扩展性。

允许其他javax.mail.Provider实现在邮件会话属性的情况下支持其他/自定义属性也是如此。

这可能是由于Java的主要焦点是向先前版本提供向后兼容性。

enum是在Java 1.5中引入的,因此针对1.4或更早版本编写的任何API都不会为此function提供支持。 这在JDK中的许多API中非常常见

你还需要记住, enum不是可扩展的,这意味着如果你想在消息摘要中引入一个新的算法,那么你就会陷入困境……你无法做到这一点。

邮件API也是如此,邮件API提供了对不同概念的支持,并非所有概念都具有相同的属性系列,并且不可能设计出能够支持不同实现之间的所有各种属性的单个枚举。现在或将来存在, enum只是为了这项工作而不灵活。

简单地认为原因只是向后兼容性。

对于JavaMail,因为它有太多与不同连接器相关的不同设置,您只需要其中一部分与其中一个支持的协议建立连接。 每个连接器都是在单独的类中实现的,我认为没有理由让POP3连接器知道IMAP连接器的设置。

对于MessageDigest ,原因是支持非标准加密算法,该算法未使用JDK打包,而是由第三方JCE适配器提供。 例如,它将如何查找CryptoPro JCE提供的GOST算法:

  MessageDigest digest = MessageDigest.getInstance("GOST3411");