目录
1、异常机制本质
- 就是当程序出现错误,程序安全退出的机制,Java是采用面向对象的方式来处理异常
- 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE
- 捕获异常:JRE得到该异常后,在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止
- Error:程序无法处理的错误,表示运行应用程序中较严重问题,一般编程操作无法处理
- Exception:程序本身能够处理的异常,如空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算术异常(ArithmeticException)等
- RuntimeException:如被 0 除、数组下标越界、空指针等,通常是由编程错误导致的
- Checked Exception:所有不是RuntimeException的异常的统称,又被称为“已检查异常”,如IOException、SQLException等以及用户自定义的Exception异常。这类异常在编译时就必须做出处理,否则无法通过编译。
2、异常的处理
- 捕捉异常:捕获异常通过3个关键词来实现:try-catch-finally。用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch)并处理它,最后通过finally语句为异常处理提供一个统一的出口,finally所指定的代码都要被执行(catch语句可有多条,finally语句最多只能有一条)。
- 声明异常:在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理,或者当CheckedException产生时,不一定立刻处理它,可以再把异常throws出去。
- 如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。
- 自定义异常:在程序中,可能会遇到JDK提供的任何标准异常类都无法充分描述清楚我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。自定义异常类只需从Exception类或者它的子类派生一个子类即可。
- 自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类。
- 习惯上,自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器:
/**IllegalAgeException:非法年龄异常,继承Exception类*/ class IllegalAgeException extends Exception { //默认构造器 public IllegalAgeException() { } //带有详细信息的构造器,信息存储在message中 public IllegalAgeException(String message) { super(message); } }
3、数组的声明
//创建基本类型一维数组
public class Test {
public static void main(String args[]) {
int[] s = null; // 声明数组;
s = new int[10]; // 给数组分配空间;
for (int i = 0; i < 10; i++) {
s[i] = 2 * i + 1;//给数组元素赋值;
}
}
}
//创建引用类型一维数组
class Man{
private int age;
private int id;
public Man(int id,int age) {
super();
this.age = age;
this.id = id;
}
}
public class Test {
public static void main(String[] args) {
Man[] mans; //声明引用类型数组;
mans = new Man[10]; //给引用类型数组分配空间;
Man m1 = new Man(1,11);
Man m2 = new Man(2,22);
mans[0]=m1;//给引用类型数组元素赋值;
mans[1]=m2;//给引用类型数组元素赋值;
}
}
- 声明的时候数组并没有真正创建,只有在实例化数组对象时,JVM才分配空间
4、数组的初始化
-
静态初始化:在定义数组的同时就为数组元素分配空间并赋值
int[] a = { 1, 2, 3 };// 静态初始化基本类型数组; Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
-
动态初始化:数组定义与为数组元素分配空间并赋值的操作分开进行
int[] a1 = new int[2];//动态初始化数组,先分配空间; a1[0]=1;//给数组元素赋值; a1[1]=2;//给数组元素赋值;
-
默认初始化:数组一经分配空间,其中的元素也按照实例变量同样的方式被隐式初始化
int a2[] = new int[2]; // 默认值:0,0 boolean[] b = new boolean[2]; // 默认值:false,false String[] s = new String[2]; // 默认值:null, null
5、数组的遍历
- 采用一般循环也可以遍历数组,但JDK1.5新增加了for-each循环,专门用于数组遍历:
public class Test { public static void main(String[] args) { String[] ss = { "aa", "bbb", "ccc", "ddd" }; for (String temp : ss) { System.out.println(temp); } } }
- 但是使用该方法遍历数组时无法对元素进行修改
6、数组的拷贝
- System类里包含了static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将src数组里的元素赋给dest数组的元素
- srcpos:指定从src数组的第几个元素开始赋值
- length:指定将src数组的多少个元素赋给dest数组的元素
public class Test {
public static void main(String args[]) {
String[] s = {"A","B","C","D","E"};
String[] sBak = new String[6];
System.arraycopy(s,0,sBak,0,s.length);//数组的拷贝
}
}