------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
异常
一、定义
异常:程序运行时出现的不正常情况。异常由来:Java运用面对对象思想,将程序运行的不正常情况进行描述、封装后,形成的对象。
异常的运用,提高了代码安全性
二、特点
1、将正常流程代码和问题处理代码分离,提高阅读性;2、不同问题用不同的类进行具体描述。如:角标越界、空指针异常等。
3、根据不同的问题分类,建立异常体系。应用原则:看父类定义,建立子类对象。
4、将可抛问题划分为:
a、严重问题,通过Error类进行描述。Error类一般不编写针对性的代码对其进行处理。
b、非严重问题,通过Exception类进行描述。Exception类对其进行针对性的处理。
Throwable
|--Error
|--Exception
可抛性:指所有可以通过关键字:throws和throw操作的类和对象都具有的属性。
PS:
Throwable中的方法:
getMessage():获取异常信息,返回String;
toString():异常名称和异常信息,返回String;
printStackTrace():获取异常名称、信息和出现的位置。它是jvm默认方法。
printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。
三、自定义异常
自定义异常:指将自己操作时所特有的异常进行封装的过程。特点:
1、必须继承异常体系,才能被关键字throws和throw所操作。
自定义类继承Exception或其子类,通过构造函数定义异常信息
Class DemoException extendss Exception
{
DemoException(String msg)
{
super(msg);
}
}
2、通过throw将自定义异常抛出。注意:throw和return一样,它后面的语句执行不到。throws和throw的区别:
a、位置不同:throws使用在函数上;throw使用在函数内。
b、使用格式不同:throws后跟异常类,可以跟多个,用逗号隔开;throw后跟异常对象。
四、异常的分类
1、编译时不被检测的异常(运行时异常):指Exception中的RuntimeException以及其子类RuntimeException:值在处理影响根本计算的传入值错误,而非程序错误时,编译时不声明错误,直接运行停止,迫使调用者更改。
特点:
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过;
如果在函数上声明类该异常,调用者可以不用进行处理。
用法:当异常的发生可能造成运算无法继续时,让自定义异常继承RuntimeException。
/*
RuntimeException:运行时异常。它是Exception中一个特殊的子类异常。
它用于处理影响根本计算的传入值错误,编译时不声明错误,直接运行停止,迫使调用者更改。
*/
//自定义异常要继承异常体系
class FuShuException extends RuntimeException
{
//调用父类功能,接收自定义信息
FuShuException(String msg)
{
super(msg);
}
}
class Demo
{
//因为是运行时异常,不用进行throws NoValueException处理
int div(int a,int b)
{
if(b<0)
throw new FuShuException("出现类除数为负数的情形");
if(b==0)
throw new ArithmeticException("除数为零");
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
//因为是运行时异常,不用进行try/catch操作
Demo d = new Demo();
//传入错误数据
int x = d.div(4,-5);
System.out.println("x="+x);
}
}
输出结果:2、编译时被检测的异常。Exception中除RuntimeException之外的异常。这种异常是可处理的,需要调用者进行修复。
五、对多异常的处理:
1、捕捉方式
格式1:
try{
//需要被检测异常的代码
}
catch(异常类 变量){//该变量用于接收发生的异常对象
//处理异常的代码
}
finally{
//一定会执行的代码,通常用于关闭资源。
}
格式2:
try{} catch(){}
格式3:
try{} finally{}
finally代码块:在异常中定义一定执行的代码。
作用:通常用于关闭资源。
异常中,问题可以在内部解决,就可以不在函数上抛出异常。什么叫问题解决?答:有catch就代表问题解决。
注意:catch用于处理异常。没有catch就代表异常没有被处理;如果该异常是检测时异常,则必须声明。
2、抛出
在类中不做处理,由throws抛出,让虚拟机处理。
3、处理原则
a、声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
b、对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
c、函数内容如果抛出需要检测的异常,要么在函数上声明,要么在函数内用try/catch捕捉。
d、如果调用到声明异常的函数,要么try/catch,要么throws。
e、如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
PS:
1、finally代码块只有一种情况不会执行。就是在其前执行了System.exit(0);
2、try是一个独立代码块,其内定义的变量只作用于内部。
3、建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句 e.printStackTrace(),
也不要简单的就书写一条输出语句。问题处理方法:异常日志。
4、异常在子父类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或该异常的子集。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理,绝对不能抛。
六、应用
/*
需求:
1、获取长方形和圆形面积。
2、自定义面积出现非法的数值时的异常处理。
*/
//用异常描述封装对象 优点:将正常流程代码和问题处理代码分开处理,提高代码阅读性。
class NoValueException extends RuntimeException
{
NoValueException(String message)
{
super(message);
}
}
interface Shape
{
void getArea();
}
//长方形实现形状
class Rec implements Shape
{
private int len,wid;
Rec(int len,int wid)
{
if(len<=0 || wid <=0)
throw new NoValueException("出现非法值");
this.len = len;
this.wid = wid;
}
public void getArea()
{
System.out.println(len*wid);
}
}
//圆的实现形状
class Circle implements Shape
{
private int radius;
//运用final单独定义常量。
public static final double PI = 3.14;
Circle(int radius)
{
if(radius<=0)
throw new NoValueException("非法");
this.radius = radius;
}
public void getArea()
{
System.out.println(radius*radius*PI);
}
}
class ExceptionTest
{
public static void main(String[] args)
{
Rec r = new Rec(3,4);
r.getArea();
Circle c = new Circle(-5);
c.getArea();
System.out.println("over");
}
}
输出结果:包
一、定义
包(package):是一种通过提供多层命名空间,对类文件进行分类管理的工具。作用:进行类组区分,方便对类进行管理;同时包可以将java的类文件和源文件相分离,便于数据分享;
二、特点
1、写在程序文件第一行;因为先有房子,才能放家具。2、类名的全称是 包名.类名;如:创建a包中Demo对象 a.Demo d = new a.Demo();
3、是一种封装形式。包、类、方法都是封装对象,私有并不代表封装,它只是封装的一种形式。
三、格式
1、自动生成包的编译格式:javac -d <目录> 文件名-d <目录> : 指定存放生成的类文件(class文件)的位置
例:javac -d . PackageDemo.java 注意:".":代表当前目录,它前后的空格不可省略。
四、包之间的访问
1、要访问其他包中的类,需要定义类的全称:包名.类名。2、包如果不在当前路径,需要使用classpath设定环境变量,为JVM指明路径。
3、被访问的包中的类权限必须是public的。
4、类中的成员权限:public或者protected。protected(保护):限制访问权限只能是其子类。类公有后,被访问的成员也要公有才可以被访问。
不同包中的子类可以直接访问父类中被protected权限修饰的成员。同一个包中,protected作用只为覆盖。
5、访问四种权限
一个java文件里面,不能出现两个以上的公有类或者接口。因为被public修饰的类名必须与java文件名相同。
五、包的导入(import)
1、可以简化类名。在调用其他包中的类时,需要写类的全称,也就是连同包名一起书写。当类存在多层包中时,
如:haha.hehe.pack.Demo,使用import导入后,使用其类时,就可以不加包名了。
导入格式如:import haha.hehe.pack.Demo;
2、一个程序文件中只有一个package,可以有多个import。import导入的是包中的类,不导入包中的包。3、注意事项:
a、在导入包时,如果包中有很多类,可以使用通配符 *来替代包中的所有类。但是,建议不要使用通配符 * ,因为将不需要使用的类导入后,会占用内存空间。
b、定义包名不要重复,可以使用url来完成定义,url是唯一的。
如:package cn.itheima.Demo。
c、导入的不同包中有相同类时,必须写类的全名以区分,否则将会报错。六、jar包
类越来越多,我们可以用包来装,当包越来越多时,我们可以将包进行压缩。而java中用jar这个工具来对包进行压缩。压缩后的后缀名为jar。jar包的优点:
1、可以将多个包进行压缩到为一个文件。方便项目的携带。
2、方便于使用,只要在classpath设置jar路径,即可以执行jar包中的java程序。
3、数据库驱动、SSH框架等都是以jar包体现的。
jar.exe工具常见命令:
a、创建jar包
jar -cvf mypack.jar packa packb
b、查看jar包
jar -tvf mypack.jar [>定向文件]
c、解压缩
jar -xvf mypack.jar
d、自定义jar包的清单文件
jar –cvfm mypack.jar mf.txt packa packb
PS:
D:\java8\jre\lib\rt.jar java的类库
tools.jar 编译工具类包
src.zip java所有类的源文件
七、应用
package packb;
//包之间访问,被访问的包中的类和方法权限都必须是public。
public class DemoB
{
public void method()
{
System.out.println("demob method run");
}
}
package packa;
//被继承的类要写全称
public class DemoA extends packb.DemoB
{
public void show()
{
System.out.println("demoa show run");
method();
}
}
//建立名为pack的包。一个程序文件中只有一个package,但可以有多个import
package pack;
import packa.*;
import packb.*;
class PackageDemo
{
public static void main(String[] args)
{
/*
//类名全称为:包名.类名
//导入包前写法
packa.DemoA a = new packa.DemoA();
a.show();
*/
//导入后写法
DemoA a = new DemoA();
a.show();
}
}
输出结果:PS:
包常见问题:
1、PackageDemo.java:8: 错误: 找不到符号
DemoA a = new DemoA();
^
符号: 类 DemoA
位置: 类 PackageDemo
错误原因:类名写错
因为类名的全名是: 包名.类名
2、PackageDemo.java:8: 错误: 程序包packa不存在
packa.DemoA a = new packa.DemoA();
错误原因:packa包不在当前目录下,需设置classpath set classpath=目标文件地址
3、PackageDemo.java:8: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行访问
packa.DemoA a = new packa.DemoA();
错误原因:DemoA的访问权限不够(类的权限修饰符有:public default)
有了包,范围变大,一个包中的类要被访问,必须要有足够大的权限,所以被访问的类要被public修饰。
4、PackageDemo.java:9: 错误: show()在DemoA中不是公共的; 无法从外部程序包中对其进行 访问
a.show();
^
错误原因:类公有后,被访问的成员也要公有才可以访问。