/** * */ package com.baidu.unbiz.common; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.management.loading.MLet; import org.junit.Test; import com.baidu.unbiz.common.logger.CachedLogger; import com.baidu.unbiz.common.sample.AnnotationClass; /** * @author <a href="mailto:[email protected]">xuc</a> * @version create on 2014年7月17日 下午4:46:10 */ public class ReflectionUtilTest extends CachedLogger { @Test public void getAllMethodsOfClass() { assertNull(ReflectionUtil.getAllMethodsOfClass(null)); Method[] methods = ReflectionUtil.getAllMethodsOfClass(MLet.class); assertTrue(methods.length > 0); Method equalsMethod = ReflectionUtil.getMethod(Object.class, "equals", Object.class); assertTrue(methods.length > 0); List<Method> methodList = Arrays.asList(methods); assertFalse(methodList.contains(equalsMethod)); List<Class<?>> list = ClassUtil.getAllInterfaces(MLet.class); int interMethodLength = 0; for (Class<?> clazz : list) { Method[] interMethods = ReflectionUtil.getAllMethodsOfClass(clazz); interMethodLength += interMethods.length; } assertTrue(methods.length > interMethodLength); } @Test public void findAllMethodAnnotation() { assertNull(ReflectionUtil.findAllMethodAnnotation((Class<?>) null, (Class<? extends Annotation>) null)); assertNull(ReflectionUtil.findAllMethodAnnotation((Class<?>) null, AnnotationClass.Test.class)); assertNull(ReflectionUtil.findAllMethodAnnotation(AnnotationClass.class, (Class<? extends Annotation>) null)); List<AnnotationClass.Test> list = ReflectionUtil.findAllMethodAnnotation(AnnotationClass.class, AnnotationClass.Test.class); assertTrue(list.size() == 8); List<Test> newList = ReflectionUtil.findAllMethodAnnotation(AnnotationClass.class, Test.class); assertTrue(CollectionUtil.isEmpty(newList)); } @Test public void getAnnotationMethods() { assertNull(ReflectionUtil.getAnnotationMethods((Class<?>) null, (Class<? extends Annotation>) null)); assertNull(ReflectionUtil.getAnnotationMethods((Class<?>) null, AnnotationClass.Test.class)); assertNull(ReflectionUtil.getAnnotationMethods(AnnotationClass.class, (Class<? extends Annotation>) null)); List<Method> list = ReflectionUtil.getAnnotationMethods(AnnotationClass.class, AnnotationClass.Test.class); assertTrue(list.size() == 8); list = ReflectionUtil.getAnnotationMethods(AnnotationClass.class, Test.class); assertTrue(CollectionUtil.isEmpty(list)); } @Test public void invokeMethod() { assertNull(ReflectionUtil.invokeMethod(null, null)); assertNull(ReflectionUtil.invokeMethod(null, new Object(), new Object())); assertNull(ReflectionUtil.invokeMethod(null, new Object())); assertNull(ReflectionUtil.invokeMethod((Object) null, (String) null, null)); assertNull(ReflectionUtil.invokeMethod((Object) null, (String) null, (Object[]) null, (Class<?>) null)); assertNull(ReflectionUtil.invokeMethod("", (String) null, (Object[]) null, (Class<?>) null)); assertNull(ReflectionUtil.invokeMethod((Object) null, (String) null, new Object[] {}, (Class<?>) null)); assertNull(ReflectionUtil.invokeMethod((Object) null, (String) null, (Object[]) null, Emptys.EMPTY_CLASS_ARRAY)); assertNull(ReflectionUtil.invokeMethod(null, new Object(), new Object())); assertNull(ReflectionUtil.invokeMethod(null, new Object())); Method method = null; try { method = String.class.getMethod("valueOf", int.class); assertEquals("1", ReflectionUtil.invokeMethod(method, null, 1)); assertEquals("1", ReflectionUtil.invokeMethod(method, "", 1)); assertEquals("1", ReflectionUtil.invokeMethod(method, new Object(), 1)); method = String.class.getMethod("trim"); assertEquals("xxx", ReflectionUtil.invokeMethod(method, " xxx ")); assertEquals("xxx", ReflectionUtil.invokeMethod(method, new Object())); } catch (Exception e) { assertTrue(e instanceof RuntimeException); } List<String> list = CollectionUtil.createArrayList(); try { method = ArrayList.class.getDeclaredMethod("RangeCheck", int.class); ReflectionUtil.invokeMethod(method, list, Integer.MAX_VALUE); } catch (Exception e) { InvocationTargetException ex = (InvocationTargetException) e.getCause(); if (ex != null) { assertTrue(ex.getTargetException() instanceof IndexOutOfBoundsException); } } try { assertEquals("xxx", ReflectionUtil.invokeMethod(" xxx ", "trim", null)); assertEquals("xxx", ReflectionUtil.invokeMethod(new Object(), "trim", null)); } catch (Exception e) { assertTrue(e instanceof RuntimeException); } list = CollectionUtil.createArrayList(); try { ReflectionUtil.invokeMethod(list, "RangeCheck", new Object[] { Integer.MAX_VALUE }, int.class); } catch (Exception e) { if (e.getCause() instanceof NoSuchMethodException) { } else { InvocationTargetException ex = (InvocationTargetException) e.getCause(); assertTrue(ex.getTargetException() instanceof IndexOutOfBoundsException); } } } @Test public void getAllFieldsOfClass() { assertNull(ReflectionUtil.getAllFieldsOfClass(null)); assertNull(ReflectionUtil.getAllFieldsOfClass(Object.class)); assertEquals(0, ReflectionUtil.getAllFieldsOfClass(List.class).length); Field[] fields = ReflectionUtil.getAllFieldsOfClass(String.class); assertTrue(fields.length > 0); Field[] instancefields = ReflectionUtil.getAllInstanceFields(String.class); assertTrue(instancefields.length > 0); assertTrue(fields.length - instancefields.length > 0); } @Test public void getAnnotationFields() { assertNull(ReflectionUtil.getAnnotationFields((Class<?>) null, (Class<? extends Annotation>) null)); assertNull(ReflectionUtil.getAnnotationFields((Class<?>) null, AnnotationClass.Test.class)); assertNull(ReflectionUtil.getAnnotationFields(AnnotationClass.class, (Class<? extends Annotation>) null)); Field[] fields = ReflectionUtil.getAnnotationFields(AnnotationClass.class, AnnotationClass.Test.class); assertTrue(fields.length == 2); fields = ReflectionUtil.getAnnotationFields(AnnotationClass.class, Test.class); assertTrue(ObjectUtil.isEmpty(fields)); } @Test public void getComponentType() throws Exception { Field f1 = BaseClass.class.getField("f1"); Field f5 = ConcreteClass.class.getField("f5"); assertNull(ReflectionUtil.getComponentType(f1.getGenericType())); assertEquals(Long.class, ReflectionUtil.getComponentType(f5.getGenericType())); } @Test public void getGenericSuperType() throws Exception { Class<?>[] genericSupertypes = ReflectionUtil.getGenericSuperTypes(ConcreteClass.class); assertEquals(String.class, genericSupertypes[0]); assertEquals(Integer.class, genericSupertypes[1]); } @Test public void getRowType() throws Exception { Field f1 = BaseClass.class.getField("f1"); Field f2 = BaseClass.class.getField("f2"); Field f3 = BaseClass.class.getField("f3"); Field f4 = ConcreteClass.class.getField("f4"); Field f5 = ConcreteClass.class.getField("f5"); Field array1 = BaseClass.class.getField("array1"); assertEquals(String.class, ReflectionUtil.getRawType(f1.getGenericType(), ConcreteClass.class)); assertEquals(Integer.class, ReflectionUtil.getRawType(f2.getGenericType(), ConcreteClass.class)); assertEquals(String.class, ReflectionUtil.getRawType(f3.getGenericType(), ConcreteClass.class)); assertEquals(Long.class, ReflectionUtil.getRawType(f4.getGenericType(), ConcreteClass.class)); assertEquals(List.class, ReflectionUtil.getRawType(f5.getGenericType(), ConcreteClass.class)); assertEquals(String[].class, ReflectionUtil.getRawType(array1.getGenericType(), ConcreteClass.class)); assertEquals(Object.class, ReflectionUtil.getRawType(f1.getGenericType())); } public static class BaseClass<A, B> { public A f1; public B f2; public String f3; public A[] array1; } public static class ConcreteClass extends BaseClass<String, Integer> { public Long f4; public List<Long> f5; } public static class BaseClass2<X> extends BaseClass<X, Integer> { } public static class ConcreteClass2 extends BaseClass2<String> { } public static class Soo { public List<String> stringList; public String[] strings; public String string; public List<Integer> getIntegerList() { return null; } public Integer[] getIntegers() { return null; } public Integer getInteger() { return null; } public <T> T getTemplate(T foo) { return null; } public Collection<? extends Number> getCollection() { return null; } public Collection<?> getCollection2() { return null; } } @Test public void testGetRawAndComponentType() throws NoSuchFieldException { Class<Soo> sooClass = Soo.class; Field stringList = sooClass.getField("stringList"); assertEquals(List.class, ReflectionUtil.getRawType(stringList.getType())); assertEquals(String.class, ReflectionUtil.getComponentType(stringList.getGenericType())); Field strings = sooClass.getField("strings"); assertEquals(String[].class, ReflectionUtil.getRawType(strings.getType())); assertEquals(String.class, ReflectionUtil.getComponentType(strings.getGenericType())); Field string = sooClass.getField("string"); assertEquals(String.class, ReflectionUtil.getRawType(string.getType())); assertNull(ReflectionUtil.getComponentType(string.getGenericType())); Method integerList = ReflectionUtil.getMethod(sooClass, "getIntegerList"); assertEquals(List.class, ReflectionUtil.getRawType(integerList.getReturnType())); assertEquals(Integer.class, ReflectionUtil.getComponentType(integerList.getGenericReturnType())); Method integers = ReflectionUtil.getMethod(sooClass, "getIntegers"); assertEquals(Integer[].class, ReflectionUtil.getRawType(integers.getReturnType())); assertEquals(Integer.class, ReflectionUtil.getComponentType(integers.getGenericReturnType())); Method integer = ReflectionUtil.getMethod(sooClass, "getInteger"); assertEquals(Integer.class, ReflectionUtil.getRawType(integer.getReturnType())); assertNull(ReflectionUtil.getComponentType(integer.getGenericReturnType())); // Method template = ReflectionUtil.getMethod(sooClass, "getTemplate"); // assertEquals(Object.class, ReflectionUtil.getRawType(template.getReturnType())); // assertNull(ReflectionUtil.getComponentType(template.getGenericReturnType())); Method collection = ReflectionUtil.getMethod(sooClass, "getCollection"); assertEquals(Collection.class, ReflectionUtil.getRawType(collection.getReturnType())); assertEquals(Number.class, ReflectionUtil.getComponentType(collection.getGenericReturnType())); Method collection2 = ReflectionUtil.getMethod(sooClass, "getCollection2"); assertEquals(Collection.class, ReflectionUtil.getRawType(collection2.getReturnType())); assertEquals(Object.class, ReflectionUtil.getComponentType(collection2.getGenericReturnType())); } public static class Base2<N extends Number, K> { public N getNumber() { return null; } public K getKiko() { return null; } } public static class Impl1<N extends Number> extends Base2<N, Long> { } public static class Impl2 extends Impl1<Integer> { } @Test public void testGetRawWithImplClass() throws NoSuchFieldException { Method number = ReflectionUtil.getMethod(Base2.class, "getNumber"); Method kiko = ReflectionUtil.getMethod(Base2.class, "getKiko"); assertEquals(Number.class, ReflectionUtil.getRawType(number.getReturnType())); assertEquals(Number.class, ReflectionUtil.getRawType(number.getGenericReturnType())); assertEquals(Object.class, ReflectionUtil.getRawType(kiko.getReturnType())); assertEquals(Object.class, ReflectionUtil.getRawType(kiko.getGenericReturnType())); assertEquals(Number.class, ReflectionUtil.getRawType(number.getReturnType(), Impl1.class)); assertEquals(Number.class, ReflectionUtil.getRawType(number.getGenericReturnType(), Impl1.class)); assertEquals(Object.class, ReflectionUtil.getRawType(kiko.getReturnType(), Impl1.class)); assertEquals(Long.class, ReflectionUtil.getRawType(kiko.getGenericReturnType(), Impl1.class)); assertEquals(Number.class, ReflectionUtil.getRawType(number.getReturnType(), Impl2.class)); assertEquals(Integer.class, ReflectionUtil.getRawType(number.getGenericReturnType(), Impl2.class)); assertEquals(Object.class, ReflectionUtil.getRawType(kiko.getReturnType(), Impl2.class)); assertEquals(Long.class, ReflectionUtil.getRawType(kiko.getGenericReturnType(), Impl2.class)); } public static class FieldType<K extends Number, V extends List<String> & Collection<String>> { List<?> fRaw; List<Object> fTypeObject; List<String> fTypeString; List<?> fWildcard; List<? super List<String>> fBoundedWildcard; Map<String, List<Set<Long>>> fTypeNested; Map<K, V> fTypeLiteral; K[] fGenericArray; } public static class MethodReturnType { List<?> mRaw() { return null; } List<String> mTypeString() { return null; } List<?> mWildcard() { return null; } List<? extends Number> mBoundedWildcard() { return null; } <T extends List<String>> List<T> mTypeLiteral() { return null; } } public static class MethodParameterType<A> { <T extends List<T>> void m(A a, String p1, T p2, List<?> p3, List<T> p4) { } } public static class Mimple extends MethodParameterType<Long> { } @Test public void testMethodParameterTypeToString() { Method method = null; for (Method m : MethodParameterType.class.getDeclaredMethods()) { method = m; } Type[] types = method.getGenericParameterTypes(); assertEquals(Object.class, ReflectionUtil.getRawType(types[0], MethodParameterType.class)); assertEquals(String.class, ReflectionUtil.getRawType(types[1], MethodParameterType.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[2], MethodParameterType.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[3], MethodParameterType.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[4], MethodParameterType.class)); // same methods, using different impl class assertEquals(Long.class, ReflectionUtil.getRawType(types[0], Mimple.class)); // change! assertEquals(String.class, ReflectionUtil.getRawType(types[1], Mimple.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[2], Mimple.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[3], Mimple.class)); assertEquals(List.class, ReflectionUtil.getRawType(types[4], Mimple.class)); } public interface SomeGuy { } public interface Cool extends SomeGuy { } public interface Vigilante { } public interface Flying extends Vigilante { } public interface SuperMario extends Flying, Cool { }; public class User implements SomeGuy { } public class SuperUser extends User implements Cool { } public class SuperMan extends SuperUser implements Flying { } }