public final class ClassGenericsUtil extends Object
Due to the way generics are implemented - via erasure - type safety cannot be guaranteed properly at compile time here. These classes collect such cases using helper functions, so that we have to suppress these warnings only in one place.
Note that many of these situations are still type safe, i.e. an empty
array of List> can indeed be cast into a List
>.
The only one potentially unsafe is instantiateGenerics(java.lang.Class<?>, java.lang.String)
, since we
can't verify that the runtime type 'type' adhers to the compile time
restriction T. When T is not generic, such a check is possible, and then the
developer should use instantiate(java.lang.Class<T>, java.lang.String)
instead.
Modifier and Type | Field and Description |
---|---|
static String |
FACTORY_METHOD_NAME
Name for a static "parameterize" factory method.
|
private static Logging |
logger
Static logger to use.
|
Constructor and Description |
---|
ClassGenericsUtil() |
Modifier and Type | Method and Description |
---|---|
static <B,T extends B> |
castWithGenericsOrNull(Class<B> base,
Object obj)
Cast an object at a base class, but return a subclass (for Generics!).
|
static <T,C extends Collection<T>> |
cloneCollection(C coll)
Clone a collection.
|
static <T> T[] |
collectionToArray(Collection<T> c,
T[] a)
Transform a collection to an Array
|
static <T> Class<? extends T> |
getComponentType(T[] a)
Retrieve the component type of a given array.
|
static <C> Method |
getParameterizationFactoryMethod(Class<C> c,
Class<?> ret)
Inspect the class for a static "parameterize" method that satisfies certain
constraints.
|
static Parameterizer |
getParameterizer(Class<?> c)
Get a parameterizer for the given class.
|
static <T> T |
instantiate(Class<T> type,
String className)
Returns a new instance of the given type for the specified className.
|
static <T> T |
instantiateGenerics(Class<?> type,
String className)
Returns a new instance of the given type for the specified className.
|
static <T> T[] |
newArray(Class<? extends T> k,
int size)
Make a new array of the given class and size.
|
static <T> T[] |
newArray(T[] a,
int size)
Clone an array of the given type.
|
static <T> ArrayList<T>[] |
newArrayOfEmptyArrayList(int len)
Create an array of
len empty ArrayLists. |
static <T> HashSet<T>[] |
newArrayOfEmptyHashSet(int len)
Create an array of
len empty HashSets. |
static <T> T[] |
newArrayOfNull(int len,
Class<T> base)
Create an array (of null values)
This is a common unchecked cast we have to do due to Java Generics
limitations.
|
static <T> T |
newInstance(T obj)
Generic newInstance that tries to clone an object.
|
static <C> C |
parameterizeOrAbort(Class<?> c,
Parameterization config)
Force parameterization method.
|
static <B,T extends B> |
toArray(Collection<T> coll,
Class<B> base)
Convert a collection to an array.
|
static <C> C |
tryInstantiate(Class<C> r,
Class<?> c,
Parameterization config)
Instantiate a parameterizable class.
|
static <D,T extends D> |
uglyCastIntoSubclass(Class<D> cls)
Cast the (erased) generics onto a class.
|
static <BASE,FROM extends BASE,TO extends BASE> |
uglyCrossCast(Class<FROM> cls,
Class<BASE> base)
This class performs an ugly cast, from
Class<F> to
Class<T> , where both F and T need to extend B. |
private static final Logging logger
public static final String FACTORY_METHOD_NAME
public static <T> T instantiate(Class<T> type, String className) throws UnableToComplyException
Returns a new instance of the given type for the specified className.
If the Class for className is not found, the instantiation is tried using the package of the given type as package of the given className.
T
- Class type for compile time type checkingtype
- desired Class type of the Object to retrieveclassName
- name of the class to instantiateUnableToComplyException
- if the instantiation cannot be performed
successfullypublic static <T> T instantiateGenerics(Class<?> type, String className) throws UnableToComplyException
Returns a new instance of the given type for the specified className.
If the Class for className is not found, the instantiation is tried using the package of the given type as package of the given className.
This is a weaker type checked version of "instantiate(java.lang.Class<T>, java.lang.String)
" for use
with Generics.
T
- Class type for compile time type checkingtype
- desired Class type of the Object to retrieveclassName
- name of the class to instantiateUnableToComplyException
- if the instantiation cannot be performed
successfullypublic static <C> Method getParameterizationFactoryMethod(Class<C> c, Class<?> ret) throws NoSuchMethodException, Exception
C
- Return class typec
- Class to inspect.ret
- Expected return typefactory(null, Parameterization)
.NoSuchMethodException
- When no factory method was found, or it
doesn't fit the constraints.Exception
- On other errors such as security exceptionspublic static Parameterizer getParameterizer(Class<?> c)
c
- Classpublic static <C> C tryInstantiate(Class<C> r, Class<?> c, Parameterization config) throws InvocationTargetException, NoSuchMethodException, Exception
Parameterization.descend(java.lang.Object)
!C
- base typer
- Base (restriction) classc
- Class to instantiateconfig
- Configuration to use for instantiation.InvocationTargetException
- when an exception occurred within the
constructorNoSuchMethodException
- when no suitable constructor was foundException
- when other instantiation errors occurredpublic static <C> C parameterizeOrAbort(Class<?> c, Parameterization config)
C
- Typec
- Class to instantiateconfig
- Parameterspublic static <T> T[] newArrayOfNull(int len, Class<T> base)
T
- Type the array elements havelen
- array sizebase
- template class for array creation.public static <B,T extends B> T[] toArray(Collection<T> coll, Class<B> base)
B
- Base typeT
- Type the array elements havecoll
- collection to convert.base
- Template class for array creation.public static <T> ArrayList<T>[] newArrayOfEmptyArrayList(int len)
len
empty ArrayLists.
This is a common unchecked cast we have to do due to Java Generics
limitations.T
- Type the list elements havelen
- array sizepublic static <T> HashSet<T>[] newArrayOfEmptyHashSet(int len)
len
empty HashSets.
This is a common unchecked cast we have to do due to Java Generics
limitations.T
- Type the set elements havelen
- array sizepublic static <D,T extends D> Class<T> uglyCastIntoSubclass(Class<D> cls)
Class<Set<String>> setclass = uglyCastIntoSubclass(Set.class);
We can't type check at runtime, since we don't have T.D
- Base typeT
- Supertypecls
- Class typecls
parameter, but cast to Class<T>
public static <BASE,FROM extends BASE,TO extends BASE> Class<TO> uglyCrossCast(Class<FROM> cls, Class<BASE> base)
Class<F>
to
Class<T>
, where both F and T need to extend B.
The restrictions are there to avoid misuse of this cast helper.
While this sounds really ugly, the common use case will be something like
BASE = Class<Database> FROM = Class<Database> TO = Class<Database<V>>i.e. the main goal is to add missing Generics to the compile time type.
BASE
- Base typeTO
- Destination typeFROM
- Source typecls
- Class to be castbase
- Base class for type checking.public static <B,T extends B> T castWithGenericsOrNull(Class<B> base, Object obj)
List
" to "List<Something>
" without having
to add SuppressWarnings everywhere.B
- Base type to cast atT
- Derived type returnedbase
- Base class to cast atobj
- Objectpublic static <T> T newInstance(T obj) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
T
- Object type, genericobj
- Master copy - must not be null.InstantiationException
- on errorIllegalAccessException
- on errorInvocationTargetException
- on errorNoSuchMethodException
- on errorpublic static <T> Class<? extends T> getComponentType(T[] a)
T
- Array type, generica
- Existing arraypublic static <T> T[] newArray(Class<? extends T> k, int size)
T
- Generic typek
- Classsize
- Sizepublic static <T> T[] newArray(T[] a, int size)
T
- Generic typea
- existing arraysize
- array sizepublic static <T,C extends Collection<T>> C cloneCollection(C coll)
T
- Data typeC
- Collection typecoll
- Existing collectionpublic static <T> T[] collectionToArray(Collection<T> c, T[] a)
T
- object typec
- Collectiona
- Array to write to or replace (i.e. sample array)