异常
-
概念:程序中出现的错误
异常体系
Throwable
-
Error:错误,Java程序本身无法恢复的严重错误,程序无需捕获处理。
-
Exception:异常,程序中的错误,程序员必须解决
-
检查时异常:编译期异常(.java -> .class)
ClassNotFoundException // 类没被找到异常 FileNotFoundException // 文件找不到异常 IOException // 输入输出异常
-
运行时异常: .class 被执行期间
NullPointerException // 空指针异常 ArrayIndexOutOfBoundsException // 数组下标越界异常 IndexOutOfBoundsException // 索引越界异常 ArithmeticException // 算术异常 InputMismatchException // 输入不匹配异常 ClassCastException // 类型转换异常 NumberFormatException // 数字格式异常
-
异常处理
-
try...catch...finally
1. try结构是必须的,catch结构和finally结构二者至少要出现其一 2. try语句块抛出异常,则try中抛出异常后的代码将不再执行,转而执行相应的catch块;如果try结构中无异常,catch则不执行。 3. catch结构可以出现多次,此时异常应该按“由小到大”的顺序进行捕获; 4. 多重捕获(multi-catch ,jdk1.7新增):一个catch语句可以捕获多个异常。 语法: catch(Exception1 | Exception2 | ... | ExceptionN e){} 5. 如果有finally结构,finally总会被执行;唯一不被执行的情况是catch(只限于catch)中出现了System.exit(1)语句;
-
throw 、throws
-
throw: 手动抛出异常:
-
用来显式地抛出一个异常实例。在方法体内的任何地方使用(例如,在条件判断中)。
- throws: 声明方法抛出异常
- 用于在方法声明的末尾中指明该方法可能会抛出的异常类型。表示该方法可能会向调用者抛出特定的异常。
-
-
try-with-resources(jdk1.7新增) 扩展try语句,称为带资源的try(try-with-resources)语句,这种try语句支持自动资源管理(例如,当流不再需要时,能自动关闭他们)。
语法:
try(resource-specification){ //use the resource } [catch(){}finally{}]
说明:
1.resource-specification 是用来声明和初始化资源(如文件流)的语句。该语句包含变量声明,在该声明中使用将被管理的对象引用初始化变量。try代码块结束时,自动释放资源。对于文件,意味着将会被自动关闭(不再需要显示的调用close方法)。 2.只有实现了AutoCloseable接口的资源,才能使用带资源的try语句。所有流类都实现了该接口。
-
异常处理结构中的 return
集合
-
概念:数据的容器
集合框架
-
Collection:单值集合(value)
-
Set : 数据无序不可重复(
Set
中的元素没有固定的顺序,无法保证元素的遍历顺序与添加顺序相同)-
HashSet
-
TreeSet: 元素会排序,实现了 SortedSet 排序接口
-
LinkedHashSet
-
-
List:数据有序可重复(元素的插入顺序被保留。当遍历 List 时,元素会按照它们被添加的顺序返回。)
-
ArrayList:数组存储,顺序存储结构,优势在于数据的查询
-
Vector: 数组存储,顺序存储结构,优势在于数据的查询
-
LinkedList:链式存储结构,优势在于增删
- HashSet:基于哈希表实现,保证元素不重复,查找速度快。
- TreeSet:基于红黑树实现,自动排序,不允许重复元素。
- HashMap:基于哈希表实现,允许 null 键和 null 值,查找速度快。
- TreeMap:基于红黑树实现,按键的自然顺序排序,或者使用自定义比较器。
-
- Queue:通常用于存储待处理的元素,遵循先进先出 (FIFO) 顺序。常用实现有:
• PriorityQueue
• LinkedList(也可以作为队列使用)
-
- 线程安全与不安全
- 线程安全
- Vector:因为它的方法都是同步的(使用 synchronized 关键字)
- 由于方法同步,Vector 在多线程环境下的性能较低
每次调用 Vector 的方法时都需要获取锁,可能会导致性能瓶颈。
使用场景:适用于需要线程安全的场合,但通常不推荐使用。
- 由于方法同步,Vector 在多线程环境下的性能较低
- Vector:因为它的方法都是同步的(使用 synchronized 关键字)
- 线程不安全
- ArrayList:如果多个线程同时访问并修改同一个 ArrayList,可能会导致数据不一致或抛出异常。
- ArrayList 的读操作性能较好,因为它支持随机访问。
在单线程环境中,ArrayList 的性能优于 Vector,因为没有同步开销。
使用场景:适用于单线程环境或外部使用同步机制的场合。
- ArrayList 的读操作性能较好,因为它支持随机访问。
- LinkedList:与 ArrayList 类似,在多线程环境中需要外部同步。
- 对于插入和删除操作,LinkedList 通常比 ArrayList 更高效,尤其是在列表的中间进行操作时。与 ArrayList 相比,LinkedList 在随机访问时性能较差,因为需要遍历节点。
使用场景:适用于单线程环境或通过外部同步确保线程安全的场合。
- 对于插入和删除操作,LinkedList 通常比 ArrayList 更高效,尤其是在列表的中间进行操作时。与 ArrayList 相比,LinkedList 在随机访问时性能较差,因为需要遍历节点。
- ArrayList:如果多个线程同时访问并修改同一个 ArrayList,可能会导致数据不一致或抛出异常。
- 线程安全
-
Map:键值对集合<key,value>
-
用于存储键值对。每个键只能映射到一个值,但可以有多个键映射到相同的值。常用实现有:
-
key-value 键值对集合,key不能重复。
-
HashMap: 键值都可以为空,线程不安全
-
Hashtable: 键值都不可以为空,线程安全
-
ConcurrentHashMap: 线程安全
-
Properties: 线程安全
-
集合(Collection)遍历
-
Set 遍历
-
forEach (遍历的同时不允许增删)
-
Iterator
-
-
List 遍历
-
for
-
forEach (遍历的同时不允许增删)
-
Iterator/ListIterator
-
集合(Collection)排序:比较器
集合的排序通常涉及使用 Comparator
接口。Comparator
允许你定义自定义的排序逻辑,以便对对象进行比较和排序。
-
内部比较器 Comparable
-
外部比较器 Comparator
TreeSet -> Comparable List -> Comparable / Comparator
集合工具:
-
Collections: 服务 Collection 集合
-
Arrays: 服务数组
泛型
-
定义:参数化类型
拆箱、装箱
拆箱和装箱是与基本数据类型(如 int
, char
, boolean
等)和它们对应的包装类(如 Integer
, Character
, Boolean
等)之间的转换过程。
1. 装箱(Boxing)
装箱是将基本数据类型转换为其对应的包装类对象的过程。Java 会自动完成这个过程,这被称为自动装箱(autoboxing)。
int num = 10; Integer boxedNum = num; // 自动装箱
在这个示例中,int
类型的 num
被自动转换为 Integer
类型的 boxedNum
。
2. 拆箱(Unboxing)
拆箱是将包装类对象转换为相应的基本数据类型的过程。Java 也支持自动拆箱,这称为自动拆箱(unboxing)。
Integer boxedNum = 20; int num = boxedNum; // 自动拆箱
在这个示例中,Integer
类型的 boxedNum
被自动转换为 int
类型的 num
。
使用 Integer
而不是基本数据类型 int
的原因主要涉及到以下几个方面:
1. 对象特性
- 对象与方法:
Integer
是一个类,允许使用对象的方法,比如compareTo()
,toString()
等。这使得它在需要调用方法时更灵活。
2. 与集合框架的兼容性
- 泛型支持:Java 的集合框架只能存储对象,而不能存储基本数据类型。因此,在使用如
List<Integer>
或Map<Integer, String>
这类泛型时,必须使用Integer
。
3. 空值表示
- 处理 null 值:
Integer
可以为null
,而int
不能。这在需要表示缺失值或未初始化状态时非常有用。例如,在数据库操作中,某些字段可能没有值,这时可以用Integer
的null
表示。
4. 自动装箱和拆箱
- 便捷性:Java 提供了自动装箱(将
int
转换为Integer
)和自动拆箱(将Integer
转换为int
)的功能,使得在大多数情况下可以方便地在两者之间切换。