JAVA基础——泛型

  • 泛型的优点和作用
    • 面向抽象 / 可复用
    • 编译期安全检测
    • 代码可读性
  • 泛型定义和使用
    • 泛型类  / 泛型接口
    • 泛型方法
    • 泛型标识符:T, E, K, V, S
  • 通配符<?>
    • <?>结合容器时,无法使用增删改查方法,编译期报错
  • 泛型擦除
    • class Test<T>:会擦除泛型,相关的参数都变Object
    • class Test<T extends Clz>:会擦除泛型,相关的参数都变Clz

本篇是参考来的,参照的Reference:https://blog.csdn.net/briblue/article/details/76736356

1. 泛型的优点和作用

  • 它提供了一种扩展能力,它更符合面向抽象开发的软件编程宗旨,使得代码更加可复用
  • 泛型又提供了一种类型检测的机制,只有相匹配的数据才能正常的赋值,否则编译器就不通过,可以说是一种编译期安全检测机制
  • 泛型提高了程序代码的可读性,不必要等到运行的时候才去强制转换

2. 泛型类

  • 泛型类的定义和使用
    • //泛型类的定义
      public class Test<T> {
      	T field1;
      }
      
      //泛型类的使用
      Test<String> test1 = new Test<>();
      Test<Integer> test1 = new Test<>();
    • 泛型还可以接受多个参数类型
    • public class MultiType <E,T>{
      	E value1;
      	T value2;
      	
      	public E getValue1(){
      		return value1;
      	}
      	
      	public T getValue2(){
      		return value2;
      	}
      }
      
  • 泛型接口:泛型接口和泛型类差不多,所以一笔带过
    • public interface Iterable<T> {
      }
  • 泛型标识符
    • T:Type,代表一般的任何类
    • E :Element ,也指元素,一般代表集合中的类;或者 Exception 异常的意思
    • K :Key ,参见HashMap的源码
    • V :Value ,通常与 K 一起配合使用
    • S :Subtype ,文章后面部分会讲解示意
    • 其他任何字符串:出于java规范,不推荐使用

3. 泛型方法

  • 使用
    • public class Test1<T>{
          
          //泛型类的普通方法
      	public void method1(T t){
      		System.out.println(t.getClass().getName());
      	}
      
          //泛型方法
      	public <E> E method2(E e){
      		return e;
      	}
          
          //泛型方法
          public <T> void method3(T e){}
      }
      
  • 注意:
    • 上代码中method1是普通方法,method3是泛型方法
    • 区分泛型方法就看方法前面的尖括号<T>,泛型方法始终以自己定义的类型参数为准,建议泛型方法的符号和泛型类的符号不要一样,容易搞混

4. 通配符<?>

  • 存在的原因
    • //父类
      class Base{}
      //子类
      class Sub extends Base{}
      
      List<Sub> lsub = new ArrayList<>();
      List<Base> lbase = lsub;    //编译报错
    • 最后一行会编译报错,因为尽管 Sub 是 Base 的子类,不代表 List<Sub>和 List<Base>有继承关系
    • <?> 解决了这个问题
  • 使用方式
    • //错误用法,public后面不应该加<?>
      public <?> void test1(Collection<?> collection){
          collection.size();    
      }
      
      //正确用法
      public void test1(Collection<?> collection){
          collection.size();    
      }
  • <?>的三种形式
    • <?> 被称作无限定的通配符
    • <? extends T> 被称作有上限的通配符
    • <? super T> 被称作有下限的通配符
  • 其他
    • 1. 如果<?>与容器配合使用,则只能调用与泛型无关的方法,不然会报错。但是<T>不会报错,前提是需要强制转换
      • //<?>提供了只读的功能,也就是它删减了增加具体类型元素的能力,只保留与具体类型无关的功能。它不管装载在这个容器内的元素是什么类型,它只关心元素的数量、容器是否为空
        public void test1(Collection<?> collection){
            collection.add(123);    //编译报错
            collection.add("hello");    //编译报错
            collection.add(new Object());    //编译报错
        
            collection.iteration().next();    //通过
            collection.size();    //通过
        }
        
        
        public <T> void test2(Collection<T> collection){
        	collection.add((T)new Integer(12));    //通过
        	collection.add((T)"123");    //通过
        
            collection.add("123");    //编译报错
        }

         

    • 2. 泛型参数相互依赖的情况
      • //泛型类
        public class Test2 <T,E extends T>{
        	T value1;
        	E value2;
        }
        
        //泛型方法
        public <D,S extends D> void test(D d,S s){}
        
        //配合通配符使用
        public <T> void test(T t,Collection<? extends T> collection){}

5. 泛型擦除

  • 泛型擦除的概念:由于Java1.5才引进泛型,为了向上兼容,JVM会对泛型擦除,即:泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除
  • 例子1:容器类中的泛型被擦除,只留下了容器本身的信息
    • List<String> l1 = new ArrayList<String>();
      List<Integer> l2 = new ArrayList<Integer>();
      	
      System.out.println(l1.getClass());    //List.class
      System.out.println(l2.getClass());	  //List.class  
      System.out.println(l1.getClass() == l2.getClass());    //true
  • 例子2:普通类中的泛型被擦除,也只留下了类本身的信息,所有泛型类型会变成Object
    • public class Erasure <T>{
      	T aaa;
      
      	public Erasure(T object) {
      		this.object = object;
      	}
      }
      
      Erasure<String> erasure = new Erasure<String>("hello");
      Class eclz = erasure.getClass();
      
      //只打印出了Erasure,而泛型String被擦除了
      String clzName = eclz .getName();    //Erasure
      
      Field[] fs = eclz.getDeclaredFields();
      for ( Field f:fs) {
          //泛型属性的类型被擦除了
      	System.out.println("Field name:" + f.getName());    //aaa
          System.out.println("type:" + f.getType().getName());    //java.lang.Object
      }
  • 例子3:泛型有上限时,会被擦除成上限类
    • public class Erasure <T extends String>{
      	T bbb;
      
      	public Erasure(T object) {
      		this.object = object;
      	}
      }
      
      Erasure<String> erasure = new Erasure<String>("hello");
      Class eclz = erasure.getClass();
      
      //只打印出了Erasure,而泛型String被擦除了
      String clzName = eclz .getName();    //Erasure
      
      Field[] fs = eclz.getDeclaredFields();
      for ( Field f:fs) {
          //泛型属性的类型被擦除了
      	System.out.println("Field name:" + f.getName());    //aaa
          System.out.println("type:" + f.getType().getName());    //java.lang.String
      }

Reference

https://blog.csdn.net/briblue/article/details/76736356

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值