当前位置: 首页 > news >正文

企业网站案例公司德州企业网站建设

企业网站案例公司,德州企业网站建设,wordpress文章直接转html代码,建湖网站设计文章目录引言:你是否也遇到过这样的麻烦?一、泛型是什么?一句话说清核心二、为什么需要泛型?3个核心优势三、泛型怎么用?3个核心场景通配符的基本形式通配符的使用场景通配符与泛型方法的区别总结四、泛型的细节和注意…

在这里插入图片描述

文章目录

        • 引言:你是否也遇到过这样的麻烦?
        • 一、泛型是什么?一句话说清核心
        • 二、为什么需要泛型?3个核心优势
        • 三、泛型怎么用?3个核心场景
      • 通配符的基本形式
      • 通配符的使用场景
      • 通配符与泛型方法的区别
      • 总结
        • 四、泛型的细节和注意事项
        • 结语:泛型的本质是“抽象”

引言:你是否也遇到过这样的麻烦?

假设你想写一个“求两个数之和”的函数,一开始可能这么写:

// 整数相加
public int addInt(int a, int b) {return a + b;
}// 浮点数相加
public double addDouble(double a, double b) {return a + b;
}

如果还要支持字符串拼接、自定义对象合并呢?难道要为每种类型都写一个几乎一样的函数?

这就是泛型要解决的核心问题:让代码摆脱“类型绑定”,实现“一次定义,多种类型通用”。今天我们就来聊聊泛型——这个让代码更简洁、更安全的“利器”。

一、泛型是什么?一句话说清核心

泛型(Generics)是编程语言中一种“参数化类型”的机制,简单说就是:在定义类、接口或方法时,不指定具体类型,而是用一个“占位符”代替,等到使用时再传入实际类型

比如上面的“相加”需求,用泛型可以写成:

// 泛型方法:T是类型占位符,代表“任意类型”
public <T> T add(T a, T b) {// 实际实现需根据类型处理,这里仅示意return ...;
}

调用时传入整数、字符串等类型,编译器会自动“替换”占位符,保证类型匹配。

二、为什么需要泛型?3个核心优势
  1. 消除重复代码,提高复用性
    不用为每种类型写重复逻辑,一套代码适配多种场景。比如Java集合框架(ListMap)就是泛型的典型应用:List<String> 存字符串,List<Integer> 存整数,底层逻辑却完全复用。

  2. 编译时类型检查,减少运行时错误
    没有泛型时,集合中可以放任意类型的对象,取出来时需要强制类型转换,容易出现 ClassCastException有了泛型后,编译器会在编译阶段检查类型是否匹配,提前规避错误

    List<String> list = new ArrayList<>();
    list.add(123); // 编译报错:不能添加整数到字符串列表
    
  3. 代码更清晰,可读性更高
    看到 List<User> 就知道这个列表存的是用户对象,不用猜类型,也不用看注释。

三、泛型怎么用?3个核心场景
  1. 泛型方法:在方法上定义类型参数,适用于“单个方法需要适配多种类型”的场景(即方法中的形参类型不确定时)。

方案1: 在方法申明上定义自己的泛型【只能在本方法中使用,其他方法不能使用】

public class MyArrayList {Object[] obj = new Object[10];int size;public <E> boolean add(E e){obj [size]=e;size++;return true;}
}

方案2:在类名后面定义泛型【公共泛型,所有方法都可以用】

public class MyArrayList<E> {Object[] obj = new Object[10];int size;public boolean add(E e){obj [size]=e;size++;return true;}public static <E> void addAll(ArrayList<E>list, E e1,E e2) {list.add(e1);list.add(e2);}
}
  1. 泛型类/接口:在类或接口定义时声明类型参数,适用于“整个类的逻辑与类型相关”的场景(如集合、容器)。

在这里插入图片描述

例 - 泛型类:自定义一个泛型栈:

public class GenericStack<T> {private List<T> elements = new ArrayList<>();public void push(T element) {elements.add(element);}public T pop() {if (elements.isEmpty()) return null;return elements.remove(elements.size() - 1);}
}
// 使用时指定类型,无需强转
GenericStack<String> stringStack = new GenericStack<>();
stringStack.push("hello");
String str = stringStack.pop(); // 直接得到String类型

例子2 - 泛型类:
在这里插入图片描述

在这里插入图片描述
两种实现方式:

  • 实现类给出具体的类型
public class MyArrayList3 implements List<String> {.....
}public class Generics {public static void main(String args[]){MyArrayList3 list3 = new MyArrayList2();}
}
  • 实现类延续泛型,创建实现类对象时再确定泛型
public class MyArrayList2<E> implements List<E>{.....
} public class Generics {public static void main(String args[]){MyArrayList2<String> list2 = new MyArrayList2<>();}
}
  1. 泛型通配符:在Java泛型中,通配符(Wildcard)是一种特殊的语法,用于灵活地表示“未知类型”,解决泛型类型参数的灵活性问题。它的核心作用是在不明确指定具体类型的情况下,限制泛型的范围,让代码更通用。

通配符的基本形式

