java反射与各种泛型

当使用反射获取到一个Type时

可能会是以下几种类型:

1.Class (eg:普通Class或者数组Class)

public class UserService {
    public User[] getUserArray() {
        return null;
    }
}
@Test
public void getUserArrayTest() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;

	Method method = clazz.getMethod("getUserArray");
	//获取返回值类型
	Type type = method.getGenericReturnType();

	System.out.println("type is class?: " + (type instanceof Class));

	if (type instanceof Class<?>) {
		System.out.println("type:" + type);
		System.out.println("type is Array?: " + (((Class<?>) type).isArray()));
	}
}

控制台输出:

type is class?: true
type:class [Lcom.valsong.reflect.User;
type is Array?: true

可以看到 getUserArray()方法的返回值类型User[]是一个Class并且是一个数组类型

ps:如何使用反射创建数组实例?

使用

User[] users = User[].class.newInstance();

的方式是行不通的 执行上述代码会得到一个错误:

Caused by: java.lang.NoSuchMethodException: [Lcom.valsong.reflect.User;.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	... 23 more

正确方式:

@Test
public void createArrayInstanceTest() throws IllegalAccessException, InstantiationException {
	User[] users = (User[]) Array.newInstance(User.class, 10);
	users[0] = new User("val", 26);
	System.out.println(Arrays.toString(users));
}

2.ParameterizedType (eg:List<User> Map<String,User> 等)

public List<User> findAll() {
	return Collections.emptyList();
}
@Test
public void findAllTest() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;
	Method method = clazz.getMethod("findAll");
	//获取返回值类型
	Type type = method.getGenericReturnType();
	System.out.println("type is ParameterizedType?: " + (type instanceof ParameterizedType));
	if (type instanceof ParameterizedType) {
		Type rawType = ((ParameterizedType) type).getRawType();
		Type [] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
		System.out.println("rawType: " + rawType);
		System.out.println("actualTypeArguments:" + Arrays.toString(actualTypeArguments));
	}
}

findAll()方法返回值List<User>类型就是ParameterizedType
控制台输出:

type is ParameterizedType?: true
rawType: interface java.util.List
actualTypeArguments:[class com.valsong.reflect.User]

注意当List没有泛型时他的类型就是class,例如

public List findAll2() {
	return Collections.emptyList();
}
@Test
public void findAll2Test() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;
	Method method = clazz.getMethod("findAll2");
	//获取返回值类型
	Type type = method.getGenericReturnType();
	System.out.println("type is ParameterizedType?: " + (type instanceof ParameterizedType));
	System.out.println("type is class?: " + (type instanceof Class));

}

控制台输出:

type is ParameterizedType?: false
type is class?: true

3.WildcardType (eg: ? , ? extends User , ? super User 等)

public List<?> findAll3() {
	return Collections.emptyList();
}
@Test
public void findAll3Test() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;
	Method method = clazz.getMethod("findAll3");
	//获取返回值类型
	Type type = method.getGenericReturnType();
	System.out.println("type is ParameterizedType?: " + (type instanceof ParameterizedType));
	if (type instanceof ParameterizedType) {
		Type rawType = ((ParameterizedType) type).getRawType();
		Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
		System.out.println("rawType: " + rawType);
		System.out.println("actualTypeArguments:" + Arrays.toString(actualTypeArguments));

		System.out.println("actualTypeArguments[0] is WildcardType?: " + (actualTypeArguments[0] instanceof WildcardType));
	}
}

控制台输出:

type is ParameterizedType?: true
rawType: interface java.util.List
actualTypeArguments:[?]
actualTypeArguments[0] is WildcardType?: true

findAll3()的返回值List<?>其中?就是WildcardType

当然类似

public List<? extends User> findAll4() {
        return Collections.emptyList();
    }

    public List<? super User> findAll5() {
        return Collections.emptyList();
    }

同理,? extends User , ? super User 也是WildcardType

4.TypeVariable (eg: T)

public class UserService extends AbstractService<User> {

}
public class AbstractService<T> {

    void save(T t) {
    }
}
@Test
public void saveTest() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;
	Method method = clazz.getMethod("save", Object.class);
	//获取返回值类型
	Type[] types = method.getGenericParameterTypes();
	Type type = types[0];
	System.out.println("type is TypeVariable?: " + (type instanceof TypeVariable));
	if (type instanceof TypeVariable) {
		System.out.println("type:" + type);
		Class<?> genericDeclaration = (Class<?>) ((TypeVariable) type).getGenericDeclaration();
		TypeVariable<?>[] typeVariables = genericDeclaration.getTypeParameters();
		System.out.println(Arrays.toString(typeVariables));
		ParameterizedType genericSuperclzz = (ParameterizedType) clazz.getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclzz.getActualTypeArguments();
		System.out.println(Arrays.toString(actualTypeArguments));

		int index = 0;
		for (int i = 0; i < typeVariables.length; i++) {

			if (type.equals(typeVariables[i])) {
				index = i;
				break;
			}
		}
		System.out.println("real type is : "+actualTypeArguments[index]);

	}
}

控制台输出:

type is TypeVariable?: true
type:T
[T]
[class com.valsong.reflect.User]
real type is : class com.valsong.reflect.User

save(T t)方法的参数T类型就是TypeVariable
要想获得T真正的类型则需要找出 type在 typeVariables 中的下标
再通过下标去actualTypeArguments中获取真正的类型

5.GenericArrayType (eg:T[] )

public class UserService extends AbstractService<User> {

}
public class AbstractService<T> {

    public T[] getAll() {
        return null;
    }
}
@Test
public void getAllTest() throws NoSuchMethodException {
	Class<?> clazz = UserService.class;
	Method method = clazz.getMethod("getAll");
	//获取返回值类型
	//获取返回值类型
	Type type = method.getGenericReturnType();

	System.out.println("type is GenericArrayType?: " + (type instanceof GenericArrayType));
	if (type instanceof GenericArrayType) {
		System.out.println("type:" + type);
		Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
		System.out.println("genericComponentType: " + genericComponentType);
		Class<?> genericDeclaration = (Class<?>) ((TypeVariable) genericComponentType).getGenericDeclaration();
		TypeVariable<?>[] typeVariables = genericDeclaration.getTypeParameters();
		System.out.println(Arrays.toString(typeVariables));
		ParameterizedType genericSuperclzz = (ParameterizedType) clazz.getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclzz.getActualTypeArguments();
		System.out.println(Arrays.toString(actualTypeArguments));
		int index = 0;
		for (int i = 0; i < typeVariables.length; i++) {

			if (type.equals(typeVariables[i])) {
				index = i;
				break;
			}
		}
		System.out.println("real genericComponentType is : " + actualTypeArguments[index]);
		Class<?> realType = Array.newInstance((Class<?>) actualTypeArguments[index], 0).getClass();
		System.out.println("real type is : " + realType);
	}
}

控制台输出:

type is GenericArrayType?: true
type:T[]
genericComponentType: T
[T]
[class com.valsong.reflect.User]
real genericComponentType is : class com.valsong.reflect.User
real type is : class [Lcom.valsong.reflect.User;

getAll()方法的返回值T[]类型是GenericArrayType
首先获取type为T[]
然后获取genericComponentType为T
genericComponentType在 typeVariables 中的下标
再通过下标去actualTypeArguments中获取真正的类型为 class com.valsong.reflect.User
最后通过手动创建一个空数组的实例来获取realType为class [Lcom.valsong.reflect.User

转载于:https://my.oschina.net/valsong/blog/1934544

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值