反射允许你在运行时分析任意的对象。如果对象是泛型类的实例,关于泛型类型参数则得不到太多信息,因为它们会被擦除。利用反射可以获得泛型类的信息。
package test;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Scanner;
/**
* Created by yangrb on 17-10-23.
*/
public class GenericReflectionTest {
public static void main(String[] args){
String name;
if (args.length>0) name=args[0];
else {
try (Scanner in = new Scanner(System.in)){
System.out.println("Enter class name (e.g. java.util.Collections):");
name = in.next();
}
}
try {
Class<?> cl = Class.forName(name);
printClass(cl);
for (Method m:cl.getDeclaredMethods()) {
printMethod(m);
}
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}
public static void printClass(Class<?> cl){
System.out.println(cl);
printTypes(cl.getTypeParameters(),"<",", ",">",true);
Type sc = cl.getGenericSuperclass();
if (sc!=null){
System.out.print("extends ");
printType(sc,false);
}
printTypes(cl.getGenericInterfaces()," implements ",", ","",false);
System.out.println();
}
public static void printMethod(Method m){
String name = m.getName();
System.out.print(Modifier.toString(m.getModifiers()));
System.out.print(" ");
printTypes(m.getTypeParameters(),"<",", ",">",true);
printType(m.getGenericReturnType(),false);
System.out.print(" ");
System.out.print(name);
System.out.print("(");
printTypes(m.getGenericParameterTypes(),"",", ","",false);
System.out.println(")");
}
public static void printTypes(Type[] types,String pre,String sep,String suf,
boolean isDefinition){
if (pre.equals(" extends ")&& Arrays.equals(types,new Type[] {Object.class}))return;
if (types.length>0) System.out.print(pre);
for (int i = 0; i < types.length; i++) {
if (i>0) System.out.print(sep);
printType(types[i],isDefinition);
}
if (types.length>0) System.out.print(suf);
}
public static void printType(Type type,boolean isDefinition){
if (type instanceof Class){
Class<?> t = (Class<?>) type;
System.out.print(t.getName());
}
else if (type instanceof TypeVariable){
TypeVariable<?> t = (TypeVariable<?>) type;
System.out.print(t.getName());
if (isDefinition) {
printTypes(t.getBounds(), " extends ", " & ", "", false);
}
}
else if (type instanceof WildcardType){
WildcardType t = (WildcardType) type;
System.out.print("?");
printTypes(t.getUpperBounds()," extends "," & ","",false);
printTypes(t.getLowerBounds()," super "," & ","",false);
}
else if (type instanceof ParameterizedType){
ParameterizedType t = (ParameterizedType) type;
Type owner = t.getOwnerType();
if (owner!=null){
printType(owner,false);
System.out.print(".");
}
printType(t.getRawType(),false);
printTypes(t.getActualTypeArguments(),"<",", ",">",false);
}
else if (type instanceof GenericArrayType){
GenericArrayType t = (GenericArrayType) type;
System.out.print("");
printType(t.getGenericComponentType(),isDefinition);
System.out.print("[]");
}
}
Result:
Enter class name (e.g. java.util.Collections):
java.util.Collections
class java.util.Collections
extends java.lang.Object
private static <T>T get(java.util.ListIterator<? extends T>, int)
public static <T>T min(java.util.Collection<? extends T>, java.util.Comparator<? extends T>)
public static <T extends java.lang.Object & java.lang.Comparable<? extends T>>T min(java.util.Collection<? extends T>)
public static <T>T max(java.util.Collection<? extends T>, java.util.Comparator<? extends T>)
public static <T extends java.lang.Object & java.lang.Comparable<? extends T>>T max(java.util.Collection<? extends T>)
public static <T>boolean replaceAll(java.util.List<T>, T, T)
public static transient <T>boolean addAll(java.util.Collection<? extends T>, T[])
public static <T>java.util.Set<T> synchronizedSet(java.util.Set<T>)
static <T>java.util.Set<T> synchronizedSet(java.util.Set<T>, java.lang.Object)
public static <T>java.util.Enumeration<T> emptyEnumeration()
public static <E>java.util.Set<E> newSetFromMap(java.util.Map<E, java.lang.Boolean>)
public static <T>java.util.List<T> unmodifiableList(java.util.List<? extends T>)
public static <T>java.util.ArrayList<T> list(java.util.Enumeration<T>)
public static <T>java.util.Iterator<T> emptyIterator()
public static <T>java.util.Collection<T> synchronizedCollection(java.util.Collection<T>)
static <T>java.util.Collection<T> synchronizedCollection(java.util.Collection<T>, java.lang.Object)
public static <T>void copy(java.util.List<? extends T>, java.util.List<? extends T>)
public static <T>void fill(java.util.List<? extends T>, T)
public static <T>java.util.List<T> nCopies(int, T)
public static void reverse(java.util.List<?>)
public static <T>java.util.Comparator<T> reverseOrder()
public static <T>java.util.Comparator<T> reverseOrder(java.util.Comparator<T>)
public static <T>void sort(java.util.List<T>, java.util.Comparator<? extends T>)
public static <T extends java.lang.Comparable<? extends T>>void sort(java.util.List<T>)
public static <T>java.util.List<T> synchronizedList(java.util.List<T>)
static <T>java.util.List<T> synchronizedList(java.util.List<T>, java.lang.Object)
public static <T>int binarySearch(java.util.List<? extends T>, T, java.util.Comparator<? extends T>)
public static <T>int binarySearch(java.util.List<? extends java.lang.Comparable<? extends T>>, T)
private static <T>int indexedBinarySearch(java.util.List<? extends T>, T, java.util.Comparator<? extends T>)
private static <T>int indexedBinarySearch(java.util.List<? extends java.lang.Comparable<? extends T>>, T)
private static <T>int iteratorBinarySearch(java.util.List<? extends T>, T, java.util.Comparator<? extends T>)
private static <T>int iteratorBinarySearch(java.util.List<? extends java.lang.Comparable<? extends T>>, T)
public static void shuffle(java.util.List<?>)
public static void shuffle(java.util.List<?>, java.util.Random)
public static void swap(java.util.List<?>, int, int)
private static void swap([Ljava.lang.Object;, int, int)
public static void rotate(java.util.List<?>, int)
private static <T>void rotate1(java.util.List<T>, int)
private static void rotate2(java.util.List<?>, int)
public static int indexOfSubList(java.util.List<?>, java.util.List<?>)
public static int lastIndexOfSubList(java.util.List<?>, java.util.List<?>)
public static <T>java.util.Collection<T> unmodifiableCollection(java.util.Collection<? extends T>)
public static <T>java.util.Set<T> unmodifiableSet(java.util.Set<? extends T>)
public static <T>java.util.SortedSet<T> unmodifiableSortedSet(java.util.SortedSet<T>)
public static <T>java.util.NavigableSet<T> unmodifiableNavigableSet(java.util.NavigableSet<T>)
public static <K, V>java.util.Map<K, V> unmodifiableMap(java.util.Map<? extends K, ? extends V>)
public static <K, V>java.util.SortedMap<K, V> unmodifiableSortedMap(java.util.SortedMap<K, ? extends V>)
public static <K, V>java.util.NavigableMap<K, V> unmodifiableNavigableMap(java.util.NavigableMap<K, ? extends V>)
public static <T>java.util.SortedSet<T> synchronizedSortedSet(java.util.SortedSet<T>)
public static <T>java.util.NavigableSet<T> synchronizedNavigableSet(java.util.NavigableSet<T>)
public static <K, V>java.util.Map<K, V> synchronizedMap(java.util.Map<K, V>)
public static <K, V>java.util.SortedMap<K, V> synchronizedSortedMap(java.util.SortedMap<K, V>)
public static <K, V>java.util.NavigableMap<K, V> synchronizedNavigableMap(java.util.NavigableMap<K, V>)
public static <E>java.util.Collection<E> checkedCollection(java.util.Collection<E>, java.lang.Class<E>)
static <T>T[] zeroLengthArray(java.lang.Class<T>)
public static <E>java.util.Queue<E> checkedQueue(java.util.Queue<E>, java.lang.Class<E>)
public static <E>java.util.Set<E> checkedSet(java.util.Set<E>, java.lang.Class<E>)
public static <E>java.util.SortedSet<E> checkedSortedSet(java.util.SortedSet<E>, java.lang.Class<E>)
public static <E>java.util.NavigableSet<E> checkedNavigableSet(java.util.NavigableSet<E>, java.lang.Class<E>)
public static <E>java.util.List<E> checkedList(java.util.List<E>, java.lang.Class<E>)
public static <K, V>java.util.Map<K, V> checkedMap(java.util.Map<K, V>, java.lang.Class<K>, java.lang.Class<V>)
public static <K, V>java.util.SortedMap<K, V> checkedSortedMap(java.util.SortedMap<K, V>, java.lang.Class<K>, java.lang.Class<V>)
public static <K, V>java.util.NavigableMap<K, V> checkedNavigableMap(java.util.NavigableMap<K, V>, java.lang.Class<K>, java.lang.Class<V>)
public static <T>java.util.ListIterator<T> emptyListIterator()
public static final <T>java.util.Set<T> emptySet()
public static <E>java.util.SortedSet<E> emptySortedSet()
public static <E>java.util.NavigableSet<E> emptyNavigableSet()
public static final <T>java.util.List<T> emptyList()
public static final <K, V>java.util.Map<K, V> emptyMap()
public static final <K, V>java.util.SortedMap<K, V> emptySortedMap()
public static final <K, V>java.util.NavigableMap<K, V> emptyNavigableMap()
public static <T>java.util.Set<T> singleton(T)
static <E>java.util.Iterator<E> singletonIterator(E)
static <T>java.util.Spliterator<T> singletonSpliterator(T)
public static <T>java.util.List<T> singletonList(T)
public static <K, V>java.util.Map<K, V> singletonMap(K, V)
public static <T>java.util.Enumeration<T> enumeration(java.util.Collection<T>)
static boolean eq(java.lang.Object, java.lang.Object)
public static int frequency(java.util.Collection<?>, java.lang.Object)
public static boolean disjoint(java.util.Collection<?>, java.util.Collection<?>)
public static <T>java.util.Queue<T> asLifoQueue(java.util.Deque<T>)
java.lang.Class<T> 描述具体类型
TypeVariable[] getTypeParameters() 如果这个类型被声明为泛型类型,则获得泛型类型变量,否则获得一个长度为0的数组。
Type getGenericSuperclass() 获得被声明为这个类型的超类的泛型类型;如果这个类型是Object或不是一个类类型,则返回null。
Type[] getGenericInterfaces() 获得被声明为这个类型的接口的泛型类型,否则,如果这个类型没有实现接口,返回长度为0的数组。
java.lang.reflect.Method 方法
TypeVariable[] getTypeParameters() 如果这个方法被声明为泛型方法,则获得泛型类型变量,否则返回长度为0的数组。
Type getGenericReturnType() 获得这个方法被声明的泛型返回类型。
Type[] getGenericParameterTypes() 获得这个方法被声明的泛型参数类型。如果这个方法没有参数,返回长度为0的数组。
java.lang.reflect.TypeVariable 描述类型变量(如 T extends Comparable<? super T>)
String getName() 获得类型变量的名字。
Type[] getBounds() 获得类型变量的子类限定。否则,如果该变量无限定,则返回长度为0的数组。
java.lang.reflect.WildcardType 描述通配符(? super T)
Type[] getUpperBounds() 获得这个类型变量的子类(extends)限定,否则,如果没有子类限定,则返回长度为0的数组。
Type[] getLowerBounds() 获得这个类型变量的超类(super)限定,否则,如果没有超类限定,则返回长度为0的数组。
java.lang.reflect.ParameterizedType 描述泛型类或接口类型(如Comparable<? super T>)
Type getRawType() 获得这个参数化类型的原始类型。
Type[] getActualTypeArguments() 获得这个参数化类型声明时所使用的类型参数。
Type getOwnerType() 如果是内部类型,则返回其外部类型,如果是一个顶级类型,则返回null。
java.lang.reflect.GenericArrayType 描述泛型数组(如T[])
Type getGenericComponentType() 获得声明该数组类型的泛型组件类型。