泛型
Java 泛型(generics)是 JDK 5 新增的特性
泛型的类型必须是类,不能是基本数据类型
在JDK8当中创建泛型可以省略后面的 例如:
GenericClass
it = new GenericClass (); GenericClass
it = new GenericClass<>();
java中泛型标记符:
| 标记符 | 说明 |
|---|---|
| E | Element (在集合中使用,因为集合中存放的是元素) |
| T | Type(Java 类) |
| K | Key(键) |
| N | Number(数值类型) |
| ? | 表示不确定的 java 类型 |
public class Test {
public static void main(String[] args) {
//使用泛型后
Map<Integer,String> map = new HashMap<>();
map.put(1,"张三");
map.put(2,"李四");
map.put(3,"王五");
map.put(4,"赵六");
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer,String> key : entries) {
System.out.println(key.getKey() + "=" + key.getValue());
}
}
}自定义泛型类
public class 类名 <泛型标记符>{
}//<T> 泛型的类型
public class Test <T>{
String name;
int age;
T test;
public Test() {
}
public Test(String name, int age, T test) {
this.name = name;
this.age = age;
this.test = test;
}
public T getTest() {
return test;
}
public void setTest(T test) {
this.test = test;
}
@Override
public String toString() {
return "Test{" +
"name='" + name + '\'' +
", age=" + age +
", test=" + test +
'}';
}
}测试
public class Test01 {
public static void main(String[] args) {
//如果定义了泛型类 实例化没有指明类型的泛型 则认为此泛型类型为Object类型
Test t = new Test();
t.setTest("likedx");
t.setTest(541884615);
Object test = t.getTest();
System.out.println(test);
//实例化指明泛型的类型为String
Test<String> tt = new Test<>();
tt.setTest("https://likedx.com");
String test1 = tt.getTest();
System.out.println(test1);
//下面会报错 因为指定了类型
//tt.setTest(123);
//指明泛型的类型
Test<String> t2 = new Test<>("张三",18,"是大傻叉");
Test<Integer> t3 = new Test<>();
t3.setTest(18);
}
}P1的Test02不是泛型类 P2的Test02是泛型类
public class Test02 extends Test<Integer>{}public class Test02<T> extends Test<T>{}总结
- 自定义泛型类可能有多个参数 此时应将多个参数一起放在尖括号内 例如:<T1,T2,T3>
- 泛型不同的引用不能相互赋值
- 泛型类的构造器用默认的就可以
- 如果泛型的类型不指定 泛型对应的类型均按照Object处理 但不等同于Object 要不用都别用泛型 要用就一路都用上
- 静态方法中不能使用类的泛型
- 异常类不能声明为泛型 public class MyException
extends Exception{} - 父类有泛型子类可以选择保留泛型也可以选择指定泛型类型
自定义泛型方法
- 泛型方法和泛型类没有关系
- 泛型方法可以声明为静态的
public <泛型标识符> 返回值类型 方法名(泛型标识符[] 形参){
//方法体...
}public class Test02 {
public static void main(String[] args) {
Integer [] i = new Integer[]{1,2,3,4,5,6};
String [] s = new String[]{"aa","bb","cc"};
Test02 t = new Test02();
t.printArr(s);
}
//方法的参数是一个数组,但是这个数组存放的数据类型不是具体的 而是一个泛型
public <E> void printArr(E[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}泛型类使用情景
假设数据库中有很多个表 对其中某一个表或者多个表进行增删改查处理 用泛型实现
user表结构
| id | name | birth | photo | |
|---|---|---|---|---|
| 1 | 张三 | zhang@126.com | 1998-02-15 | (NULL) |
| 2 | 李四 | li@qq.com | 1995-10-12 | (NULL) |
| 3 | 王五 | wang@163.com | 2001-11-03 | (NULL) |
Student表结构
| id | name | score |
|---|---|---|
| 1 | 张三 | 98 |
| 2 | 李四 | 65 |
| 3 | 王五 | 84 |
1.创建操作数据库的类
public class DataBase<T> {
//添加一条记录
public void add(T t){
}
//删除一条记录
public boolean remove(T t){
return false;
}
//修改一条记录
public void update(int index,T t) {}
//查询一条记录
public T getIndex(int index){
return null;
}
//查询多条记录
public List<T> getForList(int index) {
return null;
}
}2.创建两个表
public class Student { }public class user { }3.两个表继承数据库的类
public class StudentDataBase extends DataBase<Student>{ }public class userDataBase extends DataBase<user>{ }4.对表进行处理
public class DataBaseTest {
public static void main(String[] args) {
userDataBase u = new userDataBase();
u.add(new user());
u.getIndex(10);
StudentDataBase student = new StudentDataBase();
student.add(new Student());
student.getIndex(15);
student.remove(new Student());
}
}泛型之通配符 <?>
使用通配符后 可读 除了null可写 其他不行
public class TestDemo {
public static void main(String[] args) {
List<Object> list = null;
List<String> list1 = null;
List<?> list2 = null;
//类型转换异常
//list = list1;
//list1 = list;
list2 = list;
list2 = list1;
print(list);
print(list1);
}
public static void print(List<?> list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
}
}限制条件的通配符
- ? extends Person: 只允许泛型为Person的子类或者父类引用调用 也就是≤Person
- ? super Person:只允许泛型比Person的子类或者父类引用调用 ≥Person
创建一个继承关系的类
public class Person { }public class Student extends Person{ }测试
public class GenericTest {
public static void main(String[] args) {
List<? extends Person> list = null;
List<? super Person> list1 = null;
List<Person> l = null;
List<Student> l1 = null;
List<Object> l2 = null;
list = l;
list = l1;
//list = l2; l2是超级类(Object) 必须得是小于等于Person才可以
list1 = l;
//list1 = l1; list1不等于l1 因为l1是Student类继承了Person类 必须要比Person大于或者等于
list1 = l2;
}
}