========================================================================================

我经常在一些文章和论坛中看有人说Java泛型信息都会在编译时被擦除,所以你不能在运行时访问任何相关的信息。这也不完全对。在运行时,在少数情况下也是可以访问到泛型信息的。实际上,这些情况中已经满足了我们对Java泛型信息的需求。本文将解释这几种情况。

下面是本文所涵盖的主题列表:

The Generics Reflection Rule of Thumb()

Generic Method Return Type(方法返回值类型的泛型)

Generic Method Parameter Types(方法参数类型的泛型)

Generic Field Types(字段类型的泛型)

========================================================================================

The Generics Reflection Rule of Thumb

使用Java泛型无外乎就下面两种情况中的一种:

Declaring a class/interface as being parameterizable. (声明类、接口参数化)

Using a parameterizable class.(使用参数化的类)

当你写一个类或者接口的时候,你可以指定它可以被参数化。java.util.List接口就是这种用法。你可以使java.util.List参数化的创建一个String的列表,而不是创建一个Object的列表。

当在运行时检查参数化类型它自己的类型时,如java.util.List,没有办法知道它具体被参数化成了什么类型。这样也合理,因为在同一应用程序中参数化的类型可以是所有类型。但是,当你检查用参数化类型声明的方法或者字段时,你可以知道它们在运行时参数化成了什么类型。简而言之:

在运行时,你不会知道参数化类型它自己的类型,但是你能知道用了参数化类型的字段和方法的类型。换句话说,它们有具体的参数类型。

下面的部分我们将更进一步的来看这几种情况。

========================================================================================

Generic Method Return Types

如果你获得了java.lang.reflect.Method对象,你也是有可能获得它的返回值类型的泛型信息的。这不会是任何参数化类型的Method对象,除了在类里面使用了参数化类型。你可以去看“Java泛型:方法”来了解如何获取Method对象。下面是一个例子,类中有参数化返回值类型的返回值:

public classMyClass {protected List stringList =...;public ListgetStringList(){return this.stringList;

}

}

在这种情况下,可以取得getStringList()方法的泛型返回值类型。换句话说,是可以检测到getStringList()方法返回的是List类型而不仅仅是List。下面是如何来取:

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

