如果您查看 Sun 实现的源代码Class.getSimpleName()
,您会注意到每次调用它时似乎都会返回一个新的 String 实例。然而,Class 类中的许多其他功能都被缓存了。
由于简单的名称计算似乎并不容易,并且 JavaDoc 中没有说明它每次都必须返回一个新实例,因此它应该是缓存的一个很好的候选者。我想知道为什么没有缓存有任何设计原因?
我问是因为许多框架一直使用简单的名称,这很容易缓存。
如果您查看 Sun 实现的源代码Class.getSimpleName()
,您会注意到每次调用它时似乎都会返回一个新的 String 实例。然而,Class 类中的许多其他功能都被缓存了。
由于简单的名称计算似乎并不容易,并且 JavaDoc 中没有说明它每次都必须返回一个新实例,因此它应该是缓存的一个很好的候选者。我想知道为什么没有缓存有任何设计原因?
我问是因为许多框架一直使用简单的名称,这很容易缓存。
类名在 OpenJDK 11 及更高版本中被缓存。请参阅 OpenJDK 源代码Class.java
并搜索从该方法private ReflectionData<T> reflectionData()
调用的getSimpleName
方法。
有关详细信息,请参阅票证JDK-8187123。
可能是因为它不是一种昂贵的方法,所以缓存它并没有什么好处。
String.substring
是一种廉价的方法——它重用底层char[]
而不复制它,并且新String
对象在该数组中只是具有不同的偏移量和长度。所以真正唯一的成本是(1)对象分配——这在Java中相当便宜——和(2)lastIndexOf
调用。该调用在技术上是 O(N),但这里的 N 是类的简单名称,在实践中不会很大。
你可以缓存它,但代价是更多的内存。我的猜测是,有人做出了主观但有根据的猜测,即收益不会超过成本。
有趣的问题。由于 String 是一个不可变类,因此返回不同的实例或对同一对象的引用并不重要。我的猜测是(我主要是听听我是对还是错)也许该方法不会经常被调用,并且重新创建 (String) 对象比将其存储在其中更有意义记忆。但同样,这只是一个猜测。