1.部分反射API是泛型

1.1获取反射API的泛型

部分反射API是泛型,如Class<T>是泛型
       //如果使用Class,不带泛型,出现compile warning编译警告
Class clazz1 = String.class;
String str1 = (String) clazz1.newInstance();
//改写为带泛型的Class,如Class<T>是泛型,
Class<String> clazz2 = String.class;
String str2 = clazz2.newInstance();//不用转型,直接得到
Class<? super String> sup = clazz2.getSuperclass();

1.2获取Constructor的泛型

Constructor<T>是泛型
        Class<Integer> clazz = Integer.class;
Constructor<Integer> cons = clazz.getConstructor(int.class);
Integer i = cons.newInstance(123);

2.泛型数组

可以声明带泛型的数组,但不能用new创建带泛型的数组:

        Pair<String>[] ps1 = null;//声明带泛型的数组
Pair<String>[] ps2 = new Pair<String>[2];//用new创建带泛型的数组,报错

必须通过强制转型实现带泛型的数组:

        @SuppressWarnings("unchecked")
Pair<String>[] ps3 = (Pair<String>[]) new Pair[2];

使用泛型数组要特别小心

2.1不安全的使用泛型数组

public class Main {
public static void main(String[] args) {
Pair[] arr = new Pair[2];
Pair<String>[] ps = (Pair<String>[]) arr;//arr和ps是同一个对象 ps[0] = new Pair<String>("a","b");//指定ps[0]
arr[1] = new Pair<Integer>(1,2);//指定ps[1]
/**
* Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
* at com.testArray.Main.main(Main.java:15)
*/
Pair<String> p = ps[1];
String s = p.getFirst();//ps[1]是Integer类型,报错
}
}

2.2安全的使用泛型数组

public class Main {
public static void main(String[] args) {
//扔掉arr的引用,就只能针对ps进行操作,这种引用就是安全的
@SuppressWarnings("unchecked")
Pair<String>[] ps = (Pair<String>[]) new Pair[2]; ps[0] = new Pair<String>("a","b");
Pair<String> p = ps[1];
String s = p.getFirst();
}
}

2.3带泛型的数组实际上是编译器的类型擦除

public class Main {
public static void main(String[] args) {
Pair[] arr = new Pair[2];
Pair<String>[] ps = (Pair<String>[]) arr; ps[0] = new Pair<String>("a","b");//指定ps[0]
System.out.println(ps.getClass() == arr.getClass());
String s1 = (String) arr[0].getFirst();
String s2 = ps[0].getFirst();
System.out.println(s1);
System.out.println(s2);
}
}


### 2.4不能直接创建T[]数组
```#java
//不能直接创建T类型的数组,因为擦拭后代码变为new Object的数组,即new Object[5]
class Abc{
T[] createArray(){
return new T[5];
}
}
```
```#log
方法一:必须借助Class
```
```#java
class Abc{
T[] createArray(Class cls){
return (T[]) Array.newInstance(cls,5);
}
}
```
```#log
方法二:利用可变参数创建T[]数组
```
```#java
public class ArrayHepler {
@SafeVarargs
static T[] asArray(T... objs){
return objs;
}
public static void main(String[] args){
String[] ss = asArray("a","b","c");
Integer[] ii = asArray(1,2,3);
}
}
```
## 3.实例
```#java
import java.lang.reflect.Constructor;
import java.util.Arrays;

public class Main {

public static void main(String[] args) throws Exception{

//创建一个泛型对象,通过其创建String对象

Class clazz = String.class;

String s1 = clazz.newInstance();

System.out.println(s1);

    //创建一个范型的Constructor对象,通过其创建String对象
Constructor<String> cons = clazz.getConstructor(String.class);
String s2 = cons.newInstance("Hello");
System.out.println(s2); //创建一个泛型数组
Pair<String>[] ps = (Pair<String>[]) new Pair[2];//先创建Pair数组再转型
ps[0] = new Pair<>("a","b");
ps[1] = new Pair<>("x","y");
System.out.println(Arrays.toString(ps));
}

}

<img src="https://img2018.cnblogs.com/blog/1418970/201903/1418970-20190305215015922-1467877953.png" width="500" />

##    4.总结:
* 部分反射API是范型:
```#log
Class<T>
Constructor<T>
  • 可以声明带泛型的数组,但不能直接创建带泛型的数组,必须强制转型
  • 可以通过Array.newInstance(Class, int)创建T[] 数组,需要强制转型

