泛型

Java 泛型(generics)是 JDK 5 新增的特性

泛型的类型必须是类,不能是基本数据类型

在JDK8当中创建泛型可以省略后面的 例如:

GenericClass it = new GenericClass();

GenericClass it = new GenericClass<>();

java中泛型标记符:

标记符说明
EElement (在集合中使用,因为集合中存放的是元素)
TType(Java 类)
KKey(键)
NNumber(数值类型)
?表示不确定的 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表结构

idnameemailbirthphoto
1张三zhang@126.com1998-02-15(NULL)
2李四li@qq.com1995-10-12(NULL)
3王五wang@163.com2001-11-03(NULL)

Student表结构

idnamescore
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;
    }
}
最后修改:2023 年 03 月 29 日
如果觉得我的文章对你有用,请随意赞赏