1.擦拭法是Java泛型的实现方式。

  • 编译器把类型视为Object。

    * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型。换句话说,虚拟机对泛型一无所知,所有的工作都是编译器做的。
  • 编译器根据实现安全的强制转型。

    * Java的范型实际是有Java在编译时进行的。编译器内容永远把T视为Object处理,只是在需要转型的时候,根据T的类型实行安全的强制转型。

2.java的泛型是由擦拭法实现的,因此有一些局限:

2.1.不能是基本类型,例如int

  • 编译器把T视为Object,Object是无法持有基本类型的

2.2.无法取得带泛型的Class

无论T的类型是什么,返回的永远是范型类。如Pair和Pair反射获取Class,获取的都是同一个Class:Pair。

public class Main {
public static void main(String[] args){
Pair<String> s = new Pair<>("xiaoming","xiaohong");
Pair<Integer> i = new Pair<>(4,5); Class c1 = s.getClass();
Class c2 = i.getClass();
System.out.println("c1:"+c1);
System.out.println("c2:"+c2); System.out.print("c1==c2:");
System.out.println(c1==c2); System.out.print("c1 == Pair.class:");
System.out.println(c1 == Pair.class);
}
}


### 2.3.无法判断带泛型的Class


```#java
//判断instance只能使用Pair
public class Main {
public static void main(String[] args){
Pair s = new Pair("xiaoming","xiaohong");
Pair i = new Pair(4,5);
if(s instanceof Pair){
System.out.println("true");
}
}
}
```

2.4.不能实例化T类型,因为擦拭后实际上是new Object()


```#log
实例化T类型必须借助Class
```
```#java
public class Pair {
private T first;
private T last;
public Pair(Class clazz) throws IllegalAccessException,InstantiationException{
first = clazz.newInstance();
last = clazz.newInstance();
}
public T getFisrt(){
return first;
}
public T getLast(){
return last;
}
public void setFirst(T first){
this.first = first;
}
public void setLast(T last){
this.last = last;
}
public String toString(){
return "Pari("+first+","+last+")";
}
}
```
### 2.5注意编写的泛型类的方法不要与Object的方法重名
```#java
public class Pair {
private T first;
private T last;
public Pair(T first,T last){
this.first = first;
this.last = last;
}
public T getFirst(){
return first;
}
public void setFirst(){
this.first = first;
}
public T getLast(){
return last;
}
public void setLast(){
this.last = last;
}
public String toString(){
return "Pair("+first+", "+last+")";
}
/**提示与java.lang.Object的equals方法重名。因为范型采用了擦拭法,T擦拭后变成了Object。因此要注意与Object的重名问题
* 'equals(T)' in 'com.testArray.pair' clashs with 'equals(Object)' in 'java.lang.Object';both methods have same erasure,yet neither overides the other
public boolean equals(T pair){
return true;
}*/
}
```
## 3.泛型继承:
可以继承子泛型类
父类的类型是Pair
子类的类型是IntPair
Pari.java
```#java
package com.testArray;

public class Pair {

private T first;

private T last;

public Pair(T first,T last){

this.first = first;

this.last = last;

}

}

IntPair.java
```#java
package com.testArray; public class IntPair extends Pair<Integer>{
public IntPair(Integer first,Integer last){
super(first,last);
}
}
package com.testArray;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; public class Main {
public static void main(String[] args){
Pair<String> p = new Pair<>("xiao","ming");
IntPair ip = new IntPair(1,2);
System.out.println(p instanceof Pair);
System.out.println(ip instanceof Pair);
System.out.println(ip instanceof IntPair);
//getSuperClass()获得该类的父类
//getGenericSuperclass()获得带有泛型的父类
//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type type = IntPair.class.getGenericSuperclass();
//ParameterizedType参数化类型,即泛型
ParameterizedType pt = (ParameterizedType) type;
//getActualTypeArguments获取参数化类型的数组,泛型可能有多个
Type[] types = pt.getActualTypeArguments();
Class<?> clazz = (Class<?>) types[0];
/**
* ? 表示不确定的java类型。
* T 表示java类型。
* K V 分别代表java键值中的Key Value。
* E 代表Element。
*/
System.out.println(clazz);
}
}

总结:

*    Java的泛型是采用擦拭法实现的
* 擦拭法决定了泛型<T>:
* 不能是基本类型,例如int
* 不能获取带泛型类型的Class,例如Pair<String>.class
* 不能判断带泛型类型的类型,例如: x instanceof Pair<String>
* 不能实例化T类型,例如new T()
* 泛型方法要防止重复定义方法,例如public boolean equals(T obj)
* 子类可以获取父类的泛型类型<T>

https://blog.csdn.net/liang5630/article/details/40185591

https://www.cnblogs.com/skyislimit/p/5665853.html

廖雪峰Java4反射与泛型-3范型-4擦拭法的更多相关文章

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

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

  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泛型-7泛型和反射

    1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...

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

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

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

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

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

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

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

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

  9. 廖雪峰Java4反射与泛型-2注解-1使用注解

    1.Annotation定义 注解是放在Java源码的类.方法.字段.参数前的一种标签.如下 package com.reflection; import org.apache.logging.log ...

随机推荐

  1. 2018.4.23 深入理解java虚拟机(转)

    深入理解java虚拟机 精华总结(面试) 一.运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区.虚拟机栈.本地方法栈.堆.程序计数器,其中方法区和堆是由线程共享的数据区,其他几个 ...

  2. hdu1686 Oulipo KMP/AC自动机

    The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...

  3. SVN三种合并类型

    https://blog.csdn.net/zht666/article/details/36178117 转自:http://wenku.baidu.com/link?url=pnALYESJnX0 ...

  4. 【java编程】java中什么是bridge method(桥接方法)

    https://blog.csdn.net/mhmyqn/article/details/47342577 https://www.cnblogs.com/strinkbug/p/5019453.ht ...

  5. oracle数据库丢失数据文件、控制文件、重做日志文件、初始化文件恢复方法

    rman  target/ list backup; 查看是否已备份,如果没有,那就不知道了 模拟故障,删除/u01/app/oracle/oradata/ORCL文件夹下的所有文件 sqlplus ...

  6. S老师 C#编程数据结构篇 学习

    直接插入排序                                                       冒泡排序 简单选择排序 线性表: using System; using Sy ...

  7. C#窗体模拟键盘按键(组合键)产生事件 ---- 通过keybd_event()函数

    如何模拟键盘按键触发产生的事件,比如模拟按下Alt + F4 关闭当前程序,Ctrl+Shift 切换输入法等 可以通过win32api 键盘事件 keybd_event() 来实现 1.定义键盘按键 ...

  8. oracle-sql模式匹配

    下面是条件 like与regexp_like条件 下面是函数 regexp_instr regexp_replace regexp_substr select * from tis_ft_user_i ...

  9. Yuan先生的博客网址

    1 Web应用  https://www.cnblogs.com/yuanchenqi/articles/8869302.html 2 http协议 https://www.cnblogs.com/y ...

  10. idea 中maven编译速度过慢的问题的解决

    解决方案一 在创建Maven项目时加上 archetypeCatalog=internal 参数,如下: 解决方案二 在maven的VM Options加上-DarchetypeCatalog=int ...