一、异常类
异常处理可以允许我们在程序运行时进行诊断和补救。异常(Exception)不等于错误(Error)
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。此类异常是程序的致命异常,是无法捕获处理的。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。
下图是Error类和Exception类的继承关系。
其中异常分为两个子类:运行时异常(RuntimeException)和非运行时异常(除RuntimeException外的所有异常,如IOException、SQLException等以及用户自定义的Exception异常)
RuntimeException都是非检查型异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,例如数组越界、算数异常等,程序应该从逻辑角度尽可能避免这类异常的发生。下表是RuntimeException及其描述。
非运行时异常类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。下表是 非运行时异常及其描述。
当然,在了解了异常之后,我们要捕获异常并进行一定的处理。
捕获异常常用的方法是try-catch语句。try后是需要检查的语句,catch后是对异常的处理,一般还会在最后加上finally语句,表示最终的处理,无论如何finally语句一定会被执行。
举个例子,现在有一个数组array = {0,1,2,3,4},输入两个数字k和x,将下标为k的数字除以x,最后输出新的数组,代码如下:
package demo;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int[] array = new int[5];
for (int i = 0; i < 5; i ++ ) {
array[i] = i;
}
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int x = sc.nextInt();
try {
array[k] /= x;
} catch (ArithmeticException e) {
System.out.println("除零错误!");
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界!");
e.printStackTrace();
} finally {
for (int i = 0; i < 5; i ++ ) {
System.out.print(array[i] + " ");
}
}
}
}
显而易见,当k > 4 时,数组会越界,而当x = 0 时,会出现算数异常,现在运行一些分别模拟上列情况。
在运行中可见对异常捕获的具体方式,同时也印证了无论是否存在异常,finally语句都会执行。
在捕获完异常后,我们会对异常进行处理。对于非检查型异常的处理方式是修改完善代码逻辑,消除异常,而对于检查性异常,我们会选择抛出异常。
抛出异常的方式有两种:第一种是使用try-catch语句配合throw在函数内抛出,第二种是直接在函数名后添加异常签名抛出。在IDEA中,可以使用Alt + Enter快速选择想要使用的抛出异常的方式。
二、常用类
1.String类
String是Java中使用最广泛的类之一,它的作用是储存字符串,并且String自带许多API,可以方便我们对字符串进行处理。下面是一些常见的API:
length():返回长度
split(String regex):分割字符串
indexOf(char c)、indexOf(String str)、lastIndexOf(char c)、lastIndexOf(String str):查找,找不到返回-1
equals():判断两个字符串是否相等,注意不能直接用==
compareTo():判断两个字符串的字典序大小,负数表示小于,0表示相等,正数表示大于
startsWith():判断是否以某个前缀开头
endsWith():判断是否以某个后缀结尾
trim():去掉首尾的空白字符
toLowerCase():全部用小写字符
toUpperCase():全部用大写字符
replace(char oldChar, char newChar):替换字符
replace(String oldRegex, String newRegex):替换字符串
substring(int beginIndex, int endIndex):返回[beginIndex, endIndex)中的子串
toCharArray():将字符串转化成字符数组
2.Random类
Random类是java.until下的一个根据随机算法的起源数字进行一些变化,从而得到随机数字的方法。主要有以下几种用法:
Random ran = new Random();
//随机生成int取值范围内的数
int num1 = ran.nextInt();
//随机出int类型0~n - 1的数字
int num2 = ran.nextInt(n);
//随机出double取值范围内的数据
double num3 = ran.nextDouble();
//随机出boolean类型的值
boolean bool = ran.nextBoolean();
3.Math类
Math类都是static修饰,直接使用
abs(int a):绝对值
ceil(double d):向上取整
floor(double d):向下取整
max(int a,int b):最大值
pow(double a,double b):a的b次幂
random():随机数[0.0,1.0]
round(float f):四舍五入
sqrt(double d):算术平方根
4.Date类
表示特定的瞬间,精确到毫秒值
构造方法
Date():以当前时间毫秒值创建Date对象
Date(long time):以指定的毫秒值创建Date对象,0:1970:01:01 08:00:00,小时不是0,是因为我们处于东八区
成员方法
long getTime():获取Date对象的毫秒值
setTime(long time):设置Data对象的毫秒值
三、容器
在Java当中,有一个类专门用来存放其它类的对象,这个类就叫做容器,它就是将若干性质相同或相近的类对象组合在一起而形成的一个整体 。
1.List
List容器类似于c++STL中的vector,可以理解为动态数组。
public static void main(String[] args) {
// ArrayList类实现一个可增长的动态数组
List<String> list = new ArrayList<String>();
// 插入元素
list.add("list1");
list.add("list2");
// 打印list的大小
System.out.println(list.size());
// 按索引移除元素
list.remove(0);
// 按对象移除元素
list.remove("list2");
// 打印list的大小
System.out.println(list.size());
// 清空list
list.clear();
}
2.Queue
Queue容器是队列,只能从队尾入,队头出。
//声明一个Queue
Queue<String> q = new LinkedList<String>();
//两种在队尾添加元素的方法
q.add("a");
q.offer("b");
//虽然两个方法都可以实现添加,但是如果队列满的时候,使用add方法时就会报错,而offer方法就不一样了,它在添加失败时不会直接报错,而是会返回false。
//两种删除队头元素的方法
q.remove();
q.poll();
//remove方法和poll方法的区别:当队列为空时 remove() 方法会出现 NoSuchElementException 异常; 而 poll() 只会返回 null。
//两种返回队头元素的方法
q.element();
q.peek();
//当队列为空时,调用element方法会抛出异常,而peek则会返回null。
3.Map
1.Map是一个双列集合,一个元素包含两个值(一个key,一个value)
2.Map集合中的元素,key和value的数据类型可以相同,也可以不同
3.Map中的元素,key不允许重复,value可以重复
4.Map里的key和value是一一对应的。
//创建Map集合对象
Map<String,String> map=new HashMap<>();
//增加元素
map.put("1", "a");
map.put("2", "b");
//根据键删除元素
map.remove("1");
//判断集合中是否包含指定的键返回boolean类型
map.containsKey("2");
//判断集合中是否包含指定的值返回boolean类型
map.containsValue("b");
//判断集合是否为空返回boolean类型
map.isEmpty();
//得到集合的长度
map.size();
//清除所有键值对
map.clear();
四、泛型
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。通俗一点就是可以确定容器中存储数据的类型,防止不同类型的数据存储在同一个容器中。
例如我创建一个字符串类型的ArrayList,当我在队尾添加一个字符串时,可以正常运行,而我添加Int型数字时遍会报错。
而且IDEA明确指出,在String的ArrayList中,不能放int型数据。