java的异常、容器与常用类
1.java的异常
定义:异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通 过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。
常见异常如下:
·在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。
Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):·是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
·这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
Exception(异常):是程序本身可以处理的异常。
·Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和ArrayIndexOutOfBoundException。
另外:异常能被程序本身处理,但是错误不行。
·运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。它的特点是特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
·非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
捕获异常(try、catch以及finally关键词):
1.try-catch语句:
try {
// 可能会发生异常的程序代码
} catch (Type1 id1){
// 捕获并处置try抛出的异常类型Type1
}
catch (Type2 id2){
//捕获并处置try抛出的异常类型Type2
}
例如:
public class TestException {
public static void main(String[] args) {
int x = 1;
int y = 0;
try { // try监控区域
if (y == 0) throw new ArithmeticException(); // 通过throw语句抛出异常
System.out.println("x/y的值是:" + x / y);
}
catch (ArithmeticException e) { // catch捕捉异常
System.out.println("程序出现异常,变量y不能为0。");
}
System.out.println("程序正常结束。");
}
}
------->运行结果:程序出现异常,变量y不能为0。
程序正常结束
2.try-catch-finally语句:
try {
// 可能会发生异常的程序代码
} catch (Type1 x) {
// 捕获并处理try抛出的异常类型Type1
} catch (Type2 y) {
// 捕获并处理try抛出的异常类型Type2
} finally {
// 无论是否发生异常,都将执行的语句块
}
例如:
public class Test {
public static void main(String[] args) {
int i = 0;
String get[] = { " Hello world !", " Hello World !! ",
" HELLO WORLD !!!" };
while (i < 4) {
try {
// 特别注意循环控制变量i的设计,避免造成无限循环
System.out.println(get[i++]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组下标越界异常");
} finally {
System.out.println("--------------------------");
}
}
}
}
输出结果:
Hello world !
--------------------------
Hello World !!
--------------------------
HELLO WORLD !!!
--------------------------
数组下标越界异常
--------------------------
2.容器
定义:在计算机科学中,容器是指实例为其他类的对象的集合的类、数据结构、或者抽象数据类型。换言之,它们以一种遵循特定访问规则的系统的方法来存储对象。容器的大小取决于其包含的对象(或元素)的数目。
潜在的不同容器类型的实现可能在空间和时间复杂度上有所差别,这使得在给定应用场景中选择合适的某种实现具有灵活性。
java内部的容器:
Java内部的容器类主要分为两类:Collection(集合)与Map(图)。
List:
·ArrayList
·实现 List 接口、底层使用数组保存所有元素。
·相当于动态数组,支持动态扩容。
·不同步
Set:
·HashSet
·基于哈希表实现,底层使用HashMap来保存所有元素。
·不能保证迭代顺序
·允许使用null元素
Map:
Map(用于映射(键值对)问题处理)
·HashMap
·HashMap根据键的HashCode来实现,访问速度较快,遍历顺序并不确定。
HashMap最多只允许一条记录的键为null,允许多条记录的值为null。
HashMap线程不安全,也就是说任意时刻可以有多个线程同时写HashMap,所以可能会导致数据的不一致。
·如何确保线程安全?可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
·HashTable
HashTable是遗留类,多数功能与HashMap类似,继承自Dictionary类。
HashTable是线程安全的。也就是说任意时刻只有一个线程能够写HashTable。
HashTable的并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。
LinkedHashMap
基于哈希表和链表实现,借助双向链表确保迭代顺序是插入的顺序。
·TreeMap
基于红黑树实现
默认按照键值得升序进行排序。
在使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,
否则会在运行时抛出java.lang.ClassCastException类型的异常。
3.常用类
1.String类:
创建方式1:赋值常量
String str = “hello”;
使用双引号括起来的内容叫字符串常量值,字符串常量值分配在方法区的常量池中。
常量池的好处:
·节约内存,反复使用,不需要重新分配
·性能高,直接调用,省去创建对象的时间
2.Calendar 类:
日历类可以获得和修改日期的某个部分
创建Calendar对象
Calendar calendar = Calendar.getInstance();
3.Math类:
·较常见的Math类应用:
Math.abs();//获取绝对值函数
Math.sqrt();//开平方
4.Random类:
获得随机数。
Random random = new Random();
random.nextInt(x); //0 ~ x间随机整数(x此处为已知值)
5.Arrays类:
Arrays 类包含用于操作数组的各种方法(例如排序和搜索)。还包含一个静态工厂,允许将数组转为 List。
ListasList(T…a)------>返回由指定数组构造的List
void sort(Object[] a) ------>对数组进行排序
void fill(Object[] a,Object)------>为数组的所有元素都附上相同的值
boolean equals(Object[] a,Object[] a2)------>检查两个数组是否相等
int binarySearch(Object[] a,Object key)------>排序后的数组使用二分法查找数据
6.Date类:
Date 类表示日期和时间,里面封装了操作日期和时间的方法。Date 类经常用来获取系统当前时间。
.
Date()------>构造一个 Date 对象并对其进行初始化以反映当前时间