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

Raj*_*sad 5 java string session enums constants

我正在使用一些Java类,javax.Mail.Session以及MessageDigest我正在构建的工具.

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

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

我还没弄清楚要做什么以及在哪里获取信息,如果说我想MessageDigest使用MD5/ RC4etc 实现,或者在我的Session对象中添加另一个属性.

如果公共枚举被这些各自的类暴露给分配属性,那不是真的更好吗?

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

Rob*_*sen 7

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

向后兼容性

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

可扩展性

举个例子来看看MessageDigest.该javadoc的规定:

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

•MD5
•SHA-1
•SHA-256

这使得其他java.security.Provider库可以提供MessageDigest除API最低要求之外的其他算法的实现.仅在enumAPI级别的限制中列出默认值将限制可扩展性.

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

  • 这些原因都不令人满意*.同样的方式`String.getBytes("UTF-8")`可以接受`String.getBytes(StandardCharsets.UTF_8)`,你不需要处理可能的`UnsupportedEncodingException`,类似的映射可以(应该!)提供了`MessageDigest.getInstance("MD5")`.必须对编译时已知的事情进行运行时检查总是错误的.好的图书馆会帮助你避免这种情况. (3认同)
  • 同意.我应该清楚你提供的理由满足了这个问题.我的批评是针对api.我想指出,没有理由不使用常量来避免api所需的实现的运行时字符串查找.我们可以拥有*和*向后兼容性*和*可扩展性. (3认同)
  • @swalog 是否可以或应该提供具有相应方法的附加映射?当然,但由于上述原因,这不会使对基于字符串的方法的需求无效。 (2认同)
  • @swalog `StandardCharsets.UTF_8` 包含实际的 `Charset` 实现,因此它不会找不到它,而 `MessageDigest.getInstance(HypotheticalEnumType)` 仍然必须经过与基于字符串的方法相同的代码路径找到一个提供者,唯一的区别是不允许在失败时抛出已检查的异常。 (2认同)