Type returnType=method.getGenericReturnType();if(returnType instanceofParameterizedType){

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[ ]类型的数组typeArguements中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。

========================================================================================

Generic Method Parameter Types

在运行时,你也可以用Java反射机制访问泛型参数的类型。下面是一个例子,类里面有一个参数化类型的参数:

public classMyClass {protected List stringList =...;public void setStringList(Listlist){this.stringList =list;

}

}

你可以像这样来访问其方法参数的参数化类型:

method = Myclass.class.getMethod("setStringList", List.class);

Type[] genericParameterTypes=method.getGenericParameterTypes();for(Type genericParameterType : genericParameterTypes){if(genericParameterType instanceofParameterizedType){

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中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。

========================================================================================

Generic Field Types

也可以访问公有字段的泛型类型。字段是类的成员变量——要么是静态变量,要么是实体变量。你可以去看“Java泛型:字段”来了解如何获取Field对象。下面是一个很早之前的例子,类中有有一个叫stringList的实体字段:

public classMyClass {public List stringList =...;

}

Field field= MyClass.class.getField("stringList");

Type genericFieldType=field.getGenericType();if(genericFieldType instanceofParameterizedType){

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数组中包含一个项——一个代表实现了Type接口的java.lang.String.Class的Class实例。

========================================================================================

目录

这是一个本教程到目前为止涵盖的主题列表:

(敬请期待下一篇翻译)

java反射 泛型类型_【译】9. Java反射——泛型相关推荐

  1. java正则表达式性能_译:Java 中的正则表达式性能概述

    译者:Darren Luo 1. 概述 在本快速教程中,我们将展示模式匹配引擎是如何工作的.我们还将介绍在 Java 中优化正则表达式的不同方式. 有关正则表达式的的使用介绍,请参阅此文. 2. 模式 ...

  2. 重庆找Java开发工作_重庆【Java开发程序员】

    重庆[Java开发程序员],提倡一切为了学员就业的办学思想,教学过程中坚持以练习企业项目为主,让学员真正能学到技术,毕业就能适应工作岗位. 重庆[Java开发程序员], Java 编程开发.而且很多软 ...

  3. java web项目_[适合初中级Java程序员修炼手册从0搭建整个Web项目](二)

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在 six-finger-web 一个Web后端 ...

  4. java 添加注解_你知道Java中的package-info的作用吗?

    package-info.java对于日常业务开发的开发者来说,可能有点陌生,如果我们再项目中创建一个package-info.java,你会发现该类只有一个packge,如下 我们无法在该java文 ...

  5. core java文献翻译_外文翻译--Java技术介绍(适用于毕业论文外文翻译+中英文对照).doc...

    毕业设计(论文)外文资料翻译 学 院: 信息工程学院 专 业: 计算机科学与技术 姓 名: XXXXXXXXX 学 号: XXXXXXXXX 外文出处: Cay s.Horstmann Core Ja ...

  6. java 注解 框架_深入浅析Java注解框架

    我们经常会在java代码里面看到:"@Override","@Target"等等样子的东西,这些是什么? 在java里面它们是"注解". 下 ...

  7. java string 序列化_详解JAVA序列化

    享学课堂作者:逐梦々少年 转载请声明出处! 现在开发过程中经常遇到多个进程多个服务间需要交互,或者不同语言的服务之间需要交互,这个时候,我们一般选择使用固定的协议,将数据传输过去,但是在很多语言,比如 ...

  8. 马士兵 java 学习笔记_马士兵java教程笔记1

    ---恢复内容开始--- 前记 虽然已经是个研究生了,但是会的东西还是特别的少 甚至连java都不能说是很会 所以准备从现在开始能好好的学习java 变成java master 标识符 标识符是由字母 ...

  9. java 02-cf_cf活动如何设置java环境变量_如何设置java环境变量

    cf助手怎么连接wifi_连接无线网设置 对于刚刚学习java的win7用户来说,首先要学会安装jdk和配置java环境变量,这是学习java的唯一途径,否则编写的代码运行时会出现bug.关于这一点, ...

  10. java 字符串乱码_这份Java面试题含答案解析竟然真的让你不用在面试上“如履薄冰”...

    面试题集共分为以下十部分: 一.Core Java: 1 - 95 题1 - 24 页 基础及语法: 1 - 61 题1 - 13 页 异常: 62 - 69 题13 - 15 页 集合: 70 - ...

最新文章

  1. mysql删除表中的唯一索引吗_Mysql 使用sql删除同表中重复数据并加唯一索引
  2. 麦司机博客项目技术选型-Java后端
  3. Mybatis入门---一对多、多对多
  4. 计算机操作系统指导书,《计算机操作系统》实验指导书-2015
  5. 怎么看待传菜机器人_餐厅服务机器人可能是什么样的?
  6. Docker镜像源更改
  7. TCP ACK的pingpong交互模式
  8. NUAAccst计算机网络第四章网络层复习
  9. Tushare 基础用法
  10. [高频电子线路]-避免从第一章开始懵逼
  11. HTML文档的基本结构
  12. 移动硬盘插入电脑后不显示盘符
  13. 时序动作检测《BMN: Boundary-Matching Network for Temporal Action Proposal Generation》
  14. 考PMP需要多少钱?
  15. 33岁想从头学做网页设计_您想如何学习网页设计?
  16. USB设备仿真框架设计指南——4.DSF中的COM对象
  17. python模拟的王者游戏
  18. 开源OA系统门户:企业信息互通,集成办公
  19. 读后感系列-4.《黄金是怎样炼成的》徐小平/乔慧存
  20. Push Mail技术

热门文章

  1. vector容器——插入和删除
  2. python 量化模型_量化策略 | Python tqsdk — GhostTrader模型!(附代码)
  3. 高通笔记本装linux,在华硕畅370(TP370QL)骁龙笔记本上安装Ubuntu 18.04 ARM64的方法...
  4. python按字节读文件-使用Python进行二进制文件读写(转)
  5. 【Linux】Mac在VMware中安装ubuntu教程和安装时遇到键盘鼠标失效等问题的解决方案
  6. mysql innodb count 优化_MySQL · 引擎特性 · InnoDB COUNT(*) 优化(?)
  7. mysql 循环语句语法_MySQL循环语句之while循环测试
  8. 容器技术Docker K8s 47 服务网格(ASM)-阿里云服务网络概述
  9. 阿里云云计算 37 PolarDB MySQL的连接
  10. React Native之原理浅析, iOS原理分析与实践解析、Android原理分析与实践解析