通配符用 ? 表示,常见的使用场景有三种:

  1. 无界通配符(Unbounded Wildcard)?
    表示“任意类型”,但无法获取泛型的具体类型信息(编译时会擦除)。

    示例:

    // 可以接收任何泛型类型的List
    public void printList(List<?> list) {for (Object obj : list) {System.out.println(obj);}
    }
    

    注意:使用无界通配符的集合不能添加元素(除了null),因为编译器不知道具体类型,无法保证类型安全。

  2. 上界通配符(Upper Bounded Wildcard)? extends T
    表示“T类型或T的子类”,限制了泛型的上限。

    示例:

    // 接收Number及其子类(如Integer、Double)的List
    public double sum(List<? extends Number> list) {double total = 0;for (Number num : list) {total += num.doubleValue(); // 可调用Number的方法}return total;
    }
    

    特点:

    • 可以读取元素(类型为T或其子类,可安全向上转型为T)。
    • 不能添加元素(除了null),因为无法确定具体是哪个子类(例如List<? extends Number>可能是List<Integer>List<Double>,添加DoubleList<Integer>会出错)。
  3. 下界通配符(Lower Bounded Wildcard)? super T
    表示“T类型或T的父类”,限制了泛型的下限。

    示例:

    // 接收Integer及其父类(如Number、Object)的List
    public void addIntegers(List<? super Integer> list) {list.add(10); // 可以添加Integer(或其子类,如Integer本身)list.add(20);
    }
    

    特点:

    • 可以添加元素(类型为T或其子类,因为父类集合可以接收子类对象)。
    • 读取元素时,只能确定是Object类型(因为父类可能是任意上层类型,无法安全转型为具体类型)。

通配符的使用场景

  • 无界通配符:当代码不依赖泛型的具体类型,仅需要“任意类型的泛型”时(如打印集合)。
  • 上界通配符:当需要读取泛型对象,并使用其上层父类的方法时(如计算数值总和)。
  • 下界通配符:当需要写入泛型对象,且对象类型是某个类的子类时(如向集合添加特定类型元素)。

通配符与泛型方法的区别

通配符和泛型方法都能实现泛型的灵活性,但适用场景不同:

  • 通配符更适合限制泛型范围(如? extends Number),简化参数声明。
  • 泛型方法(如<T> void method(List<T> list))更适合需要在方法中复用具体类型的场景(如返回与参数同类型的对象)。

总结

通配符通过?? extends T? super T三种形式,解决了泛型类型的灵活性问题,核心是在“类型安全”和“通用性”之间找到平衡:

  • 上界通配符:只能读,不能写(除null)。
  • 下界通配符:只能写(特定类型),读时只能作为Object
  • 无界通配符:只读(Object),基本不能写

四、泛型的细节和注意事项
  1. 类型擦除:泛型信息仅在编译时存在,运行时会被“擦除”为原始类型(如 List<String> 运行时会变成 List)。因此不能用 new T()T.class 这样的写法,也不能判断 obj instanceof List<String>所以,实际上来说,Java中的泛型其实是伪泛型,只是在编译时检查,运行时仍然换回Object类型处理,处理完毕后再次强转回对应的类型输出而已

  2. 泛型数组限制:不能直接创建泛型数组(如 new T[10] 不允许),但可以声明泛型数组引用(T[] array

  3. 静态方法不能使用类的泛型参数:类的泛型参数属于实例,静态方法需自己声明泛型参数

  4. 泛型中不能写基本数据类型(在泛型擦除时,基本数据类型无法转换成Object类型)

  5. 指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类型

  6. 如果不写泛型,类型默认是Object

  7. 泛型不具备继承性,但是数据具备继承性
    在这里插入图片描述

结语:泛型的本质是“抽象”

泛型的核心思想是“对类型进行抽象”——就像函数用参数抽象值,泛型用类型参数抽象具体类型。它让代码从“为具体类型服务”升级为“为一类逻辑服务”,这也是面向对象“抽象”思想的延伸。

在这里插入图片描述
在这里插入图片描述


如果我的内容对你有帮助,请 点赞 评论 收藏 。创作不易,大家的支持就是我坚持下去的动力!
在这里插入图片描述

http://www.dtcms.com/a/609391.html

相关文章:

  • 从图片到PPT:用Python实现多图片格式(PNG/JPG/SVG)到幻灯片的批量转换
  • 鸿蒙应用构建体系深度解析:ABC、HAP、HAR、HSP与APP的技术全貌
  • Go 项目结构与编码规范
  • Docker + Nginx 部署 Java 项目(JAR 包 + WAR 包)实战笔记
  • 第四十三篇:多进程编程(Multiprocessing):如何真正实现并行计算?
  • 建设产品网站安徽整站优化
  • [大模型应用].Net下接入VLM多模态模型分析
  • asp网站改成php开发公司招聘
  • 基于GOOSE通信的防逆流保护系统在5.8MW分布式光伏项目中的应用
  • Airsim仿真、无人机、无人车、Lidar深度相机应用研究!
  • OpenCV中TrackBar控件
  • 基于Matlab多目标粒子群优化的无人机三维路径规划与避障研究
  • 嵌入式系统-实验三——串口通信实验
  • 2025cesium进阶教程|Cesium 天气特效实现:从 ShaderToy 移植下雪效果的完整方案
  • 数据库 - SQL
  • 单页网站seo怎么做秦皇岛高端网站设计
  • 做网商必备网站手机百度关键词优化
  • python实现电脑手势识别截图
  • openEuler 全场景操作系统下 cpolar 内网穿透的价值深挖与协同优化
  • 为什么选择威洛博直线模组——从 3C、新能源、半导体到医疗的大致解析
  • 利用ArcPy批量检查管线隐患点与周边设施距离的实现方案
  • 【ZeroRange WebRTC】Amazon Kinesis Video Streams WebRTC SDK 音视频传输技术分析
  • 政务机关数字化办公核心系统
  • 盐城做网站企业新增网站推广教程
  • 衡东建设局网站公司内部交流 网站模板
  • 自己做网站要买什么在网站制作前需要有哪些前期策划工作
  • RAG系统学习之——RAG技术详解与实战指南
  • ASC学习笔记0014:手动添加一个新的属性集
  • 通过手机远程操控电脑,一步步学习便捷方法
  • 【AI学习-comfyUI学习-Segment Anything分割+实时图像裁剪-各个部分学习-第九节2】