java基础--异常、package


一、异常的概述

异常:就是程序在运行时出现不正常情况

异常由来:问题也是生活中一个具体的事物,也可以通过java的类进行描述,并封装成对象。

对于问题的两种划分:一种是严重问题,一种非严重问题

对于严重的,java通过Error类进行描述,一般不编写针对性的代码对其进行处理

对于非严重的,java通过Exception类进行描述,Exception可以使用针对性的处理方式进行处理。

Error和Exception都是Throwable直接子类

二、异常try-catch

java提供了特有的语句进行处理,如下格式(注意:finally语句可不用)

try

{

        需要被检测的代码

}

catch(异常类  变量)

{

        处理异常的代码

}

finally

{

        一定会执行的代码

}

class Div 
{
	int div(int a,int b)
	{
		return a/b;
	}
}
public class ExceptionDemo
{
	public static void main(String[] args ) 
	{
		try
		{
			Div d = new Div();
			int x = d.div(7,0);/*虚拟机检测到算术异常,并封装成对象
			                     new AritchmeticException(),try检测到
			                     虚拟机抛出的异常对象,就将它传给catch
			                     语句*/		                              
			System.out.println("x = " + x);			
		}
		catch(Exception e)//Exception e = new ArithmeticException()
		{
			System.out.println("0不能作除数");
     		        System.out.println(e.getMessage());//  / by zero
			System.out.println(e.toString());//异常名称 : 异常信息
			e.printStackTrace();/*异常名称,异常信息,异常出现的位置
                                      其实jvm默认的异常处理机制,就是在调用
                                      printStackTrace方法,打印异常的堆栈的跟
                                      踪信息*/
		}
		System.out.println("over");			
	}
}
三、异常声明throws
在上述程序中,调用div(int a,int b)时,参数b若为0,虚拟机就会抛出异常,若不为0,

程序就能顺利通。由于div(int a,int b)存在风险,方法的定义者希望调用者对此进行处

理,可以用throws关键字进行声明,则调用者必须捕捉异常或者抛出异常,一般用上述

程序的try--catch()语句处理异常

/*未对div方法声明的异常进行处理,编译不通过*/
class Div 
{
	int div(int a,int b) throws Exception
	{
		return a/b;
	}
}

public class ExceptionDemo
{
	public static void main(String[] args ) 
	{
		Div d = new Div();
		int x = d.div(7, 1);
		System.out.println("x = " + x);				
		System.out.println("over");			
	}
}
/*main方法将异常抛给虚拟机,编译通过,且div方法的参数b不为0,程序运行正常,
  若参数为0,则程序运行终止,报异常*/
class Div 
{
	int div(int a,int b) throws Exception
	{
		return a/b;
	}
}

public class ExceptionDemo
{
	public static void main(String[] args ) throws Exception
	{
		Div d = new Div();
		int x = d.div(7, 1);
		System.out.println("x = " + x);				
		System.out.println("over");			
	}
}
四、多异常处理
对多异常的处理

1、声明异常时,建议声明更为具体的异常,这样处理得更具体

2、对方声明几个异常,就对应几个catch块。如果多个catch块中的

      异常出现继承关系,父类异常catch块定义在最下面

异常处理的一种方式:将异常信息输出到异常日志文件中

class Div 
{       //声明了两个具体的异常
	int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException
	{
		int[] arr = new int[a]; 
		System.out.println(arr[7]);
		return a/b;
	}
}
public class ExceptionDemo
{
	public static void main(String[] args )
	{
		try
		{
			Div d = new Div();
			int x = d.div(7, 0);
			System.out.println("x = " + x);				
		}	
		catch(ArithmeticException e)
		{
			System.out.println("算术" +e.toString() );
		}
		catch(ArrayIndexOutOfBoundsException e)
		{
			System.out.println("数组角标 " +e.toString() );
		}		
		System.out.println("over");			
	}
}
五、自定义异常
因为项目中会出现特有的问题,而这此问题并未被java所描述封装对象,所以对于

这些特有的问题需,要进行自定义的异常封装。下面程序示例了如何自定义了一个

异常类

/*需求:在本程序中,对于除数是负数的,也视为错误的,无法进行运算,
 * 那么需要对这个问题进行自定义的描述	,就需要自定义一个异常类
 */

//自定义的异常类
class FuSuException extends Exception
{	
}

