首页/新闻资讯/正文详情

JavaSE加强:异常、泛型、集合框架吗,,

发布时间:2026/9/25 19:14:08 来源:云帆数科 栏目:资讯中心
JavaSE加强:异常、泛型、集合框架吗,,
一、异常异常程序出现的非正常情况会终止程序正常执行。Java 异常顶层父类Throwable分为两大分支Error系统级错误、Exception代码级异常1. 运行时异常RuntimeException特点编译不报错运行才报错可处理可不处理又叫非受检异常NullPointerException 空指针异常引用变量为 null调用方法/属性触发IndexOutOfBoundsException 索引越界异常数组、字符串、集合索引超出范围ArrayIndexOutOfBoundsException 数组越界ClassCastException 类型转换异常2. 编译时异常除Runtime外所有异常特点编译阶段直接报错必须处理否则无法运行又叫受检异常常见文件异常、IO异常、日期解析异常、网络异常3. 异常两种处理方式try-catch捕获异常程序可以继续运行throws抛出异常交给上层调用者处理4. 自定义异常继承 RuntimeException自定义运行异常/** * 自定义运行时异常不需要编译强制处理 */ public class BusinessRuntimeException extends RuntimeException { // 无参构造 public BusinessRuntimeException() { super(); } // 带异常信息 public BusinessRuntimeException(String message) { super(message); } // 异常信息 原始异常对象包装根源异常 public BusinessRuntimeException(String message, Throwable cause) { super(message, cause); } }使用演示public class TestRuntimeEx { public static void main(String[] args) { int age -5; if(age 0){ // 抛出运行时异常编译不会报错不用强制try‑catch throw new BusinessRuntimeException(年龄不能为负数当前 age); } } }继承 Exception自定义编译异常/** * 自定义编译期受检异常 */ public class CheckBusinessException extends Exception { public CheckBusinessException() { super(); } public CheckBusinessException(String message) { super(message); } public CheckBusinessException(String message, Throwable cause) { super(message, cause); } }使用演示public class TestCheckEx { // 受检异常必须throws声明否则编译报错 public static void checkScore(int score) throws CheckBusinessException{ if(score 0 || score 100){ throw new CheckBusinessException(分数必须0‑100之间输入score); } } public static void main(String[] args) { try { checkScore(120); } catch (CheckBusinessException e) { e.printStackTrace(); } } }5.处理异常的方法方案一层层上抛最外层捕获异常记录下异常信息并影响用户观看的信息进行提示自定义异常沿用上面//自定义运行时业务异常 public class BusinessRuntimeException extends RuntimeException{ public BusinessRuntimeException(String message) { super(message); } }底层 DAO/Service 层只抛异常不处理public class UserService { /** * 查询用户出现问题向上抛出本方法不捕获 */ public void queryUser(Integer userId) { if(userId null || userId 0){ //业务出错抛出自定义异常向上抛 throw new BusinessRuntimeException(用户ID非法); } if(userId 999){ throw new BusinessRuntimeException(该用户账号已被封禁); } System.out.println(查询用户成功); } }中间层继续向上抛不捕获public class UserController { private UserService userService new UserService(); //这里不写try-catch异常继续向外抛给调用者main public void getUserInfo(Integer userId){ userService.queryUser(userId); } }最外层 (main) 统一捕获打印日志 用户友好提示public class MainTest { public static void main(String[] args) { UserController controller new UserController(); Integer userId -2; try { //调用异常会从service→controller→抛到这里 controller.getUserInfo(userId); }catch (BusinessRuntimeException e){ //①记录完整异常信息给开发人员排查问题日志生产环境用log System.out.println(【系统日志开发看】异常堆栈信息); e.printStackTrace(); //②给用户看的提示简洁友好不能输出堆栈 System.out.println(【给用户提示】操作失败e.getMessage()); }catch (Exception e){ //兜底捕获所有其他未知异常 System.out.println(【系统日志】未知异常); e.printStackTrace(); System.out.println(【给用户提示】系统繁忙请稍后重试); } } }输出结果【系统日志开发看】异常堆栈信息 com.xxx.BusinessRuntimeException: 用户ID非法 at UserService.queryUser(UserService.java:8) ... 【给用户提示】操作失败用户ID非法方案二最外层捕获异常后尝试重新修复示例模拟网络请求捕获异常后重试修复//自定义运行时异常 class NetworkException extends RuntimeException{ public NetworkException(String msg){ super(msg); } } public class NetService { private int failCount 0; //模拟网络失败次数 //模拟调用远程网络接口偶尔会网络异常 public void callRemoteApi(){ failCount; //模拟前2次网络报错第3次成功 if(failCount 2){ throw new NetworkException(网络连接失败连接超时); } System.out.println(远程接口调用成功获取数据完成); } }最外层捕获异常尝试修复重试public class RetryMain { public static void main(String[] args) { NetService netService new NetService(); int maxRetry 3; //最大重试次数 int current 0; while(current maxRetry){ try { netService.callRemoteApi(); //正常执行无异常修复成功跳出循环 System.out.println(✅操作完成无需重试); break; }catch (NetworkException e){ current; if(current maxRetry){ //达到最大重试修复失败返回用户错误 System.out.println(【日志】多次重试仍然失败); e.printStackTrace(); System.out.println(【给用户】网络异常请检查网络后再尝试); }else{ //捕获异常执行修复操作休眠等待然后重试 System.out.printf(⚠️捕获异常%s开始第%d次重试修复%n,e.getMessage(),current); try { Thread.sleep(1000); //等待1秒模拟修复等待网络恢复 } catch (InterruptedException ie) { ie.printStackTrace(); } } }catch (Exception e){ //其他不可预期异常无法修复直接结束 e.printStackTrace(); System.out.println(【给用户】系统发生未知错误); break; } } } }输出效果⚠️捕获异常网络连接失败连接超时开始第1次重试修复 ⚠️捕获异常网络连接失败连接超时开始第2次重试修复 远程接口调用成功获取数据完成 ✅操作完成无需重试二、泛型 Generic1. 作用统一集合存储的数据类型集合中只能存放指定类型数据避免向下转型时出现类型转换异常 ClassCastException编译阶段做类型校验编译期就发现类型错误提高代码安全性没有泛型时集合存 Object取出来需要强制类型转换极易报类型转换异常。2. 使用格式标准格式集合数据类型 对象名 new 集合数据类型();示例ListString list new ArrayListString();JDK7 钻石语法JDK7 及以后右边的泛型类型可以省略只写一对尖括号 钻石语法ListString list new ArrayList();⚠️注意不是返回 Object编译期会根据左边String推导右边类型运行时擦除为 Object。3. 泛型特点泛型尖括号内只能写引用类型不能写基本数据类型基本类型必须使用对应的包装类✅ListInteger❌Listint泛型只在编译阶段生效运行阶段会发生泛型擦除全部变为 Object。泛型是编译期语法糖JVM 运行看不到泛型信息。不写泛型就是裸类型默认当作Object处理//裸泛型等价于ListObject List list new ArrayList(); list.add(abc); list.add(123);4. 通配符?通配符一般用于方法参数用来接收多种泛型类型的集合不能 add 添加元素。List?无限定通配符可以接收任意泛型类型的 Listpublic void show(List? list){ //可以获取元素取出是Object不能add除了null Object o list.get(0); }List? extends Animal上限通配符含义只能接收Animal或者Animal 的子类集合规则可以获取元素不能添加元素// Dog Cat 继承 Animal public void test(List? extends Animal list){ Animal a list.get(0); //获取没问题 //list.add(new Dog()); //报错不能添加 }List? super Animal下限通配符含义只能接收Animal或者Animal 的父类集合规则可以存 Animal 以及它的子类对象获取出来只能是 Objectpublic void test(List? super Animal list){ list.add(new Dog()); //可以存Animal子类 Object obj list.get(0); //取出只能用Object接收 }记忆口诀? extends T上界取元素可以存元素不行? super T下界存元素可以取元素只能 Object5. 自定义泛型类类名后面E,T,K,V定义泛型符号符号只是占位符大写字母习惯。 EElement 元素TType 类型返回值KKey 键VValue 值/** * 自定义泛型类 * TT是占位符创建对象的时候确定真实类型 */ public class MyGenericT { private T data; public T getData() { return data; } public void setData(T data) { this.data data; } }使用创建对象时指定真实类型// T替换为String MyGenericString g1 new MyGeneric(); g1.setData(张三); String s g1.getData(); // T替换为Integer MyGenericInteger g2 new MyGeneric(); g2.setData(100);如果创建对象不指定泛型T 就变为 Object。6. 自定义泛型接口接口上定义泛型T两种实现方式//泛型接口 public interface MyInterfaceT { void show(T t); }方式 1实现类确定具体类型//实现类直接写死类型TString public class Impl1 implements MyInterfaceString{ Override public void show(String s) { System.out.println(s); } }方式 2实现类继续保留泛型创建对象时确定类型//实现类也带上T把泛型继续传递 public class Impl2T implements MyInterfaceT{ Override public void show(T t) { System.out.println(t); } } //使用 Impl2Integer impl new Impl2(); impl.show(666);7. 自定义泛型方法方法上单独定义泛型跟类的泛型无关写在返回值前面Tpublic class MyUtil { //泛型方法T写在返回类型前面 public T void print(T t){ System.out.println(t); } //有返回值的泛型方法 public T T getObj(T t){ return t; } }调用时传入什么参数编译器自动推导 T 的类型MyUtil util new MyUtil(); util.print(hello); //TString util.print(999); //TInteger三、集合框架重点集合存储多个引用类型对象的容器长度可变功能比数组更强大。集合两大根接口Collection、Map1. Collection 单列集合存单个元素1List 接口有序、可重复、有索引ArrayList底层数组根据索引查询快、增删慢线程不安全开发最常用ListString namesnew ArrayList();LinkedList底层链表增删快、查询慢适合频繁增删数据2Set 接口无序、不可重复、无索引HashSet底层哈希表去重、无序效率高 去重依赖hashCode() equals()LinkedHashSet保留存储顺序不可重复2. Map 双列集合存键值对key-valuekey 唯一、value 可重复、无序HashMap底层哈希表查询增删极快线程不安全开发首选LinkedHashMap保留键值对存储顺序3. 集合通用方法所有Collection都有add()添加元素remove()删除元素contains()判断是否包含元素size()获取集合元素个数clear()清空集合isEmpty()判断是否为空4. 集合遍历方式普通for循环有索引集合增强for循环所有单列集合//增强for循环(既可以遍历数组也可以遍历集合) //本质是遍历迭代器的简化写法 ArrayListString namesnew ArrayList(); for(String name:names){ System.out.pringtln(name); }迭代器 Iterator通用遍历可遍历同时删除ArrayListString namesnew ArrayList(); IteratorString itnames.iterator(); while(it.hasNext()){ String nameit.next(); System.out.println(name); }//迭代器只能遍历集合Lambda表达式public interface IterableT{ default void forEach(Consumer? super T action){ objects.requireNoNull(action);//判断集合是否为空 for(T t:this){ action.accept(t); } } } public class a{ ArrayListString namesnew ArrayList(); //写法一 names.forEach(new ConsumerString(){ Override public void accept(String s){ System.out.println(s); } }); //写法二 names.forEach(s-System.out.println(s)); //写法三 names.forEach(System.out::println); }当遍历集合时又存在增删集合元素的行为时可能出现业务异常这种现象便称为并发修改异常问题5. 数组和集合区别数组长度固定可以存基本类型/引用类型集合长度可变只能存引用类型

相关推荐

本土游戏UGC“概念热、生态冷”:2021-2022基础薄弱之辨
本土游戏UGC“概念热、生态冷”:2021-2022基础薄弱之辨

2021年上半年,我在各种场合反复听到同一个词:游戏UGC。那一年3月,海外以用户创作内容为核心的平台在纽交所上市,市值直冲全球游戏公司第一梯队,“游戏UGC”这个概念从行业术语变成了资本热词;到了下半年&am… · 2026/9/25 19:14:02

医学背景转AI+医疗:月薪38K的转型经验,收藏这份高效学习路线!
医学背景转AI+医疗:月薪38K的转型经验,收藏这份高效学习路线!

本文分享了一位医学背景人士如何通过3个月规划,成功转型AI医疗领域并获得38K月薪的经验。核心步骤包括:拆解自身工作,挖掘AI结合点;通过医疗AI项目实践,掌握关键技能;将医学经验与AI能力结合,优… · 2026/9/25 19:13:56

企业微信自动回复实战:文本、图片、文件消息如何进入统一处理流程
企业微信自动回复实战:文本、图片、文件消息如何进入统一处理流程

最近在帮团队重构企微的智能客服底层架构,发现一个普遍的“代码坏味道”:很多兄弟在处理客户端发来的消息时,碰到文本就写一套解析逻辑,碰到图片写一套下载逻辑,碰到文件又单独开个线程。最后整个 Webhook 入口堆满了 … · 2026/9/25 19:13:50

Scanopy:不褪色的时序网络拓扑图谱系统
Scanopy:不褪色的时序网络拓扑图谱系统

1. 这不是又一个“画图工具”,而是一套能自己长出血管的网络拓扑系统Scanopy 这个名字刚出来的时候,我第一反应是“扫描canopy(树冠)”——不是巧合。它真就像一棵活的树:根系扎进各个网段,枝干自动伸展&am… · 2026/9/25 19:43:15

Ubuntu安装CUDA避坑指南:版本兼容、驱动配置与常见错误排查
Ubuntu安装CUDA避坑指南:版本兼容、驱动配置与常见错误排查

1. 为什么Ubuntu装CUDA翻车率这么高:先把版本矩阵搞清楚我先说一个结论:在Ubuntu上装CUDA,90%的翻车都不是因为操作复杂,而是因为版本没对齐。很多人拿到NVIDIA官网的安装命令就复制粘贴,结果要么驱动起不来&#xff0… · 2026/9/25 19:43:15

CSP-S初赛完善程序题解密:逆序对与冒泡变体的算法本质
CSP-S初赛完善程序题解密:逆序对与冒泡变体的算法本质

1. 这道“完善程序”题到底在考什么?——从2025年CSP-S初赛第1题看信奥赛命题底层逻辑如果你刚做完2025年CSP-S初赛试卷,翻到“完善程序”第一题时心里咯噔一下——代码框里空着五六个下划线,旁边是几行看似熟悉又莫名陌生的C片段&#xff0c… · 2026/9/25 19:43:09

ThinkPHP校园快递仓库管理系统:从入库到取件的全流程设计与实现
ThinkPHP校园快递仓库管理系统:从入库到取件的全流程设计与实现

1. 校园快递代收的真实痛点:这个系统到底在解决什么问题1.1 三个高频场景:快递堆成山、找件翻半天、取件排长队我在学校宿舍区旁边的快递代收点蹲过整整一个下午,才彻底理解为什么校园快递仓库管理会成为一个值得拿来做设计和实现的题目。那个… · 2026/9/25 19:43:03

SQL Server行转列从CASE WHEN到PIVOT再到动态SQL实战
SQL Server行转列从CASE WHEN到PIVOT再到动态SQL实战

行转列这事儿,干SQL Server开发的应该都不陌生——做报表、做导出、做仪表盘,隔三差五就要碰上一回。业务库为了写入高效,通常把明细按“一行一条”的窄表存,可人眼看数据偏偏喜欢“一行一个对象、后面挂一堆列”的宽表。就拿最典… · 2026/9/25 19:43:03

Java程序员的第二职业技能:Agent开发实战指南(收藏版)
Java程序员的第二职业技能:Agent开发实战指南(收藏版)

本文为Java程序员提供Agent开发转型路线图,从概念到实战,介绍如何将LLM构建成能自主感知、推理、决策、行动的智能体程序。文章强调Java开发者已有技能与Agent开发的相通之处,并通过Python基础、LLM理解、框架上手、RAG与向量检索、Multi-Age… · 2026/9/25 19:42:32

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码