泛型

泛型

概述

1.泛型可以理解为在类上面贴了一个标签,作用是编译器通过标签确定类型。
2.所谓泛型:就是允许在定义类、接口时指定类型形参,这个类型形参将在声明变量、创建对象时确定(即传入实际的类型参数,也可称为类型实参)。 从而把原来程序运行时可能发生问题,转变为编译时的问题。

特点

▲在底层运行时会先执行一个“擦除”的动作。
▲泛型不支持继承。
▲泛型中声明的类型支持通配符。

类型通配符使用场景

 List不能被当成List对象使用,也就是说List不是List的子类。 String是继承Object的,但是泛型String并不是继承泛型Object。

 假设现在需要定义一个方法,该方法里有一个集合形参,但是集合形参的元素是不确定的,那我们应该怎样定义?

 为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了类型通配符(?)。为了表示各种泛型List的父类,我们需要使用类型通配符,类型通配符是一个问号(?),将一个问号作为类型实参传给List集合,写做List<?>(意思是未知类型元素的List),它的元素类型可以匹配任何类型。

 通配符上限 List<? extends Number> 类型必须继承Number
 通配符下限 List<? super Integer> 类型必须是Integer或者Integer的父类

泛型入门及泛型的“擦除”机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.zx.泛型;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.zx.bean.User;

//泛型入门
public class Test01 {

public static void main(String[] args) {


List list = new ArrayList();

list.add("jack");
list.add(20);
list.add("123");

User user = new User(1,"rose","123");
list.add(user);

User user2 = new User(2,"tom","123");
list.add(user2);

//System.out.println("集合的长度:"+list.size());


for(int i=0;i<list.size();i++) {
Object obj = list.get(i);

if(obj instanceof User) {
User u = (User)obj;
System.out.println("name:"+u.getName()+" pass:"+u.getPassword());
}

}

//定义集合的时候声明泛型
List<User> userList = new ArrayList<>();

userList.add(user);
userList.add(user2);

for(int i=0;i<userList.size();i++) {
User u = userList.get(i);
System.out.println("name:"+u.getName()+" pass:"+u.getPassword());

}
System.out.println("集合的长度:"+userList.size());

try {
//泛型 存在 “擦除” 机制,程序编译完成之后,泛型会被 檫除|抹除
Class<?> clazz = userList.getClass();
//获取集合的add方法
Method method = clazz.getMethod("add", Object.class);
//调用方法添加数据
method.invoke(userList, "jack");
System.out.println("集合的长度:"+userList.size());

for(Object obj : userList) {
System.out.println("obj:"+obj);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

}

}

泛型不支持继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.zx.泛型;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.zx.bean.User;

//泛型不支持继承
public class Test02 {

public static void main(String[] args) {

//定义集合的时候声明泛型
List<String> names = new ArrayList<>();

names.add("jack");
names.add("rose");

//因为泛型不支持继承 ,因此如下方法调用会出现异常
//play(names);

}

/*public static void play(List<Object> names) {

}*/

}

泛型通配符讲解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.zx.泛型;

import java.util.ArrayList;
import java.util.List;

//泛型通配符讲解
public class Test03 {

public static void main(String[] args) {


List<Byd> byds = new ArrayList<>();

List<Bmw> bmws = new ArrayList<>();

List<Dog> dogs = new ArrayList<>();
/* play(byds);
play(bmws);
play(dogs);*/

play02(byds);
play02(bmws);
//因为 dogs中的数据 并没有继承 Car因为不可以作为实参来调用 play02方法
//play02(dogs);

}

//定义方法用于接收汽车相关信息
public static void play(List<?> list) {

}

// 通配符上限 类型 必须属于Car的子类或者Car类型
public static void play02(List<? extends Car> list) {

Car car = list.get(0);

}

}

class Car{

public void run() {
System.out.println("car---->run");
}
}

class Byd extends Car{

public void run() {
System.out.println("Byd---->run");
}
}

class Bmw extends Car{
public void run() {
System.out.println("Bmw---->run");
}

}

class Dog{
public void run() {
System.out.println("Dog---->run");

}
}

自定义泛型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.zx.泛型.自定义泛型类;

//自定义泛型类 泛型约束符 建议使用 E E代表Element 或者 T T代表Type
public class MyList<E> {

//定义数据用于存放集合中的元素信息
Object[] arr = new Object[10];
//定义下标 用于记录 数据中当前添加的元素的索引位置
int index = 0;

//往集合中添加数据
public void add(E e) {
arr[index++] = e;
}

//从集合中获取元素
public E get(int num) {

Object obj = arr[num];

return (E)obj;
}

//也可以在方法上声明泛型
public static <T> T getObj(Object t) {

return (T)t;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.zx.泛型.自定义泛型类;

import java.util.ArrayList;
import java.util.List;

public class Test {

public static void main(String[] args) {

MyList<String> mylist = new MyList<>();
mylist.add("jack");
mylist.add("rose");

String name = mylist.get(0);

}

}

-------------本文结束感谢您的阅读-------------