Java基础之泛型

本文深入解析Java泛型的诞生背景、发展历程及语法应用,从JDK1.5引入泛型开始,详细介绍其如何增强集合、接口与继承类,提升代码灵活性与安全性。通过实例展示泛型在List接口、SpringDataJPA中的运用,以及菱形语法的便捷性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

泛型:

           java泛型.诞生于JDK1.5版本;

作用:

  1. 增强java集合,让集合可以记住你存储的类型,并在编译的时候就可以检测;
  2.  除了对集合有所增强外.java泛型还增强了接口和继承类.让子类和实现类在派生上更加灵活多样化;

↓↓↓↓↓↓↓↓↓↓ 文章下方会有实例演示↓↓↓↓↓↓↓↓↓↓↓↓↓

历史:

  • JDK 1.5 以前

       没有泛型,集合在存储的都是Object类型.即使你存一个String类型的变量,在存的时候它是String类型,但是存入之后集合就会忘掉它的类型,然后在你取的时候,取出的都是Object类型。假如你想要一个String类型的值。你就需要自己去强转,但是这样就会衍生一个问题,那就是常常会发生ClassCastException,就是所谓的转换异常

  • JDK 1.5
  1. 在JDK1.5 版本对所有的接口都进行了重写让其支持泛型
  2. 典型的就是list 接口,在JDK1.5版本后我们在list存储元素。它就会记住我们的存储类型。并且在编译的时候就会检测你存入的类型时候正确。只要编译的时候没有问题。在程序运行后,它就不会再产生classCastException异常;
  3. 泛型用在接口和抽象类上.让其实现类与子类更加多样化;典型示例就是List接口,与Spring data jpa接口示例;
  • JDK 1.7  菱形语法;

JDK 1.5 创建一个List集合是这样的List<String> list = new ArrayList<String>();

JDK 1.7 创建一个List集合是这样的List<String> list = new ArrayList<>();

JDK 1.7 在JDK 1.5的基础上对泛型又进行了加强.那就是菱形语法.在JDK1.5版本.我们必须在 ''等号''  左右两方都加上泛型,但是JDK1.7 我们只需要在 "等号" 的左边加上右边省略不写, java会自动推断我们想要这个list集合存储的类型.使得编码更加简单;

语法:

<>  在菱形符号中写入我们想要的元素类型

实例:
    1. 简单的实例用法
        List<String> , Map<String,Object>   
    2. 通配符
        List<?>   list<? extends Object >  list<? super String>
    List<?> 代表可以存入不确定的类型,
    list<? extends Object>  这种语法被称之为设定泛型上限
            这个list所存入的集合必须是继承于object的或者object本身
    list<? super String>  这种语法被称为设定泛型下限
            这个list所存入的集合必须是string的父类或者本身

-------------------------------------------------------------------
当然上方的Object 和string是示例 ,你可以指定任意类型   

实例:

# 此处我们示例为java源码片段.由此演示-----<我想没有再比java源码更加适合作为典例了吧!>
--------------------------------------------------------------------------------------
# List接口片段
public interface List<E> extends Collection<E> {
    // 此处重点,看接口的写法:
    // 我们需要记住的一点就是无论接口还是类.泛型要写都要写.
    // 切记不能写成 public interface 类名  extends 父接口<E>{} .要写两边子父类泛型都要写上,

   ..... 此处省略一万字!!!!!!
    int size();
}
# list的实现类 ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
 
      ..... 此处省略一万字!!!!!!

    //重点在此处构造.切记我们自己在写构造的时候 不能写成 public 类名<E>(){}  这种语法是错误的,    
    // 构造是不存在泛型的;
    // 由此有个注意的地方.那就是 new ArrayList<String> (),虽然我们new 了 ArrayList<String>(),但是是不存在public class ArrayList<String>这个带实际泛型类型的类的;
    // 所以 不存在 new ArrayList<string>().instanceof Arraylist<String>.class的 
    /*
    List<String> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();
    System.out.print(list1.getclass() == list2.getclass()) //结果是true
    由此可以验证.不存在Arraylist<String> 或者ArrayList<Integer> 类
    所以我们也不能使用instanceOf 这个方法
    切记切记.......................
*/
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }        

}

---------------------------------------------------------------------------------
# spring data jpa 源码 
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

    // 可以做返回值
	List<T> findAll();

	List<T> findAll(Sort sort);

    //可以做方法形参
	List<T> findAllById(Iterable<ID> ids);

    //设定泛型上限
	<S extends T> List<S> saveAll(Iterable<S> entities);

     ....... 省略一万字..
}

注意:

  1. 静态方法
  2. 静态初始化块
  3. 静态变量

上面3点声明与初始化都不允许使用类型形参 也就是上面的<E>

  • 派生类的时候 .子父类泛型要写都写.要不写都不写,不要一个写一个不写;
  • 带有泛型的类.构造的时候切记不要在构造上加泛型;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值