获取java泛型参数类型

1、Type和Class的区别

简单来说,Class实现了Type接口。

Type源码定义:

package java.lang.reflect;

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */

public interface Type {
}

Class实现了Type接口:

public final class Class<T> implements java.io.Serializable,
                              java.lang.reflect.GenericDeclaration,
                              java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
}

类型的概念

“类型”刻划了一组值及其上可施行的操作,可理解为“值集”和“操作集”构成的二元组。

“类型的概念”与“值的概念”相对立,前者是程序中的概念,后者则是程序运行时的概念,两者通过“标识值”的语言成分(例如,变量、表达式等)联系起来。

比如变量v为具体类型T,类型T所刻划的值集为{v1,v2,…vn,…},则变量v运行时能取且只能取某个vi为值。由此可见,“类型”规定了具有该类型的变量或表达式的取值范围。

2、获取Java泛型参数类型

package com.rk.test;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.junit.Test;

public class ReflectTest
{
	@Test
	public void test()
	{
		Type type = Tiger.class.getGenericSuperclass();//com.rk.test.BaseAnimal<com.rk.test.Cat>
		ParameterizedType pt = (ParameterizedType) type;//com.rk.test.BaseAnimal<com.rk.test.Cat>
		Type[] types = pt.getActualTypeArguments();//[class com.rk.test.Cat]
		Type rawType = pt.getRawType();//class com.rk.test.BaseAnimal
		Type ownerType = pt.getOwnerType();//null
		Class clazz = (Class) types[0];//class com.rk.test.Cat
		String className = clazz.getName();//com.rk.test.Cat
		String simpleName = clazz.getSimpleName();//Cat
		System.out.println(className);
		System.out.println(simpleName);
	}
}

class BaseAnimal<T>
{
}

class Cat
{
}

class Tiger extends BaseAnimal<Cat>
{
}

3、ParameterizedType

package java.lang.reflect;

/**
 * ParameterizedType represents a parameterized type such as
 * Collection<String>.
 *
 * <p>Instances of classes that implement this interface must implement
 * an equals() method that equates any two instances that share the
 * same generic type declaration and have equal type parameters.
 *
 * @since 1.5
 */
public interface ParameterizedType extends Type {
    /**
     * Returns an array of {@code Type} objects representing the actual type
     * arguments to this type.
     *
     * <p>Note that in some cases, the returned array be empty. This can occur
     * if this type represents a non-parameterized type nested within
     * a parameterized type.
     *
     */
    Type[] getActualTypeArguments();

    /**
     * Returns the {@code Type} object representing the class or interface
     * that declared this type.
     */
    Type getRawType();

    /**
     * Returns a {@code Type} object representing the type that this type
     * is a member of.  For example, if this type is {@code O<T>.I<S>},
     * return a representation of {@code O<T>}.
     *
     * <p>If this type is a top-level type, {@code null} is returned.
     *
     */
    Type getOwnerType();
}
时间: 2024-08-04 13:57:27

获取java泛型参数类型的相关文章

ParameterizedType获取java泛型参数类型

https://blog.csdn.net/qq_18242391/article/details/54251947 前言 这两天在看以前写的ssh项目时,遇到一个问题就是封装的BaseDaoImpl抽象类,构造方法里面是这样写的. Class<T> clazz; public BaseDaoImpl() { ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass(); clazz = (Class&l

利用ParameterizedType获取泛型参数类型

//利用ParameterizedType获取java泛型的参数类型 public class Demo { public static void main(String[] args) { classTest(); interfaceTest(); } private static void classTest() { MySuperClass<Student, String> mySuperClass = new MySuperClass<Student, String>() 

Java泛型:类型擦除

类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String>().getClass(); System.out.println(c1 == c2); /* Output true */ 显然在平时使用中,ArrayList<Integer>()和new ArrayList<String>()是完全不同的类型,但是在这里,程序却的的确确会输

转:有关Java泛型的类型擦除(type erasing)

转载自:拈花微笑 自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资.在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结论是 Java使用类型擦除(type erasing),泛型信息只在编译时供javac作类型检查用,在编译后便被javac擦除,因此无法被反射 C++使用代码模板实现泛型,即在预处理时会生成类似?list_int?,?list_char?等的泛型类,虽然解决Java的运行时伪泛型的问题,但是会导致编

Java泛型之类型擦除

类型擦除 学过C++模板的,在使用Java泛型的时候,会感觉到有点不疑问,例如:(1)无法定义一个泛型数组.无法调用泛型参数对象中对应的方法(当然,通过extends关键字是可以做到,只是比较麻烦):(2)ArrayList<Integer>和ArrayList<String>在运行时的类型是相同的.Java中的泛型有这些问题,是它的实现机制决定的,即"类型擦除". 类型擦除的定义:编译通过后,准备进入JVM运行时,就不再有类型参数的概念,换句话说:每定义一个泛

Java泛型之类型未被擦除

大家都知道Java源码在编译之后会擦除泛型信息,现在来看一个泛型未被擦除的情况,见ConcurrentHashMap.comparableClassFor方法. ParameterizedType.getActualTypeArguments能获取类所实现的接口中未被擦除的泛型信息.实验如下: public class Parameterized { public static void main(String[] args) { Type[] types = Integer.class.get

Gson通过借助TypeToken获取泛型参数的类型的方法(转)

最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下. 由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型). 但是有的时候,我们确实需要获知泛型参数的类型,比如将使用了泛型的Java代码序列化或者反序列化的时候,这个时候问题就变得比较棘手. class Foo<T>

Gson通过借助TypeToken获取泛型参数的类型的方法

最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下. 由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型). 但是有的时候,我们确实需要获知泛型参数的类型,比如将使用了泛型的Java代码序列化或者反序列化的时候,这个时候问题就变得比较棘手. class Foo<T>

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

java泛型(二).泛型的内部原理:类型擦除以及类型擦除带来的问题 参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(type erasure). Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型