廖雪峰Java4反射与泛型-3泛型-7泛型和反射的更多相关文章

  1. 廖雪峰Java4反射与泛型-3范型-4擦拭法

    1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...

  2. 廖雪峰Java4反射与泛型-3范型-6super通配符

    1.super通配符 1.1super通配符第一种用法 泛型的继承关系 Pair<Integer>不是Pair<Number>的子类,如 static void set(Pai ...

  3. 廖雪峰Java4反射与泛型-3范型-5extends通配符

    1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...

  4. 廖雪峰Java4反射与泛型-3范型-3编写泛型

    编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...

  5. 廖雪峰Java4反射与范型-3范型-1什么是泛型

    1.为什么需要泛型? JDK提供了ArrayList,可以看作"可变长度"的数组: 比数组使用方便 示例1:如果使用ArrayList存储String类型: 需要强制转型 不方便, ...

  6. 廖雪峰Java4反射与泛型-2注解-3处理注解

    1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...

  7. 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method

    2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...

  8. 廖雪峰Java4反射与泛型-1反射-1Class类

    1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...

  9. 廖雪峰Java4反射与泛型-2注解-2定义注解

    1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...

随机推荐

  1. RESTful规范(一)

    一.学习restframework之前准备 1.json格式若想展示中文,需要ensure_ascii=False import json dic={'name':'你好'} print(json.d ...

  2. Linux,IDS入侵防御系统

    https://www.comparitech.com/net-admin/network-intrusion-detection-tools/11 2018年的顶级入侵检测工具 https://op ...

  3. 20165313Java实验四 Android程序设计

    实验报告封面 课程:Java程序设计 班级:1653班 姓名:张晨晖 学号:20165313 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 15:25 实验序号:实验四 ...

  4. canvas的认识,时钟的设置

    canvas的三要素:ID标识,width宽度,height高度,他是行元素 IE9才支持canvas,canvas是一个透明的画板,要用js去画 绘制一个圆 线性渐变颜色 径向渐变 图片的绘制: 视 ...

  5. 工作记录[续] android OBB

    前两篇在这里: Android上使用native IO 最近工作中的问题笔记 最近遇到的问题是, java.io.IOException: FAT Full StackOverflow的结果: htt ...

  6. mongodb集群性能优化

    mongodb集群性能优化 在前面两篇文章,我们介绍了如何去搭建mongodb集群,这篇文章我们将介绍如何去优化mongodb的各项配置,以达到最优的效果. 警告 不做任何的优化,集群搭建完成之后,使 ...

  7. nginx实现nginx/tomcat负载均衡

    准备三台centos7虚拟机,全部安装nginx或者tomcat 虚拟机A 10.0.3.46        在index.html 中添加10.0.3.46作为标志 虚拟机B 10.0.3.66   ...

  8. Map的嵌套使用

    Map嵌套Map: 例: AAA: Javas班: 001 熊大 002 熊二 Hdoop班 001 小猪猪 002 小菲菲 ★使用增强for循环遍历Set数组: import java.util.H ...

  9. oracle-对象表-外部表

    http://www.blogjava.net/decode360/archive/2008/10/16/286802.html create or replace type person as ob ...

  10. react-router 从 v3 版本升到 v4 版本,升级小记

    react-router v4 跟 react 一样拆成了两部分,核心的 react-router 和依运行环境而定的 react-router-dom 或 react-router-native(跟 ...