学习日志(day18)
方法可变参数
方法可变参数是什么
方法可变参数是指定方法的个数可以变化,个数可以为0或者n个
如何定义方法可变参数
定义方法可变参数
public double method(int ...param){
}
方法可变参数的规则
- 规则1:一个方法只能有一个可变参数
- 规则2:如果一个方法有多个参数,那么可变参数必须定义在最后
public void method(int a,int b,int ...c){
}
- 规则3:方法可变参数本质上是一个数组,因此可变参数可被当作数组来使用
public void method(int ...c){
if(c!=null&&c.length>0){
for(int i=0;i<c.length;i++){
System.out.println(c[i]);
}
}
}
method() 无参调用,method()方法的参数是空指针
method(1,2,3,4,5)传入多个离散值,method()方法参数c是一个数组,传入的参数是数组元素
int [ ] score={3,55,5}
method(score) 传入数组对象,此时method()方法参数c是一个数组
异常
异常的定义
异常(exception),翻译为中文是例外,程序在编译时,或者运行时发生的不寻常的事情。
异常发生后怎么处理
发生异常需要捕获
如果一个程序有异常发生,那么程序就无法正常运行了,会导致程序强行终止运行。当程序发生异常时,我们应该去捕获异常,只要异常被捕获,程序中就没有异常了,就可以继续正常运行了。
异常体系结构
Throwable类
Throwable类是异常体系结构的父类。Throw able类的父类是Object在Throwable下分为两套异常类别,分别为Error和Exception,其中Error是指错误,Exception指的是异常
Error类
Error是指无法通过开发人员编写程序能够解决的异常叫做Error,典型的Error内存溢出、动态连接失败(加载dll文件)、虚拟机错误
Exception类
Exception是所有异常类的父类,这里的异常是指能够通过编写程序处理的异常。Exception类有两套子类,一套是运行时异常,一套是编译时异常。
编译时异常必须捕获,如果不捕获会导致程序无法编译,也就无法运行,例如ClassnotfoundException就是编译时异常。
public static void main(String[] args) {
Class.forName("java.lang.String");//如果不捕获程序就无法运行
}
可以使用try, catch解决
public static void main(String[] args) {
try {
Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
RuntimeException类
RuntimeException类是所有运行时异常的父类
怎么捕获异常
java中有五个与捕获异常相关的关键字,分别是try,catch,finally,throw,throws。这五个异常关键字分成两类处理异常的方式。其中try,catch,finally为一组专门处理异常的方式,其中throw,throws为一组专门处理异常的方式
try,catch,finally异常处理
- 第一种用法
try {
} catch (Exception e) {
e.printStackTrace();
}
- 第二种用法
try {
} catch (Exception e) {
e.printStackTrace();
} finally {
}
- 第三种用法
try {
}finally {
}
- try中用于包裹住可能发生异常的代码
- catch中用于捕获异常,并对异常进行处理
- finally中用于回收资源
- try与catch组合时,一个try可以与多个catch组合,但是catch只有一个
- try与finally组合时,一个try只能与一个finally组合,且try与finally都只能有一个
- try不能单独使用,catch不能单独使用,finally不能单独使用,catch和finally不能组合使用
不捕获异常
public static void main(String[] args) {
int i=1,j=0,res;
System.out.println("begin");
res=i/j;
System.out.println("end");
System.out.println(res);
}
输出了begin,没有输出end,说明程序发生了异常,也没有捕获,提示异常信息为算术异常,除零异常。
使用try和catch捕获异常
public static void main(String[] args) {
try {
int i=1,j=0,res;
System.out.println("begin");
res=i/j;
System.out.println("end");
}catch(Exception e) {
System.out.println("catched");
e.printStackTrace();
}
System.out.println("over");
}
- try中放了可能发生异常的代码
- 如果try中发生了异常,那么程序就会立即被catch捕获,异常被捕获后就没有了,程序就可以继续运行了
- 异常发生后,程序进入catch,导致从异常发生位置开始到catch位置之间的代码无法运行
- 当try中没有发生异常时,程序不会进入到catch中执行
finally
public static void main(String[] args) {
try {
int i = 1, j = 1, res;
System.out.println("begin");
res = i / j;
System.out.println("end");
return;
} catch (Exception e) {
System.out.println("catched");
e.printStackTrace();
} finally {
System.out.println("finally");
}
System.out.println("over");
}
当try中有finally时,finally是必须要执行的
如果没有发生异常,执行顺序是try-finally
如果发生了异常,执行顺序是try-catch-finally
多重catch
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
try {
System.out.println("计算开始");
int i,j,res;
System.out.println("请输入除数");
i=input.nextInt();
System.out.println("请输入被除数");
j=input.nextInt();
res=i/j;
System.out.println(res);
System.out.println("计算结束");
}catch(InputMismatchException e) {
System.out.println("除数和被除数必须是整数");
}catch(ArithmeticException e) {
System.out.println("除数不能为零");
}catch(Exception e) {
System.out.println("其他异常"+e.getMessage());
}finally {
System.out.println("感谢使用本程序");
}
System.out.println("程序结束");
}
一个try可以配置多个catch,但是多个catch是有先后顺序的,必须把子类的catc写在前面,把父类的atch写在后面,并列的catch没有先后顺序。
throw,throws异常处理
throw和throws配合是一套处理异常的方式。两者要配合使用
throws
用于定义在方法声明的后面,表示该方法可能会抛出异常,并告诉主调方法需要处理该方法抛出异常
throws不能单都写一行代码,后面是抛出异常的类型,可抛出多个异常类型,多个之间用逗号隔开。
throw
throw用在方法内部,后面紧跟一个异常对象,表示抛出这个异常
被调方法不处理异常,直接抛给主调方法
public static void main(String[] args) {
try {
divide();
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
public static void divide() throws ArithmeticException{//把异常抛出给主调方法去处理
System.out.println("start");
int i=1,j=0;
int res = i / j;
System.out.println("over");
}
main方法是主调方法
divide是被调方法,被调方法内部发生异常时,被调方法没有处理异常,而是将异常抛给主调方法,由主调方法处理异常。
被调方法抓住异常再次抛该主调方法(常用)
public static void main(String[] args) {
try {
divide();
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
public static void divide() throws ArithmeticException {//把异常抛出给主调方法去处理
try {
System.out.println("start");
int i = 1, j = 0;
int res = i / j;
System.out.println("over");
} catch (Exception e) {
ArithmeticException ex = new ArithmeticException("除零异常");
throw ex;
}
}
- 被调方法先自己处理异常,在抛出异常该主调方法
- 在异常对象的构造函数中输入中文异常描述信息,再将这个异常对象使用throw关键字抛出
- 在主调方法中捕获的异常就是中文信息
自定义异常
java关于一场提供了很多API,如果这些异常API不能满足你的需要,此时你可以自己定义异常类。用于满足自己的业务需求
- 定义异常类,继承Exception或者RuntimeException,继承Exception表示自定义编译时异常,继承RuntimeException表示自定义运行时异常
- 设置异常的描述信息
在Throwable类中定义了描述异常信息的属性,名字是message。可以将自定义异常的描述存储在该属性中。通过构造函数可将异常描述信息传递到throwable中赋值给message属性
public class GenderException extends RuntimeException{
public GenderException(String message) {
super(message);
}
}
class Student{
private String gender;
public String getGender() {
return gender;
}
public void setGender(String gender) {
if ("男".equals(gender)||"女".equals(gender)){
this.gender = gender;
}else {
throw new GenderException("请输入男或女");//抛出异常
}
}
}
class Test{
public static void main(String[] args) {
try{
Student s = new Student();
s.setGender("雌");
}catch (GenderException e){
e.getMessage();
e.printStackTrace();
}
}
}
异常相关的方法
- getMessage() 获取异常描述信息
- printStackTrace()输出异常的堆栈信息
近期评论