public class GenericTypeSafe {
@Test
public void
testTypeSafeCache() {
System.out.println("===testTypeSafeCache===");
final TypeSafeCache cache = new TypeSafeCache();
cache.put(Integer.class, 1);
cache.put(Long.class, 1L);
cache.put(Double.class, 1.0);
System.out.println(cache.get(Integer.class));
System.out.println(cache.get(Long.class));
System.out.println(cache.get(Double.class));
}
@Test
public void
testTypeSafeAnnotationType() throws NoSuchMethodException,
SecurityException {
System.out.println("===testTypeSafeAnnotationType===");
final A<String,
Integer> a = new A<>("A", 1);
Method method = a.getClass().getMethod("getU");
System.out.println("method:" + method);
Annotation a1 = method.getAnnotation(A1.class);
System.out.println("annotationType:" + a1.annotationType());
System.out.println("annotationType().getCanonicalName():" + a1.annotationType().getCanonicalName());
System.out.println(
"annotationType().getClass().getCanonicalName():" + a1.annotationType().getClass().getCanonicalName());
System.out.println(".annotationType().getTypeName():" + a1.annotationType().getTypeName());
System.out.println(".annotationType().getGenericSuperclass():" + a1.annotationType().getGenericSuperclass());
Annotation result = getAnnotation(method, a1.annotationType().getTypeName());
System.out.println("result:" + result);
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface A1 {
}
public static class TypeSafeCache {
private
Map<Class<?>, Object> cache = new HashMap<>();
public <T> void put(Class<T>
type, T instance) {
if (type != null) {
cache.put(type, type.cast(instance));
} else {
throw new RuntimeException("type is
null.");
}
}
public <T> T
get(Class<T> type) {
return type.cast(cache.get(type));
}
}
public static Annotation
getAnnotation(final AnnotatedElement element, final String annotationTypeName) {
Class<?> annotationType = null;
try {
annotationType = Class.forName(annotationTypeName);
} catch (Exception ex) {
throw new
IllegalArgumentException(ex);
}
System.out.println("annotationType:" + annotationType);
return element.getAnnotation(annotationType.asSubclass(Annotation.class));
}
}
|
If a class has a type parameter but the instance of the type should be automatically initiated instead of being passed in, here are examples:
public class GenericInitiation {
public static class Foo<T> {
private Class<T> clazz;
public Foo(Class<T>
clazz) {
this.clazz = clazz;
}
public T getInstanceOfT()
throws
InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
public T
getInstanceOfTInSubClass() {
final ParameterizedType superClass =
(ParameterizedType) getClass().getGenericSuperclass();
@SuppressWarnings("unchecked")
Class<T> type = (Class<T>)
superClass.getActualTypeArguments()[0];
try {
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static class Bar extends Foo<String>
{
public
Bar(Class<String> clazz) {
super(clazz);
}
}
@Test
public void testInitiation() throws
InstantiationException, IllegalAccessException {
System.out.println("===testSubClassInitiation===");
Foo<Random> foo = new
Foo<>(Random.class);
System.out.println(foo.getInstanceOfT().getClass());
Bar bar = new Bar(String.class);
System.out.println(bar.getInstanceOfTInSubClass().getClass());
}
}
|
No comments:
Post a Comment