廖雪峰Java4反射与泛型-3泛型-7泛型和反射
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泛型和反射的更多相关文章
- 廖雪峰Java4反射与泛型-3范型-4擦拭法
1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...
- 廖雪峰Java4反射与泛型-3范型-6super通配符
1.super通配符 1.1super通配符第一种用法 泛型的继承关系 Pair<Integer>不是Pair<Number>的子类,如 static void set(Pai ...
- 廖雪峰Java4反射与泛型-3范型-5extends通配符
1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...
- 廖雪峰Java4反射与泛型-3范型-3编写泛型
编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...
- 廖雪峰Java4反射与范型-3范型-1什么是泛型
1.为什么需要泛型? JDK提供了ArrayList,可以看作"可变长度"的数组: 比数组使用方便 示例1:如果使用ArrayList存储String类型: 需要强制转型 不方便, ...
- 廖雪峰Java4反射与泛型-2注解-3处理注解
1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...
- 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method
2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...
- 廖雪峰Java4反射与泛型-1反射-1Class类
1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...
- 廖雪峰Java4反射与泛型-2注解-2定义注解
1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...
随机推荐
- Python基础练习及答案
1.请用代码实现:利用下划线将列表的每一个元素拼接成字符串,li=['alex', 'eric', 'rain'] 该题目主要是考的字符串的拼接,join方法, s = "" li ...
- Spring通知方法错误
错误提示,主要最后一句话 ,花了2个小时 org.springframework.beans.factory.BeanCreationException: Error creating bean ...
- 找工作String类(重点,背诵)(本质是一个类)
一个顶层设计者眼中只有2个东西接口,类(属性,方法) 无论String 类 , HashMap实现类 , Map接口 String str = "Hello" ; // 定义 ...
- IT痴汉的工作现状11-程序猿的烦恼
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/lincyang/article/details/25535181 痴汉们事实上是非常 ...
- .NET本质论 组件
模块定义 CLR程序存在模块(module)中.一个CLR模块是一个字节流,通常作为一个文件存储在本地的文件系统中或者Web服务器上 CLR模块采用Windows NT的PE/COFF可执行文件格式的 ...
- 如何利用 Chrome 来模拟移动网络来调试 FastAdmin 网站
如何利用 Chrome 来模拟移动网络来高度 FastAdmin 网站 因为目前大多数都在开发移动类的网页,所以客户端的速度下载速度要也考虑. 虽然都已经 4G 了,但还是要看看在网络质量很差的情况 ...
- c166 -div
unsigned short a=10; unsigned short b; unsigned short c;unsigned long d; b = (unsigned short)(d/2400 ...
- js-自定义对话框
引用插件 <link rel="stylesheet" type="text/css" href="${ctx }/resources/comm ...
- 用shell通过jps -m来杀死进程
#!/bin/sh ### find pid jps=`jps -m` echo "$jps"|while read i do if[[ $i =~"agentTestT ...
- JDK官网下载教程
进入官网网址 https://www.oracle.com/index.html 登录成功后,即可进行下载! PS:新版谷歌浏览器可能会出现无法下载的问题,使用IE浏览器即可.