Ответ 1
Об общих static
factory методах параметризованных типов
Похоже, вы хотите написать удобные методы factory для создания родовых коллекций.
Вы можете написать такие общие методы, как эти:
public static <T> List<T> newArrayList() {
return new ArrayList<T>();
}
public static <K,V> Map<K,V> newHashMap() {
return new HashMap<K,V>();
}
Тогда вы можете просто написать:
// absolutely type-safe!!! no compilation warnings at all!!!
List<String> names = newArrayList();
List<Integer> nums = newArrayList();
Map<String, List<String>> map = newHashMap();
Обратите внимание, что в некоторых контекстах вышеприведенные методы не должны быть static
, и вы можете отказаться от имен реализации class
из методов и использовать только имена interface
(например, newList
, newMap
).
Подтверждение от Effective Java 2nd Edition
Этот тип универсального метода type-inferring static
factory фактически одобрен Effective Java 2nd Edition; у него была уникальная привилегия быть первым пунктом, обсуждавшимся в книге.
Вот соответствующие цитаты из пункта 1: Рассмотрим методы static
factory вместо конструкторов:
Четвертое преимущество методов
static
factory заключается в том, что они уменьшают многословность создания экземпляров с параметризованным типом.При вызове конструктора параметризованного класса, к сожалению, вы должны указать параметры типа, даже если они очевидны из контекста. Это обычно требует, чтобы вы предоставляли параметры типа дважды в быстрой последовательности:
Map<String,List<String>> m = new HashMap<String,List<String>>();
Эта избыточная спецификация быстро становится болезненной по мере увеличения длины и сложности параметров типа. Однако с фабриками
static
компилятор может определить параметры типа для вас. Это называется выводом типа. Например, предположим, чтоHashMap
предоставил этотstatic
factory:public static <K,V> HashMap<K,V> newInstance() { return new HashMap<K,V>(); }
Затем вы могли бы заменить словосочетание выше на эту краткую альтернативу:
Map<String,List<String>> m = HashMap.newInstance();
К сожалению, стандартные версии коллекций, такие как
HashMap
, не имеют методовstatic
factory начиная с версии 1.6, но вы можете поместить эти методы в свой собственный класс утилиты. Более того, вы можете предоставить такие фабрикиstatic
в своих параметризованных классах.
Элемент также предписывает общее соглашение об именах для этих методов static
factory:
getInstance
- возвращает экземпляр, который описывается параметрами [...]newInstance
- КакgetInstance
, за исключением того, что он гарантирует, что каждый возвращаемый экземпляр отличается от всех остальных.new
Type
- КакnewInstance
, но используется, когда метод factory находится в другом классе.Type
указывает тип объекта, возвращаемого методом factory.
В параметрах явного типа
В большинстве случаев вам не нужно явно указывать параметры типа, так как система вывода типов типов generic Java обычно может определить, что вам нужно.
Тем не менее, чтобы предоставить явные параметры типа, синтаксис заключается в том, чтобы поместить его перед именем метода (не после). Здесь приведен пример вызова с явным параметром общего метода <T> List<T> emptyList()
из java.util.Collections
:
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
Обратите внимание, что синтаксический притвор для явной тип параметризации для вызова общего метода заключается в том, что вы должны квалифицировать тип (if static
) или объект, к которому вы вызываете метод, даже если их можно опустить, если он не была явной параметризацией.
Ссылки
Приложение: коллекция factory методов из Guava
Следует отметить, что Guava фактически уже предоставляет методы static
factory для типов в Структура коллекций Java:
Из основного package com.google.common.collect
:
-
Lists.newArrayList()
,newLinkedList()
,... -
Sets.newHashSet()
,newTreeSet()
,newEnumSet(…)
,... -
Maps.newHashMap()
,newTreeMap()
,newEnumMap(…)
,...
Фактически, в духе рекомендации Эффективного Java 2nd Edition, собственные коллекции Guava не предоставляют конструкторы public
, а вместо этого предоставляют методы static create()
factory:
-
HashMultiSet.create()
,Multiset
реализация -
TreeMultimap.create()
,Multimap
Остальная часть библиотеки также предоставляет много полезных функций.