Java反射 - 泛型

使用Java泛型通常分为两种不同的情况:

  1. 声明一个类/接口是可参数化的。
  2. 使用可参数化的类。
    当你写一个类或接口时,你可以指定它应该是可参数化的。 java.util.List接口就是这种情况。 而不是创建一个Object列表,你可以参数化java.util.List来创建一个String String列表,如下所示:
List<String> myList = new ArrayList<String>();

当通过反射在运行时检查可参数化类型本身时,如java.util.List,无法知道类型已经被参数化。对象本身不知道它被参数化了什么。

但是,该对象的引用知道包含它所引用的泛型的类型。也就是说,如果它不是一个局部变量。如果对象被对象中的字段引用,则可以通过反射来查看Field声明,以获取有关由该字段声明的泛型类型的信息。

如果对象被方法中的参数引用,也是一样的。通过该方法的Parameter对象(一个Java反射对象),您可以看到声明了哪个泛型类型的参数。

最后,您还可以查看方法的返回类型,以查看它声明的泛型类型。同样,你不能从返回的实际对象中看到它。您需要通过反射来查看方法声明,以查看它声明的返回类型(包括泛型)。

综上所述:只能从引用的声明(字段,参数,返回类型)中看到这些引用引用的对象所具有的通用类型。你不能从对象本身看到它。

以下各节将仔细研究这些情况。

泛型方法返回类型

如果已经获得java.lang.reflect.Method对象,则可以获取有关其通用返回类型的信息。 您可以阅读如何获取文本“Java泛型:方法”中的Method对象。 下面是一个带有参数化返回类型的方法的示例类:

public class MyClass {

  protected List<String> stringList = ...;

  public List<String> getStringList(){
    return this.stringList;
  }
}

在这个类中,可以获得getStringList()方法的通用返回类型。 换句话说,可以检测到getStringList()返回一个List <String>而不仅仅是一个List。

Method method = MyClass.class.getMethod("getStringList", null);

Type returnType = method.getGenericReturnType();

if(returnType instanceof ParameterizedType){
    ParameterizedType type = (ParameterizedType) returnType;
    Type[] typeArguments = type.getActualTypeArguments();
    for(Type typeArgument : typeArguments){
        Class typeArgClass = (Class) typeArgument;
        System.out.println("typeArgClass = " + typeArgClass);
    }
}

这段代码将打印出“typeArgClass = java.lang.String”文本。 Type []数组typeArguments数组将包含一个项目 - 一个表示java.lang.String类的Class实例。 类实现了Type接口。

泛型方法参数类型

您也可以通过Java Reflection在运行时访问通用类型的参数类型。 下面是一个带有参数化List作为参数的方法的示例类:

public class MyClass {
  protected List<String> stringList = ...;

  public void setStringList(List<String> list){
    this.stringList = list;
  }
}
method = Myclass.class.getMethod("setStringList", List.class);

Type[] genericParameterTypes = method.getGenericParameterTypes();

for(Type genericParameterType : genericParameterTypes){
    if(genericParameterType instanceof ParameterizedType){
        ParameterizedType aType = (ParameterizedType) genericParameterType;
        Type[] parameterArgTypes = aType.getActualTypeArguments();
        for(Type parameterArgType : parameterArgTypes){
            Class parameterArgClass = (Class) parameterArgType;
            System.out.println("parameterArgClass = " + parameterArgClass);
        }
    }
}

这段代码将打印出“parameterArgType = java.lang.String”文本。 Type []数组的parameterArgTypes数组将包含一个项 - 一个表示类java.lang.String的Class实例。 类实现了Type接口。

通用字段类型

也可以访问通用类型的公共字段。 字段是类成员变量 - 静态或实例变量。 您可以阅读关于在文本“Java Generics:Fields”中获取Field对象的信息。 这是前面的例子,带有一个名为stringList的实例字段。

public class MyClass {
  public List<String> stringList = ...;
}
Field field = MyClass.class.getField("stringList");

Type genericFieldType = field.getGenericType();

if(genericFieldType instanceof ParameterizedType){
    ParameterizedType aType = (ParameterizedType) genericFieldType;
    Type[] fieldArgTypes = aType.getActualTypeArguments();
    for(Type fieldArgType : fieldArgTypes){
        Class fieldArgClass = (Class) fieldArgType;
        System.out.println("fieldArgClass = " + fieldArgClass);
    }
}

这段代码将打印出“fieldArgClass = java.lang.String”文本。 Type []数组fieldArgTypes数组将包含一个项目 - 一个表示类java.lang.String的Class实例。 类实现了Type接口.

实战

package com.reflection.detail;

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

/**
 * 反射泛型
 * Created by Fant.J.
 * 2018/2/7 16:31
 */
public class Reflection_Generics {
    public static void main(String[] args) throws NoSuchMethodException {

        Class aClass = People.class;
        Method getStringList = aClass.getMethod("getStringList", null);
        //获取方法的返回值类型
        Type returnType = getStringList.getGenericReturnType();
        System.out.println(returnType);

        if(returnType instanceof ParameterizedType){
            ParameterizedType type = (ParameterizedType) returnType;
            Type[] typeArguments = type.getActualTypeArguments();
            for(Type typeArgument : typeArguments){
                Class typeArgClass = (Class) typeArgument;
                System.out.println("typeArgClass = " + typeArgClass);
            }
        }

    }
}

java.util.List<java.lang.String>
typeArgClass = class java.lang.String
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 4,183评论 1 44
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,625评论 18 399
  • 7月28日正式加入了拆书帮北京翰林分舵的入营训练营,拿到拆书家的入场门票。训练营是每一个想要成为拆书帮会员,在拆书...
    钟西贝阅读 1,327评论 5 50
  • 自己的项目整个工程只有一个界面是需要达到横屏的效果在网上找了好多都不是很好用 最后改变transform实现了 ...
    my我的阅读 297评论 0 0
  • 他说:想要自由 她说:想要流浪 他说:不甘于平凡 她说:不愿意随波逐流 很多时候,摆在眼前的貌似有很多选择 很多时...
    拾狸阅读 194评论 0 0