如何获取java泛型的参数类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取java泛型的参数类型相关的知识,希望对你有一定的参考价值。

private List<String> list = new ArrayList<String>(0);
如何获取list的参数类型是String?

注意不是获取参数的值
1.list.getClass();//这是获取list本身的类型,错误
2.for(int i = 0;i<list.size();i++)//list的长度为0,错误
Object o = list.get(i);
return o.getClass();

3。ParameterizedType type = ((ParameterizedType)t2.list.getClass().getGenericSuperclass())[0];
return type.getActualTypeArguments();这是获取父类的参数类型,错误

一般可以使用反射来获取泛型参数的实际类型,以下是详细代码:
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

public class GenericTest
/*使用反射来获取泛型信息*/
private Map<String, Integer> score;
public static void main(String[] args) throws SecurityException, NoSuchFieldException
//Class clazz = GenericTest.class;
Class<GenericTest> clazz = GenericTest.class;
//System.out.println(clazz);
Field f = clazz.getDeclaredField("score");

//直接使用getType只对普通类型有效,无法取到泛型参数
Class<?> a = f.getType();
System.out.println("score的类型是:"+a);

//获得Field实例f的泛型类型
Type gType = f.getGenericType();
//如果gType类型是ParameterizedType的对象
if (gType instanceof ParameterizedType)
ParameterizedType pType = (ParameterizedType) gType;
//获取原始类型
Type rType = pType.getRawType();
System.out.println("原始类型是:"+rType);
//取得泛型类型参数
Type[] tArgs = pType.getActualTypeArguments();
System.out.println("泛型类型是:");
for (int i = 0; i < tArgs.length; i++)
System.out.println("第"+i+"个泛型类型是:"+tArgs[i]);

else
System.out.println("获取泛型类型出错!");



输出结果如下:
score的类型是:interface java.util.Map
原始类型是:interface java.util.Map
泛型类型是:
第0个泛型类型是:class java.lang.String
第1个泛型类型是:class java.lang.Integer
参考技术A List<String> list = new ArrayList<String>(0);
System.out.println(list.getClass() == ArrayList.class);

输出结果为 true

你这个问题问的很好,说明你很关注泛型。

具体来讲,泛型只是一种编译时机制,只对变量起作用。

List<String> list = new ArrayList<String>();
List mylist = list;

mylist.add(new ArrayList<String>());

上面的代码可以编译,也可以运行。

在编译后的 class 文件中是没有泛型信息的。其类型匹配及强转都由编译器进行。如果类型不匹配,则不能编译。

这主要是为了代码运行的高效性,java 编译器分担的运行前检查越多,JVM 的负担就越小。

如果你想进行深入研究,那就要对 class 文件有所了解。
参考技术B 泛型的类型是无法在运行时通过反射取得的,泛型类型在编译成字节码的时候已经被虚拟机给去掉了,只是起到提示编译器进行类型检查的作用 参考技术C 你这个问题很没有意义,并且还是个悖论.list长度为0,里面啥也没有,你还非要去获取它,那根本就是获取不到,况且既然为0,也就更没有必要去获取它.
想深入也不是这么个深入法,这纯粹属于没事找事型的.

java怎么获取一个泛型方法的真实泛型类型

不知道我对你的题目的理解对不对:有个方法返回一个 泛型 ,你想去这个 泛型 的类型是不是?

package test;

import java.util.ArrayList;
import java.util.List;

public class Test01 

public static void main(String[] args) 
List<String> strings = new ArrayList<String>();
strings.add("123");//模拟返回一个泛型

System.out.println(strings.getClass());//第一次取类型
System.out.println(strings.get(0).getClass());//假如通过第一步知道是ArrayList类型,则再取类型

输出结果:

class java.util.ArrayList

class java.lang.String

这里只举例讲一下方法,不知道是不是你想要的,

参考技术A 用gentyref这个工具应该能解决你的问题。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.googlecode.gentyref.GenericTypeReflector;

public class ClassWithGenericMethod

public <T> void chill(List<T> aListWithTypeT)
System.out.println(GenericTypeReflector.getTypeParameter(aListWithTypeT.getClass(), Collection.class.getTypeParameters()[0]));


public void chillWildcard(List<?> aListWithTypeWildcard)
System.out.println(GenericTypeReflector.getTypeParameter(aListWithTypeWildcard.getClass(), Collection.class.getTypeParameters()[0]));


public <T> T chillReturn(Class<T> c)
T ret = null;
try
ret = c.newInstance();
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();

System.out.println(ret.getClass());
return ret;


public static void main(String... args)
ClassWithGenericMethod cwfm = new ClassWithGenericMethod();
cwfm.chill(new ArrayList<String>());
cwfm.chillWildcard(new ArrayList<Integer>());
cwfm.chillReturn(ClassWithGenericMethod.class);


以上是关于如何获取java泛型的参数类型的主要内容,如果未能解决你的问题,请参考以下文章

Java基础Java中如何获取一个类中泛型的实际类型

java如何获得泛型中的类

java反射获得泛型参数getGenericSuperclass():获取到父类泛型的类型

Java通过反射获取泛型类型信息

JAVA中,关于可变参数和泛型的问题。

Java中可以通过泛型参数区分类型吗?