java中的泛型详解

提示:泛型的好处、泛型的用途、泛型的demo、泛型中的通配符有哪些


前言

今天准备提取出来一个工具类的时候,才猛然意识到,自己对java基础中的泛型可能没有想象中的那么熟悉。因此就总结了一下,同时也方便了后续的查阅。本人水平有限,如有误导,欢迎斧正,一起学习,共同进步!


一、泛型的好处

泛型是用来保护数据类型的安全。他的好处有
1、节省了来回转换的开销
2、避免了一些错误,比如不指定泛型,list里面同时存着int、boolean的数据,相加的时候,就会报错

二、泛型的用途

泛型的用途有:

  1. 含有泛型的类、
  2. 含有泛型的方法
  3. 含有泛型的接口
  4. 含有泛型的通配符:当使用泛型类或者方法时,传递的数据中,泛型类型的值不确定,可以通过通配符<?>表示,但是一旦使用泛型的通配符以后,只能使用Object类的共性方法,集合中元素的自身方法无法使用。

List : 该容器类型是Object的
List <?> : 该容器的数据类型可以是任意的
? : 通配符,不确定类型,代表该集合中可以存储任意类型的数据
? extend E : 限定了上限。E以及E的子类
? super E : 限定了下线,E以及E的父类

三、代码示例

1、含有泛型的类的代码:

注意,这里的T,是可以随便写的。只要是大写字母,ABCDEFG… 都可以的,这里是为了见名之意,是用的Type的T,有的源码(Collection的源码的泛型是E)中是E,代表element元素
代码如下(示例):

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Point<T> {

    private T x;
    private T y;
}

测试类:

public static void main(String[] args) {
    // 创建对象的时候,才确定了泛型的类型
    Point<Integer> point = new Point<>();
    point.setX(1);
    // 此时,只能set Integer类型的数据
    point.setY(123);

    System.out.println("=====================");

    Point<String> point1 = new Point<>();
    // 此时,只能set String类型
    point1.setY("test");
}

2、含有泛型的方法

代码如下(示例):

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Point<T> {

    // 定义泛型的方法
    public static  <M> void consolePrint(M m){
        System.out.println("泛型的M的值:"+m);
        System.out.println("泛型的M是String类型吗?:"+(m instanceof String));
    }
}

测试类

public static void main(String[] args) {

    // 测试泛型的方法
    Point.consolePrint("hello world");
    Point.consolePrint(new User());
}

3、含有泛型的接口

真正实现这个接口的时候,才知道具体的实现类型(泛型)是啥。

3.1、单个泛型

接口:

// 定义泛型的接口
public interface Door <A>{
    A getType();
}

实现:

class DoorImplA implements Door<Integer>{
    // 注意,泛型是Integer,返回就是Integer
    @Override
    public Integer getType() {
        return null;
    }
}


class DoorImplB implements Door<String >{
    // 注意,泛型是String,返回就是String
    @Override
    public String getType() {
        return null;
    }
}

3.2、多个泛型

当然, 泛型是可以有多个的,比如:

// 定义泛型的接口
public interface Door <A,B>{
    A getType();

    B getTypeB();
}


class DoorImplA implements Door<Integer,String >{
    // 注意,泛型是Integer,返回就是Integer
    @Override
    public Integer getType() {
        return null;
    }

    @Override
    public String getTypeB() {
        return null;
    }
}


class DoorImplB implements Door<String, User>{
    // 注意,泛型是String,返回就是String
    @Override
    public String getType() {
        return null;
    }

    @Override
    public User getTypeB() {
        return null;
    }
}

4、含有泛型的通配符

class Son extends User{};
public class Demo2 {

    // 这里可以放任意类型的
    public static void test1(List<?> list){

    }

    // 这里只可以放Object类型的
    public static void test2(List<Object> list){

    }

    public static void main(String[] args) {
        List<User> list1 = new ArrayList<>();
        List<Son> list2 = new ArrayList<>();
        List<Object> list3 = new ArrayList<>();
        // test1中,都可以放list1、2、3
        test1(list1);
        test1(list2);
        test1(list3);

        // test2中只可以放test3
        test2(list3);
    }
}

测试类

package com.zheng.genericity;

import com.zheng.entity.Teacher;
import com.zheng.entity.User;

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

/**
 * @author: ztl
 * @date: 2024/03/06 22:51
 * @desc:
 */

class Son extends User{};
public class Demo2 {

    // 这里可以放user和user的子类
    public static void test1(List<? extends User> list){

    }

    // 这里只可以放user、user的父类  
    public static void test2(List<? super User> list){

    }

    public static void main(String[] args) {
        List<User> list1 = new ArrayList<>();
        List<Son> list2 = new ArrayList<>();
        List<Object> list3 = new ArrayList<>();
        // test1中,只可以放User和user的子类
        test1(list1);
        test1(list2);

        // test2中只可以放user和user的父类
        test2(list3);
    }
}


总结

泛型到这里就结束了。祝大家五一快乐!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值