class Div1
{  
	/*当在方法内部出现了thow抛出的异常对象,必须给出对应的处理动作
	 * 要么在内部try——catch处理;要么在方法上声明让调用者处理
	 */
	int div(int a,int b) throws FuSuException
	{   
		if(b<0)
			throw new FuSuException();//自定义异常虚拟机不认得,需手动抛
		return a/b;
	}
}
public class ExceptionDemo1 {
	public static void main(String[] args) {
		try
		{
			Div1 d = new Div1();				
			int x = d.div(7, -1);
			System.out.println("x = " + x);				
		}
		catch(FuSuException e)
		{
			System.out.println(e.toString());	//只打印出了名称,没有信息	
			System.out.println("除数为负,发生异常");		
		}
	}
}
上述程序中自定义的异常类中,有些地方并不完。当自定义的异常类的对象调用

toString(),只打印了名称,而没有信息,原因是定义类时,没有定义相应的信息,

在throwable体系中,提供了可对异常信息进行赋值的构造方法,直接调用即可

修改如下:

//自定义的异常类
class FuSuException extends Exception
{	
	FuSuException()
	{
	}
	FuSuException(String msg)  //带参构造方法,定义异常信息
	{
		super(msg);
	}	
}

class Div1
{  
	int div(int a,int b) throws FuSuException
	{   
		if(b<0)
			throw new FuSuException("by FuSu");//带参构造方法传入异常信息                            
		return a/b;
	}
}
补充一点,为什么自定义异常必须继Exception?因为Throwable这个体系中的异常类和异常对象都

可抛出,也是这个体系中独有的特点。
六、throws与throw的区别
1、thows使用的在方法上;throw使用在方法内

2、thows后面跟的是异常类,可以跟多个,用逗号隔开;throw后面跟的是异常对象

七、RuntimeException

Exception中有一个特殊的子类异常RuntimeException运行异常。

如果在方法内抛出该异常,方法上不用声明,编译一样通。

如果在方法上声明了该异常,调用者可以不用进行处理,编译一样通过。

像ArithmeticException就是该类的子类,也就具备这样的特性。

class Div2
{
	int div(int a,int b)
	{
		if(b == 0)
		throw new ArithmeticException();//方法内抛出该异常,方法上不用声明,编译通过
		return a/b;
	}
}
public class ExceptionDemo2 {
	public static void main(String[] args) {
		Div2 d = new Div2();				
		int x = d.div(7, 1);
		System.out.println("x = " + x);			
	}
}

class Div2
{       //方法上声明了该异常,调用者可以不用进行处理,编译一样通过
	int div(int a,int b) throws ArithmeticException
	{
		return a/b;
	}
}
public class ExceptionDemo2 {
	public static void main(String[] args) {
		Div2 d = new Div2();				
		int x = d.div(7, 1);
		System.out.println("x = " + x);			
	}
}
自定义异常时:如果该异常的发生,无法再继续运算,就让自定义异常继承RuntimeException
//继承运时异常
class FuSuRunException extends RuntimeException
{	
	FuSuRunException(String msg)
	{
		super(msg);
	}	
}

class Div2
{  
	int div(int a,int b)
	{
		if(b < 0)
			throw new FuSuRunException("除以负数异常!");
		if(b == 0)
			throw new ArithmeticException();//方法内抛出该异常,方法上不用声明,编译通过
		return a/b;
	}
}
public class ExceptionDemo2 {
	public static void main(String[] args) {
		Div2 d = new Div2();				
		int x = d.div(7, -1);
		System.out.println("x = " + x);			
	}
}
八、异常-finally
finally语句放在try-catch处理异常的语句的后面。在finally语句中的代码一定会执行。

通常用于关闭资源,像关闭数据库连接、释放系统资源。

/*
 * 数据库基本操作:
 * 1、连接数据库
 * 2、操作数据
 * 3、断开数据库连接
 */
class DBOperate 
{
	try
	{
		连接数据库;
		数据库操作;
	}
	catch(SQLException e)
	{
	}
	finally
	{
		关闭数据库;		
	}
}
九、异常处理语句的其它格式
格式

try

{

}

finally

{

}

class TryDome
{
	void tryDome() throws Exception //没有catch语句,异常没有处理,
				       //需要声明异常
	{
		try
		{
			throw new Exception();			
		}
		finally
		{
			//一定会执行的代码
		}
	}
}

