Java异常
就是程序中出现不正常情况
异常体系:
Throwable
Error
通常出现重大问题如:运行的类不存在或者内存溢出等。
不编写针对代码对其处理。
Exception(异常,可针对性的处理方式进行处理)
在运行时运行出现的一些情况,可以通过try catch finally处理。
Exception和Error的子类名都是以父类名作为后缀。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。
无论Error或Exception都具有一些共性内容。比如:不正常情况的信息,引发原因等。
异常处理:
java提供了特有的语句进行处理
try
{
//需要被检测的代码;
}
catch(异常类 变量)
{
//处理异常的代码; //(处理方式)
}
finally
{
//一定会执行的语句;
}
注:finally除非前面有系统退出【System.exit(0);】否则一定被执行。
eg:
class Demo
{
int div(int a,int b)
{
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d= new Demo();
try
{
int x=d.div(4,0);
System.out.println(“x=”+x);
}
catch(Exception e)
{
System.out.println(“除零了”);
System.out.println(e.getMessage()); //异常信息。
System.out.println(e.toString()); //异常名称:异常信息。
e.printStackTrace();
}
System.out.println(“over”);
}
}
多异常的处理。
1. 声明异常时:建议声明更为具体的异常。这样处理的可以更具体。
eg:throws ArithmeticException,ArrayIndexoutofBoundsException
声明几个,对应几个catch(ArithmeticException e) catch(ArrayIndexoutofBoundsException e)
2. 对方声明几个异常,就对应有几个catch块,不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。【否则执行了Exception e其它的都不执行了】。
建议在进行catch处理时,catch中一定要定义具体处理方式。不要简单定义一句e.printStackTrace(),也不要简单的就书写一条输出语句。
自定义异常:
必须是继承Exception,因为父类中已经把异常信息的操作都完成了。所以子类只要在构造时,将异常信息传递给父类通过super语句。那么就可以直接通过getMessage()方法获取自己定义的异常信息了。
异常体系有一个特点:因为异常类和异常对象都被抛出,他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。只有这个体系中的类和对象,才可以被throws和throw操作。
eg:
<span style="font-size:14px;">class FuShuException extends Exception //自定义的异常类。
{ //如果{}为空,则异常出现时没有异常信息,因为未定义。
private String msg; //定义异常信息,重新写getMessage()。
FuShuException(String msg)
{
this.msg = msg;
}
public String getMessage()
{
return msg;
}
}
/*以上{}中所有代码,可以替换成
FuShuException(String msg)
{
super(msg);
}
*/
</span>
可以替换的原因如下:
Exception的父类Throwable已经做了很多的工作。
class Throwable
{
private String message;
Throwable(String message)
{
this.message=message;
}
public String getMessage()
{
return message;
}
}
class Exception extends Throwable
{
Exception(String message)
{
super(message);
}
}
eg:
除法运算(除数不可以为负)
需求:在本程序中,对于除数是负数,也视为是错误的无法进行运算的。那么就需要对这个问题进行自定义描述。
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
要么:1.在内部try catch处理。2.在函数上声明让调用者处理。
一般情况下,函数内出现异常,函数上需要证明。
class Demo
{
int div(int a,int b) throws FuShuException //声明出来
{
if(b<0)
throw new FuShuException(); //手动通过throw关键字抛出一个自定义异常对象。
//重新定义后()可加上一些文字“出现了除数负”
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d=new Demo();
try
{
int x=d.div(4,-2);
System.out.println(“x=”+x);
System.out.println(“over”);
}
catch(FuShuException e)
{
System.out.println(e.toString());
System.out.println(“除数出现负数了”);
}
}
}
class FuShuException extends Exception
{
FuShuException(String msg)
{
super(msg);
}
}
throws 和throw的区别
1. throws使用在函数上。函数() throws ***Exception {}
throw使用在函数中。(代码)**********; throw new ****Exception;
2. throws 后面跟的异常类,可以跟多个,用逗号隔开。
throw后跟的是异常对象。
Exception中有一个特殊子类:
RuntimeException的子类异常在函数内抛出,不用在函数上声明。如:throw ArithmeticException(“被0除了”);
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修整。
自定义异常时:如果该异常的发生,无法再继续进行运算,就让自定义异常继续RuntimeException。
对于异常分两种:
1. 编译时被检测到的异常。(函数上面要标识的)【抛或者try】
2. 编译时不被检测的异常(运行时异常。RuntimeException以及其子类)。
finally 代码块:定义一定会执行的代码。
通常用于关闭资源(如断开数据库连接)
三种格式:
1> try
{
需要被检测的代码;
}
catch()
{
处理异常的代码;
}
2> try
{
}
catch()
{
}
finally
{
}
3> try
{
}
finally
{
}
记住一点:catch是用于处理异常。如果没有catch就代表异常没有处理过,如果该异常是检测时异常,那么必须声明(必须在函数上声明throws ***)。
异常在子类父类覆盖中的体现:
1. 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
class AException extends Exception
{
}
class BException extends AException
{
}
class CException extends Exception
{
}
class Fu
{
void show() throws AException
{
}
}
class Zi extends Fu
{
void show() throws BException
{
}
}
层级关系:
Exception:
|--AException
|--BException
|--CException
子类只可以抛AException或BException。如果子类真的发生CException,则只可以try,不可以抛。
1. 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
2. 如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类有异常,只可以try处理,不可以抛。
异常的好处:
1. 将问题进行封装。
2. 将正常流程代码和问题处理代码分离。方便阅读。
异常处理原则:
1. 处理方式有两种:try或者throws。
2. 调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应一个catch。
3. 多个catch,父类的catch放到最下面。
4. catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句,也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
try
{
Throw new AException();
}
catch(AException e)
{
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,再抛出和该异常相关的异常。
try
{
Throw new AException();
}
catch(AException e)
{
Throw new BException;
}
或者异常可以处理,但需要将异常产生的和本功能相关的问题提供出去,让调用者知道,并处理。也可以将捕获异常处理后,转换新的异常。
try
{
Throw new AException();
}
catch(AException e) //比如汇款例子,不成功,“钱退回到账户”。提示错误。
{
对AException处理;
throw new BException();
}
包(Package)
对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称是:包名.类名
包也是一种封装形式。
Package pack; //包名都小写。
class PackageDemo
{
public static void main(String() args)
{
System.out.println(“Hello Package!”);
}
}
方式1:
把上述放到一个文件夹中名字:” pack”。
运行javac pack.PackageDemo.java
方式2:
直接:javac –d . PackageDemo.java
.代表当前地址(假设当前地址为:“D:\javaEx\day10”),也可以写成:javac –d D:\javaEx\day10 PackageDemo.java。当然这里可以换成其它地址。
如类在其它位置:
① 运行时要不切刀那个地址;
② 在当前目录调用,则:set classpath=c:\myclass(例:可能是D:、E:),指向包的父目录即可。
不同包中的类如何访问?
包与包之间进行访问,被访问的包中的类以及类中的成员,需要path修饰。
不同包中的子类还可以直接访问父类中被protected修饰的成员。
包与包之间可以使用的权限只有两种:public、protected
权限 public protected default(既类前面什么也不写) private
同一个类中 ok ok ok ok
同一个包中 ok ok ok
子类 ok ok
不同包中 ok
同一个包中的protected修饰的类,子类的同名类覆盖权限必须>=protected才可以。
注:一个java文件中不可以出现2个或以上的public修饰的类或接口。public修饰的类要和文件名同名。
还可以多层包目录:package packa.packb.packc.packd;
/*
为了简化类名的书写,使用一个关键字:import
import导入的是包中的类。建议,不要写通配符*,需要用到包中的哪个类,就导入哪个类(节省内存空间)
*/
eg:
c:\myclass
c:\myclass\packb\packc\DemoA.class
c:\myclass\packb\DemoZ.class
import packb.*; //即packb下所有的类(不包括包)
import packb.packc.*; //即packc下所有的类(不包括包)
import packb.DemoZ; //即只导入packb包下的DemoZ类
如果出现几个包中的类有同名的引用,必须加包名.类名引用
eg: packA.Demo d=new packA.Demo();
packB.Demo k=new packB.Demo();
为了避免包名同名,可以使用url来完成定义,url是唯一的。
eg:package cn.itcast.demo
package cn.itcast.test
Jar包
Java的压缩包
方便项目的携带。
方便于使用,只要在classpath设置jar路径即可。
数据库驱动,SSH框架等都是以jar包体现的。
可以去网上下载一些jar包,然后拿来用。
eg:
c:\myclass 下有两个java包【packa,pack】
如下【dos下】:
c: (进入c盘)
cd myclass
jar -cf haha.jar pack packa
jar -tf haha.jar [查看jar包下的目录]
jar 回车【可查看jar包的各种命令】
如果此时想运行pack包下的JarDemo:
set classpath=c:\myclass\haha.jar
java pack.JarDemo
如果想查看某jar包的信息。
jar –cfv a.jar pack packa (回车)
jar –tvf a.jar (回车)
jar –tvf a.jar >c:\1.txt (回车)//导出信息到1.txt c盘下