Изучив все отзывы, я пришел к выводу, что независимо от того, что я делаю, решением будет какая-то форма клуджа (со слабым запахом).Я думаю, что это связано с тем фактом, что та часть API коллекций, которая создает неизменяемые экземпляры, не позволяла избежать вложения неизменяемых экземпляров, а также не предоставляла «общедоступный» способ для клиента надлежащим образом избежать вложенности.1002 * И из-за соображений, связанных с несколькими загрузчиками классов и сериализацией через RMI, единственное решение, которое мне действительно понравилось (сравнение эталонных классов от Jorn Horstmann), имеет проблемы.Однако, когда я беру его подход и объединяю его с модификацией подхода имени класса (рекомендованного Евгением Кулешовым), я думаю, что я настолько близок, насколько я собираюсь найти решение, которое поможет мне в моем многопоточномсреда распределенной обработки.И это выглядит примерно так:
public class MyCollections {
private static final String UNMODIFIABLE_MAP_CLASS_NAME =
Collections.unmodifiableMap(new HashMap()).getClass().getName();
public static <K, V> Map<K, V> unmodifiableMap(Map<K, V> map) {
return map.getClass().getName().equals(UNMODIFIABLE_MAP_CLASS_NAME)
? map
: Collections.unmodifiableMap(map);
}
}
Это все еще имеет все преимущества сравнительного сравнения при условии все происходит в одном контексте ClassLoader и строка имени класса была правильно интернирована.И делает это при вежливом сохранении инкапсуляции (избегая моего кода, ссылающегося на имя класса напрямую).Однако, если эти два предположения не выполняются, тогда оценка вернется к стандартному сравнению строк, которое будет работать при условии, что имя класса не меняется между различными версиями библиотеки (что, по-видимому, имеет довольно низкую вероятность).
Есть ли что-то, что я забываю или упускаю в этом подходе?
И еще раз спасибо всем за ваши отзывы.Я действительно ценю это.