十、覆盖中异常的特点

异常在子父类覆盖中的体现:
1、子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出

      父类的异常、或者该异常的子类、或者不抛。

2、如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子类,

      包括子类子集,或者不抛。

3、如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,不可以抛出异

      常。如果子类方法发生了异常,就必须要进行try处理,不能抛。

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 //只能抛AException、或BException
				     //不能抛CException
	{		
	}
}

为何子类的覆盖方法,只能抛出父类的异常、或者该异常的子类,不能抛出新类

class FuTest
{
	void function(Fu f)
	{
		try
		{
			f.show();
		}
		catch(AException e)  //只能接收处理AException,或子类。	                                       
		{			
		}
	}
}

public class ExceptionDemo3 {
	public static void main(String[] args)
	{
		FuTest ft = new FuTest();
		ft.function(new Zi());     /*这段代码显示了子类的覆盖方法,只能抛出
                                              父类的异常、或者该异常的子类的原因。因为
                                              function方法里的catch语句只处理AException,
                                              若子类覆盖方法抛出新异常,该function方法无法
                                              无法正常执行*/		
	}
}

十一、练习

/*需求:有一个长方形,可以获取面积,如果出现非法的数值,视为是获取
 * 面积出问题。问题通过异常来表示,对这个程序进行基本设计
 * 
 */
interface shape
{
	public abstract void getArea();
}

class Rec implements shape
{
	private double length;
	private double wide;
	
	Rec(double length,double wide)
	{
		if(length <= 0 || wide <= 0)
		{
			 throw new NotValueException("出现0,或负数的非法值");
		}
		this.length = length;
		this.wide = wide; 
	}
	public void getArea()
	{
		System.out.println(length * wide);
	}
}

class NotValueException extends RuntimeException
{
	NotValueException(String msg) 
	{
		super(msg);
	}
}
public class ExceptionTest1 {
	public static void main(String[] args)
	{
		Rec rec = new Rec(5,3);
		rec.getArea();
		System.out.println("over");
	}
}
十二、package包

什么是包?包类似于一个文件夹,里面存放了一些.class文件。它的一个作用就是对类

文件进行分类管理。同时当我们有两个Demo.class文件时,不采用包机制,将无法准确

位到哪个Demo.class,所以包机制给类提供了多层命名空间,通进包名.类名定位到特定

类。

该如何使用包呢?我们用源文件加命令行的方式看下如何使用包。通过如下如步骤:

一、定义包

在源文件的第一行使用关键字package  包名;这样的格式定义,例如:package pack;

二、编译

javac -d . XXX.java  //在当前的文件夹中新建一个包名命名的文件夹,并将编译产生的

                                 //存在这个文件夹中

三、运行

java 包名.类名  //运行程序


关于包总结起来有下面几点:

  • 对类文件进行分类管理
  • 给类提供多层命名空间
  • 写在程序的第一行
  • 类名的全称是 包名.类名
  • 包也是一种封装形式

十三、包与包之间的访问

包与包进之间进行访问,被访问的包中的类以及类中的成员,需要public修包饰。

不同包中的子类还可以直接访问父类中被protected权限修饰的成员

包与包之间可以使用的权限只有两种,public protected

修饰符的访问权限:

                      public        protected          default         private

同一个类中      yes                 yes                   yes                yes

同一个包中      yes                 yes                   yes        

子类                 yes                 yes

不同包中          yes

package packa;

public class DemoA extends packb.DemoB {
	 public void show()
	 {
		 System.out.println("demoa show run");
		method();		 
	 }
}
package packb;

public class DemoB {
	protected void method() 
	{
		System.out.println("demob method run");
	}
}
package pack;

public class PackDemo {
	public static void main(String[] args)
	{
		packa.DemoA  d = new packa.DemoA();  //不在同一个包中,用类全名
		d.show();
	}
}
十四、import
我们要使用位于其它包中的类时,需要使用类的全名,即包名.类名。为了简化书写,

可用关键字import导入包中的类。导入后,可直接写类名,不用写全名。如下格式:

import 包名.*;     //"*"号是通配符,表导入这个包中的所有类

import 包名.类名;  //导入包中具体的那个类

注意:当导入的不同包中的类,有同名的类,必须使用类全名




























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值