高级Android开发工程师
Java基础第一节 泛型
泛型是什么
1.泛型是JDK5引入的新特性,提供了编译时类型安全监测机制(类型监测提前,提前到编译期)。
2.泛型的本质是参数类型;也就是说所有的泛型都是参数
3.不存在jvm虚拟机。
泛型(Generic)是Java编程语言的强大功能。它们提高了代码的类型安全性,使你在编译时可以检测到更多错误
泛型的作用
- 类型检测(提前到编译期),减少因类型问题导致运行时异常
- 消除类型转换
//不使用泛型 List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0); //使用泛型 List<String> list = new ArrayList<String>(); list.add("hello"); String s = list.get(0); // 不需要转型
- 泛型可以增加代码复用性
泛型的特点
- 版本差异:
JDK5:泛型引入
JDK7:<> 钻石运算符,可以自动推断类型参数。例如:
Box integerBox = new Box<>();//JDK7之前
Box integerBox = new Box<>(); //JDK7之后 - JAVA泛型其实是伪泛型,因为虚拟器不支持泛型
JAVA中的泛型
1. 泛型类
泛型类: 一般在类名后面加 (T代表泛型的类型,可以用任意的字母)
1.1:常见泛型类
/**
*泛型类
*/
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
1.2: 多种类型泛型类
/**
*(多种类型的参数)
*/
public class Pair<K,V> {
// T stands for "Type"
private K k;
private V v;
public Pair(K k,V v){
this.k=k;
this.v=v;
}
public void getV() {
return v;
}
public T getK() {
return k;
}
}
1.3: 创建实例
//创建实例
Box box=new Box();box.set("1");
Pair pair=new Pair(1,2);
Box<Integer> integerBox = new Box<>();
Pair<String, Box<Integer>> p = new Pair<>("primes", new Box<Integer>(1));
2. 泛型接口
泛型接口:同泛型类差不多、
/**
* 泛型接口
* @param <T> 泛型对象
*/
public interface genericsText<T> {
void setT(T t);
T getT();
}
public <T> T getT(T t1) {
return t1;
}
public <T,F> T getT(T t1,F f) {
return t1;
}
2.1 泛型接口实现继承
public interface genericsText<T> {
void setT(T t);
T getT();
}
/**
* 子类设置泛型
* @param <T> 泛型对象
*/
interface GenericsText1<T> extends GenericsText<T> {
}
/**
* 子类直接给父类设置类型变量String
*/
interface GenericsText2 extends GenericsText<String> {
}
3. 泛型方法
/**
* 泛型方法
*
* @param t 值
* @param <T> 泛型类型
* 请注意:加了<T>的才是泛型方法
*/
public <T> void set(T t) {
System.out.println(t.toString());
}
public <T> T getT(T t1) {
return t1;
}
public <T, F> T getT(T t1, F f) {
return t1;
}
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getK().equals(p2.getK()) &&
p1.getY().equals(p2.getY());
}
public static void main(String[] args) {
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = compare(p1, p2);
}
知识点
常见的泛型类型变量字母代表名称
- E:元素(集合框架中常见,指集合内容的类型)
- K:键
- V:值
- N:数字
- T:类型
- S,U,V等:第二,第三,第四个类型
类型参数VS类型变量
Box<T>
T:类型参数
Box<Srting>
String:类型变量
原始类型
原始类型:缺少实际类型变量的泛型就是原始类型。例如:
class Box<T>{}
Box box=new Box();//Box就是Box<T>的原始类型
受限的类型参数
- 功能:对泛型变量的范围作出限制。
- 限制格式:
2.1 单一限制:<U extends Number>
。
2.2 多种限制:<U extends A & B & C>
(A为class类,B C为interface接口)。 - Extends表达的含义:广义上“扩展”,兼有“类继承”和“接口实现”。
- 多种限制时,有类和接口,必须把类限制第一位,否则会报错。
- 多种限制时,最多只有一个类(即B和C不能是类);因为java是单继承。
- 限制的作用,方便类型检查,并且可以使用限制类型的方法。没限制可以理解为受限Object
继承
class A{}//父类A
class B extends A{} //B继承A
class Box<T>{} //泛型BOX
//重点
Box<B> 与Box<A>没有任何关系,也不构成继承
** 通配符**
含义:泛型中的问号符“?”,就是“通配符”
作用:代码更加灵活
副作用:
- 类型退化:不能依赖类型参数的方法
分类:
- 受限通配符:List<? extends Number>
- 不受限的通配符
使用范围:
- 参数类型
- 字段类型
- 局部变量类型
- 返回值类型
重点知识
JAVA泛型擦除机制
JAVA泛型
- JAVA的泛型机制其实是伪泛型机制,JDK5引入新特性泛型,为了向下兼容(虚拟机),所以是一种伪泛型机制
JAVA伪泛型机制:类型擦除
- 在编译期时,编译器会检查泛型的类型,在字节码的时候,就已经没有泛型的信息了,泛型类型擦除为Object
- 因为JAVA虚拟机不支持泛型,所以需要擦除
泛型的缺点
- 无法使用基本数据类型(可以用包装类型)
- 无法创建类型参数实例(反射可以)
- 无法创建参数化类型的静态变量(静态变量是全局的)
- 无法对参数化类型使用转换或者instanceof关键字(不受限的通配符可以)
- 无法创建参数化的数组(类型擦除后,变成了原始类型object)
- 泛型不能重载(类型擦除后,变成了原始类型object)
面试题
- Array(数组)中可以使用泛型嘛?
答:1. 不能使用泛型,本身实现不支持 - 你可以把List
<String>
传递给一个接受List<object>
参数的方法嘛?
ArrayList list1=new ArrayList();
ArrayList list2=new ArrayList();
答:1.虽然String继承Object,但是ArrayList`<String>`和ArrayList`<Object>`没有任何关系。泛型没有继承关系。
* **Java中List`<Object>`和原始类型的list之间的区别?Set和Set<?>到底区别在哪里?**
答:
1. Set是原始类型,Set<?>是泛型。
2. 泛型是会受类型检查的。
* ** List`<?>`和List`<Object>`的区别?**
答:
1. List`<?>`是未知类型的list,List`<Object>`是任意类型的List。
2. List<String>可以赋值给List<?>,却不能赋值给List<Object>。
结束语
谢谢您的观看,有不足之处,请多多指教。如果给到您帮助了,麻烦点个赞。谢谢