(一)异常处理
异常的处理方式:
方式一:捕获处理
捕获处理的格式:
try{
可能会发生异常的代码
}catch(异常的类型 变量名){
异常处理代码;
}
捕获处理要注意的细节:
1.如果一个try块的代码出现了异常,经过处理之后,那么try-catch块外面的代码可以正常执行。
2.如果一个try块的代码出现了异常,那么在try块中出现异常的代码后面的所有代码都无法正常执行。
3.一个try块后面可以跟有多个catch块,也就是说一个try块可以捕获多种异常的类型。
4.一个try块后面可以跟有多个catch块,但是捕获的异常类型必须按照从小到大进行捕获,否则后面的没有进行的机会。(是废话,编译出错。)
方式二:抛出处理(关键字:throw throws)
抛出处理要注意的细节:
1.如果一个方法的内部抛出了一个编译时异常对象,那么必须要在方法中声明抛出。
2.如果调用了一个声明抛出编译时异常类型的方法,那么调用者必须要进行处理,否则编译报错。
3.一个方法如果遇到了throw关键字,那么该方法会马上停止执行。
4.一种情况只能抛出一种异常类型。
throw 与throws的区别:
1.throw关键字是用于在一个方法的内部抛出异常对象的,throws是用于在方法上声明抛出异常类型的。
2.throw关键字后面跟的是异常的对象,throws后面跟的是异常的类型。
3.throw关键字一次只能抛出一个异常对象,throws关键字一次可以声明抛出多种异常类型。
什么时候使用抛出处理?什么时候使用捕获处理?
如果需要通知调用者出现异常,使用抛出处理。
如果与用户打交道的代码出现异常,使用捕获处理,千万不能抛出。
例如:
class demo1
{
public static void main(String[] args) //throws Exception//抛出给Java虚拟机处理
{
//main方法调用了声明抛出异常类型的div方法,那么main必须进行处理(捕获处理或抛出处理)
//或者用try-catch自己处理
try{
div(8,2,null);
}catch(Exception e){//捕获后,处理
System.out.println("++++++");
}
System.out.println("========");
}
public static void div(int a,int b,int[] arr)throws Exception,NullPointerException{//方法内部抛出了一个异常对象,必须在方法上声明抛出异常类型
if(b==0){
throw new Exception();//抛出异常对象给调用者div
//System.out.println(">>>>>>>>");//throw后面的语句不可能执行,相当于废话,编译报错
}else if(arr==null){
throw new NullPointerException();
}
int c=a/b;
System.out.println("结果是:"+c);
}
}
Throwable:所有异常与错误的终极父类
Error:错误一般都是由于jvm或者硬件引发的问题,所以一般不会通过代码处理。
Exception:异常 如果程序出现了异常,那么一般就需要通过代码去处理了。
运行时异常 (RuntimeException及其子类) :如果一个方法内部抛出了一个运行时异常对象,那么方法声明可以声明抛出也可以不声明抛出异常类型,如果调用了一个声明抛出运行时异常类型的方法,那么调用者可以处理也可以不处理。
编译时异常 (非运行时异常,受检异常) :如果一个方法内部抛出了一个编译时异常对象,那么方法必须要声明抛出异常类型,如果调用了一个声明抛出编译时异常类型的方法,那么调用者必须要处理。
为什么java编译器对运行时异常管理得如此宽松呢?
因为运行时异常时是可以通过程序员良好的编程习惯避免发生的。
3.自定义异常
自定义一个类继承Exception。
例如:
/*
模拟去吃臭豆腐,带够十块钱,可以吃到香喷喷的臭豆腐,不够就跑出没有带够钱的异常。
*/
class LessMoneyException extends Exception
{
public LessMoneyException(String message){
super(message);
}
}
class demo4
{
public static void main(String[] args)
{
int money;
try{
Choutofu(5);
}catch(LessMoneyException e){
e.printStackTrace();
System.out.println("哎,下次再来,,,");
}
}
public static void Choutofu(int money)throws LessMoneyException{
if(money<10){
throw new LessMoneyException("钱不够,吃不起???");
}else{
System.out.println("臭豆腐真香!!!");
}
}
}
(二)finally块
使用前提:必须要配合try块使用,不能单独使用。
finally块的代码在任何情况下都可以执行,只有在jvm退出的时候不能执行。
try块的表现形式有三种:
方式一:适用于没有资源文件释放,只需要处理异常的代码。
try{
可能发生异常的代码;
}catch(异常类型 e){
异常处理的代码
}
方式二:适用于既有资源释放也需要处理异常的代码。
try{
可能发生异常的代码;
}catch(异常类型 e){
异常处理的代码
}finally{
释放资源的代码;
}
方式三:适用于只需要释放资源文件,不需要异常处理的代码。
try{
可能发生异常的代码;
}finally{
释放资源的代码;
}
例如:
import java.io.*;
class demo6
{
public static void main(String[] args)
{
FileReader fileReader=null;
try{
//第一步找到目标文件
File file=new File("E:\\a.txt");
//第二步:建立文件 与程序的数据输入通道
fileReader=new FileReader(file);
//读取文件数据
int content=0;
while((content=fileReader.read())!=-1){//如果没有读取到文件的末尾就继续读取
System.out.print((char)content);
}
}catch(IOException e){
System.out.println("读取文件失败。。");
}finally{
//可能释放资源失败,表示根本没有权限操作文件,就不用再关了
try{
//关闭资源 (释放资源文件)
fileReader.close();//不管怎样,都会关闭资源
System.out.println("释放资源成功!!");
}catch(IOException e){
System.out.println("释放资源失败!!");
}
}
}
}
(三)包
两个java文件中存在同名的类,那么后编译的class文件会覆盖之前的class文件。
包:java中的包相当于windows中的文件夹。
包的好处:
1.解决类名重复class文件覆盖的问题。
2.方便软件版本的发布。
包语句的格式:
package 包名;
在编译时加上 -d 参数,会新建一个文件夹
格式:
javac -d 存放class文件的路径 java源文件名(.表示当前路径,..是父路径,/是根路径)
包要注意的事项:
1.一个java文件如果有了包语句,那么该类文件的完整类名是“包名+类名”。
2.一个java文件只能有一个package语句。
3.package语句必须位于java文件中的第一个语句。
有了包之后类与类之间的访问:
导包语句的作用:简化书写
导包语句的格式:
import 包名.类名。
注意细节:
1.一个java文件可以出现多个import语句。
2.导包时可以使用*通配符来匹配类名,*可以匹配任何类名。
3.import a.*;该语句不会作用于a包下面的子包。
推荐:不要使用通配符导包,因为结构不清晰。
jvm加载class文件是属于懒惰型加载,只有使用到了该类文件的时候才会被加载到内存。import导包并不会使class文件被加载到内存。
一个类文件被加载到内存的时候,会加载静态代码块的代码。
什么时候需要导包语句呢?
类与类之间的访问,如果两个类不属于同一个包,就要用导包语句。
java.lang包中的类,jvm会自动导入。
包名命名规范:全部小写。
package bb;
import aa.demo10;//导入aa包中的demo10
public class demo9
{
public static void main(String[] args)
{
demo10 c=new demo10();
c.print();
//System.out.println("Hello World!");
}
}
package aa;
public class demo10
{
public void print(){
System.out.println("这是demo10的print方法");
}
}
(四)权限修饰符
访问权限修饰符:用于控制修饰的类、变量、方法的可见范围。
public protected default(表示没有权限修饰符) private (从大到小排序)
同一个类 true true true true
同一个包 true true true false
子父类 true true false false
不同的包 true false false false
注意:在不同包中类与类之间可以访问的权限修饰符只有public protected可以访问,但是protected必须要在
继承关系下才能使用。