Почему Class.getSimpleName() не кэшируется?
Если вы посмотрите на исходный код реализации Sun Class.getSimpleName()
, вы заметите, что, похоже, он возвращает новый экземпляр String каждый раз, когда вы назови это. Однако многие другие функции класса Class кэшируются.
Поскольку простое вычисление имен не кажется легким, и в JavaDoc нет ничего, чтобы сказать, что он должен каждый раз возвращать новый экземпляр, он должен быть хорошим кандидатом для кэширования. Мне интересно, может ли быть какая-то причина дизайна, почему это не кэшировано?
Я спрашиваю, потому что многие фреймворки используют простые имена все время, и это так легко кэшировать.
Ответы
Ответ 1
Обновление: имя кэшировано в OpenJDK 11
Имя класса кэшируется в OpenJDK 11 и более поздних версиях. См. исходный код OpenJDK для Class.java
и найдите метод private ReflectionData<T> reflectionData()
, вызванный из метода getSimpleName
.
Подробности см. в билете JDK-8187123.
Ответ 2
Наверное, потому что это не дорогостоящий метод, поэтому его кэширования не так много.
String.substring
- дешевый метод - он повторно использует базовый char[]
, не копируя его, а новый объект String
имеет только смещение и длину в этом массиве. Так что действительно единственные затраты: (1) выделение объекта - что довольно дешево в Java - и (2) вызов lastIndexOf
. Этот вызов технически O (N), но N здесь - это простое имя класса, которое на практике не будет очень большим.
Вы можете кэшировать его, но за счет большей памяти. Я предполагаю, что кто-то сделал субъективное, но образованное предположение, что выгоды не перевешивают затраты.
Ответ 3
Интересный вопрос. Поскольку String является неизменным классом, на самом деле не имеет значения, возвращаете ли вы отдельные экземпляры или ссылку на один и тот же объект.
Мое предположение было бы (и я даю ему в основном услышать, правильно или неправильно), что, возможно, метод не вызывается очень часто, и имеет смысл повторно создать объект (String), чем хранить его в Память. Но опять же, это всего лишь предположение.