天天看点

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

一、内部类

理解:

一个类中又完整的嵌套了另一个类结构,被嵌套的类称为内部类。外面的类称为外部类, 和内部类无关的外部类称为外部其他类。

class A{
	String name;
	public void method(){
		for(){
			int i;
			class B{
				String anme;
			}
		}
	}
}
class Other{

}
           

好处:

可以直接访问外部类中的所有成员,包含私有的!!!
           

分类:

定义在成员位置上:

成员内部类(没有使用static修饰)   √
		静态内部类(使用static修饰)
           

定义在局部位置上:

局部内部类(有类名)
		匿名内部类(没有类名)             √
           

枚举

枚举的理解

枚举其实就是一个类,枚举类的实例是一组限定的对象
           

传统的方式创建枚举 【了解】

对比:单例类

1、构造器私有化
2、本类内部创建对象
3、通过public static方法,对外暴露该对象
           

枚举类

1、构造器私有化	
2、本类内部创建一组对象,添加public static修饰符,直接暴露对象
           

使用enum关键字定义枚举【掌握】

引入:jdk5.0出现的新特性

特点:

1、使用enum关键字代替class关键字
	2、对象(常量)的创建必须放在枚举类中的第一句
	语法:
	对象名(实参列表),对象名(实参列表);
	3、如果是无参构造,则无参构造的定义和实参列表都可以省略
           

介绍枚举类的常见方法【了解】

toString:Enum类已经重写过了,返回的是当前对象的常量名。自定义的枚举类可以继续重写该方法
name:Enum类中的name方法返回的是当前对象的常量名(同toString),但自定义的枚举类不可以继续重写该方法
values:一个静态方法,用于返回指定的枚举类中的所有枚举常量
valueOf:一个静态方法,将一个有效的字符串转换成枚举对象
           

枚举类如何实现接口【掌握】

特点:

1.和普通类实现接口一样,只是允许枚举常量也有自己对抽象方法的特有实现!
2.enum类不能再继承其他类,因为已经隐式的直接继承了Enum类
           

语法:

enum A implements 接口1,接口2{
 		常量1(参数){
 			//抽象方法的实现
 
 		},常量2(参数){
 
  			//抽象方法的实现
 		}
 		//类对抽象方法的实现
 
 }
           

注解

注解的理解

定义:用于修饰java中的数据(属性、方法、构造器、类等),相当于程序中的补充文字。不改变程序的逻辑,但可以被编译器或运行时解析,并做相应处理

内置的三种基本注解【掌握】

@Override:只能用于修饰方法,检测被修饰的方法是否为有效的重写,如果不是,则报编译错误! 

 @Deparecated:用于表明被修饰的数据已经过时,不建议使用,为了新老版本的兼容,没有贸然的废弃,只是提醒!可以用于修饰:

  类或接口、属性、方法、构造、局部变量、包、参数
 
 @Suppresswarnings:用于抑制程序中的编译警告,可以用于修饰类或接口、属性、方法、构造、局部变量、参数
           

自定义注解和使用【了解】

定义注解:

1、定义注解的关键字@interface
  2、注解类体中的成员是:
  	参数类型 方法名();
           

注意:

①参数类型只能是 八大基本类型、String、枚举类、Class类型或上述类型的数组类型
   ②方法名遵循标识符的命名规则和规范,但建议使用value.因为使用时,可以省略方法名
   ③可以在定义方法时,指定默认值,语法:
   参数类型 方法名() default 默认值;
           

使用注解:

在被修饰的数据上方,添加注解即可。语法:
   @注解类型(方法名=值)
           

四种元注解【了解】

Retention:用于指明被修饰的注解可以保留多长
			RententionPolicy:SOURCE  CLASS  RUNTIME
Target:用于指明被修饰的注解可以用于修饰哪些数据
			ElementType:TYPE LOCAL_VARIABLE FIELD METHOD等
Documented:能否在生成的帮助文档中显示
Inherited:注解是否具备继承性
           

常见的运行异常介绍

NullPointerException 空指针异常
	当试图使用null对象的属性或方法时
ArrayIndexOutOfBoundsException 数组下标越界异常
	当试图使用数组的索引超过范围:0——length-1
ClassCastException 类型转换异常
	当试图将不是该类型的实例强转成该类型
ArithmeticException 数学运算异常
	除数为0时
NumberFormatException 数字格式不正确
	当试图将字符串转换成数值时,如果该字符串不是有效的数值格式
           

异常处理的概念

处理程序中发生的不正常现象,称为异常处理
           

##异常处理的分类 ★

方式一:自己处理
try{

	需要检测的代码块
}catch(异常类型 名){

	处理的语句
}


方式二:抛给他人处理
语法:throws
           

内部类详解

一、理解

一个类中又包含了另外一个类结构,其中被包含称为内部类,外面的类称为外部类。其他类称为外部其他类。
           

二、好处

可以直接访问外部类的所有成员,包含私有的
           

三、分类

按定义位置不同:
	定义在成员位置上:
		成员内部类(没有static修饰)
		静态内部类(有static修饰)
	定义在局部位置上:
		局部内部类(有类名)
		匿名内部类(没有类名)
           

四、特点

一)定义在成员位置上

1、可以访问外部类的所有成员。

成员内部类:可以访问所有的

静态内部类:只能访问静态的

2、都可以添加访问修饰符

3、都可以包含 类中的五大成员:属性、方法、构造、初始化块、内部类

成员内部类:只能包含非静态

静态内部类:可以包含所有成员

4、作用域:整个类体中,本类中任意地方可以访问以及外部其他类中可以通过对象或类去访问

5、互访原则

内部类————>外部类:

直接访问

外部类————>内部类:

创建对象去访问

外部其他类——>内部类:

创建对象去访问

成员内部类:Outer.Inner i = new Outer().new Inner();
静态内部类:Outer.Inner i = new Outer.Inner();
           

6、当外部类和内部类的成员重名时,默认访问内部类的成员,如果想访问外部类的成员,可以遵循以下语法

成员内部类:Outer.this.成员

静态内部类:Outer.成员

二)定义在局部位置上

1、可以直接访问外部类所有成员,包含私有的

2、不能加访问修饰符

3、作用域:仅仅在定义它的方法或代码块中,而且遵循前向引用

4、互访原则

内部类——>外部类

直接访问

外部类——>内部类

在作用域内,创建对象去访问

5、当外部类和内部类的成员重名时,默认访问内部类的成员,如果想访问外部类的成员,可以遵循以下语法

Outer.this.成员
           

6、只能访问使用final修饰的局部变量,也就是不能更新该变量

jdk7:需要手动添加final修饰符,否则报错

jdk8:不需要手动添加,隐式添加

7、匿名内部类的语法和应用场景

语法:

new 父类或接口(实参列表) {
	//类体:里面可以包含属性、方法、初始化块、内部类,但不能有构造器和静态成员!
	
}
           

应用场景:

一般作为接口的实例,当做方法的实参!

枚举详解

一、枚举的理解

枚举本质就是一个类,该类的对象是一组有限的特定的值,所以可以认为枚举是常量的集合

二、自定义枚举类 【了解】

class 类名{
	//1.构造器私有化
	private 类名(参数列表){
	}
	//2.本类内部创建对象,并添加public static修饰符,对外暴露该对象
	public static final 类名 对象名1 = new 类名(实参列表);
	public static final 类名 对象名2 = new 类名(实参列表);
	...
}
           

三、使用enum关键字定义枚举 【重点】

jdk5.0出现的新特性:支持enum关键字

语法:

enum 枚举类名{
	对象名1(实参列表),
	对象名2(实参列表);
	private 枚举类名(形参列表){
	...
	}
	private 属性类型 属性名;
}
           

注意:

1、对象的定义必须在类体的第一句
2、如果是无参构造器,那么无参构造器可以省略,并且对象名后面的实参列表也可以省略
3、枚举类中的对象默认的修饰符 就是 public static final
           

四、枚举类的常见方法

使用enum关键字定义的枚举类,默认继承了Enum类,所以具备了Enum类中的所有方法
toString:Enum类重写过toString方法,默认返回当前对象名,子类可以继续重写该方法
ordinal:返回常量的次序号,默认从0开始
name:返回当前对象名,子类不可以重写该方法
values:返回该枚举类所有常量
valueOf:将字符串转换成枚举对象,但要求字符串必须为合法的枚举对象名
compareTo:比较两个对象的次序号
           

五、枚举类实现接口

注意:使用enum关键字定义的枚举类默认继承了Enum,所以不能继承其他类,只能实现接口,而且可以多实现

enum 类名 implements 接口1,接口2{
	对象名(){实现接口中的抽象方法};
	//实现接口中所有的抽象方法
}
           

注解详解

一、注解的理解

jdk5.0出现的新特性。

注解又称为元数据,用于修饰java中的数据(类、属性、方法、构造、包等)。

特点:

1、类似于注释,都是在代码中嵌入补充文字,不改变程序正常的逻辑

2、不同于注释,注解可以在编译时读取,也可以在运行时读取

使用注解:
在被修饰的数据的上方,添加注解类型,语法:@注解类名(name=value)
           

二、内置的三种常见注解

@Override :代表被修饰的方法为有效的重写方法。该注解只能修饰方法
@SuppressWarnings :抑制编译警告,提高代码的整洁性!
@Deprecated:代表被修饰的类或方法等元素为过时的,提高新老版本兼容性
           

三、元注解

概念:用于修饰注解的注解

@Target:代表被修饰的注解,可以用来修饰哪些数据
	ElementType[]:FIELD、METHOD、PACKAGE、TYPE、CONSTRUCTOR、LOCAL_VARIABLE、PARAMETER
@Rentention:代表被修饰的注解,可以保留多久
	RententionPolicy:SOURCE、CLASS、RUNTIME
@Documented:代表被修饰的注解,是否可以在帮助文档中显示
@Inherited:代表被修饰的注解,是否具备继承性
           

四、自定义注解

1、使用@interface定义
2、里面具有方法的定义
	类型 方法名() [default 值];
类型:八大基本数据类型、String类型、枚举、Class类型以及以上类型的数组类型。
           

异常详解

一、异常概念

异常:程序运行时发生的不正常的现象。

二、异常体系图

Throwable

Error:严重的错误
Exception:应用程序最好捕获的异常
	编译异常(受检异常):
		FileNotFoundException
	运行异常(非受检异常):RuntimeException
		NullPointerException空指针异常
		ArithmeticException数学运算异常
		ArrayIndexOutOfBoundsException数组下标越界异常
		ClassCastException类型转换异常
		NumberFormatException数字格式不正确异常
           

常见的运行异常:

NullPointerException空指针异常
		ArithmeticException数学运算异常
		ArrayIndexOutOfBoundsException数组下标越界异常
		ClassCastException类型转换异常
		NumberFormatException数字格式不正确异常
           

一、NullPointerException空指针异常

当试图调用null对象的属性或方法时,或 使用null对象抛出 。示例:throw null

示例:

public class Test{
	public static void main(String[] ags){
		Person[] pers = new Person[2];
		System.out.println(pers[0].com.name.equals("john"));
	}
}
class Person{
	Computer com;
}
class Computer{
	String name;
}
           

技巧:提高容错性

if(name.equals("john")){}建议改成:if("john".equals(name))
           

二、ArrayIndexOutOfBoundsException数组下标越界

当使用数组的下标超出范围时,范围:0——数组.length-1

三、ArithmeticException数学运算异常

当除数为0时

四、ClassCastException类型转换异常

当试图将某对象转换成不是该对象类型的类型时

五、NumberFormatException数字格式不正确异常

当试图将非数值型的字符串转换成数值型时

异常处理

一、使用try catch

语法:

try{
	①
	//可能出现异常的代码②
	③
}catch(异常类型 e){
	//处理语句④
}finally{
	//最后一定要执行的语句 ⑤
}
           

执行顺序:

如果出现异常:①②④⑤

如果没有出现异常:①②③⑤

注意事项:

1、finally可以省略

2、catch可以省略

3、catch可以多个,执行顺序为如果出现异常,则从上往下依次匹配各个异常类型,如果满足,则执行对应catch块的语句。如果都不满足,则抛给jvm打印错误追踪日志!

catch块中如果有父类异常类型放在最后

异常的体会:

1、提高软件的用户体验性

2、不能滥用异常处理。因为try块中的语句过多会影响性能,一般会将可能出现异常的代码才放在try块

3、尽量使用多个catch块代替多个try catch

try{

}catch(){
}catch(){
}catch(){
}
           

4、将正常的代码和容易出错的代码以及解决错误的语句实现了分离!

二、使用throws

语法:

方法声明处,添加显式的抛出异常

public 返回类型 方法名(参数列表) throws 异常类型{

}
           

执行特点:

1、如果方法中出现了异常,则抛给调用方。调用方可以选择继续抛还是自己处理。如果抛给jvm,则jvm必须处理,则打印错误追踪日志!

2、如果程序中出现了异常,而没有发现异常处理语句,则默认使用throws方式

自定义异常

一、语法

1.定义一个类,继承Exception或RuntimeException

如果继承Exception,则为编译异常

如果继承RuntimeException,则为运行异常

2、定义构造器

示例:

class XXException extends Exception{
	public XXException(){}
	public XXException(String s){
		super(s);
	}
}
           

二、如何生成异常对象

1、系统自动生成

针对于系统定义好的异常类

2、手动生成

针对于系统定义好的异常类以及自定义的异常类

throw 异常对象;

throw和throws的区别

一、语法

1.定义一个类,继承Exception或RuntimeException

如果继承Exception,则为编译异常

如果继承RuntimeException,则为运行异常

2、定义构造器

示例:

class XXException extends Exception{
	public XXException(){}
	public XXException(String s){
		super(s);
	}
}
           

二、如何生成异常对象

1、系统自动生成

针对于系统定义好的异常类

2、手动生成

针对于系统定义好的异常类以及自定义的异常类

throw 异常对象;

图解枚举类与注解

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

JDK1.5之前需要自定义枚举类

JDK 1.5 新增的 enum 关键字用于定义枚举类

若枚举只有一个对象, 则可以作为一种单例模式的实现方式

枚举类的属性

枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰

枚举类的使用 private final 修饰的属性应该在构造器中为其赋值

若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数

enum枚举类

必须在枚举类的第一行声明枚举类对象。

枚举类和普通类的区别:

使用 enum 定义的枚举类默认继承了 java.lang.Enum 类
枚举类的构造器只能使用 private 访问控制符
枚举类的所有实例必须在枚举类中显式列出(, 分隔    ; 结尾). 列出的实例系统会自动添加 public static final 修饰
           

JDK 1.5 中可以在 switch 表达式中使用Enum定义的枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字, 无需添加枚举类作为限定

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

枚举类的主要方法:

values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。

valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

和普通 Java 类一样,枚举类可以实现一个或多个接口

若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注解)

Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。

Annotation 可以像修饰符一样被使用, 可用于修饰包,类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在 Annotation 的 “name=value” 对中。

在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替java EE旧版中所遗留的繁冗代码和XML配置等。

基本的 Annotation

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元素

三个基本的 Annotation:

@Override: 限定重写父类方法, 该注解只能用于方法
@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
@SuppressWarnings: 抑制编译器警告
           

自定义 Annotation

定义新的 Annotation 类型使用 @interface 关键字

Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明. 其方法名和返回值定义了该成员的名字和类型.

可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字

public @interface MyAnnotation{
	       String name() default “atguigu";
        }
           

没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation

JDK 的元 Annotation 用于修饰其他 Annotation 定义

JDK5.0提供了专门在注解上的注解类型,分别是:

Retention
Target
Documented
Inherited
           

元数据

String name = “name”;

JDK 的元 Annotation

@Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 @Rentention 时必须为该 value 成员变量指定值:

RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释

RetentionPolicy.CLASS: 编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解。 这是默认值

public enum RetentionPolicy{
SOURCE,
CLASS,
RUNTIME
}
           

RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注释. 程序可以通过反射获取该注释

@Retention(RetentionPolicy.SOURCE)
@interface MyAnnotation1{  }
@interface MyAnnotation2{  }

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{  }
           

@Target: 用于修饰 Annotation 定义, 用于指定被修饰的 Annotation 能用于修饰哪些程序元素. @Target 也包含一个名为 value 的成员变量.

@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.

定义为Documented的注解必须设置Retention值为RUNTIME。
           

@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解

实际应用中,使用较少

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)

Java程序在执行过程中所发生的异常事件可分为两类:

Error: Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。

Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:

空指针访问
试图读取不存在的文件
网络连接中断
           

对于这些错误,一般有两种解决方法:一是遇到错误就终止程序的运行。另一种方法是由程序员在编写程序时,就考虑到错误的检测、错误消息的提示,以及错误的处理。

捕获错误最理想的是在编译期间,但有的错误只有在运行时才会发生。比如:除数为0,数组下标越界等

分类:编译时异常和运行时异常
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

1.运行时异常

是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。
对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
           

2.编译时异常

是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。
对于这类异常,如果程序不处理,可能会带来意想不到的结果。
           

1.运行时异常

是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。
对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
           

2.编译时异常

是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。
对于这类异常,如果程序不处理,可能会带来意想不到的结果。
           

常见异常

java.lang.RuntimeException 
ClassCastException
ArrayIndexOutOfBoundsException
NullPointerException
ArithmeticException
。。。
java.io.IOExeption
FileNotFoundException
EOFException
java.lang.ClassNotFoundException
java.lang.InterruptedException
java.io.FileNotFoundException
java.sql.SQLException
           

例如

public class Test7_1{
    	   public static void main(String[] args) {
      	String friends[]={"lisa","bily","kessy"};
      	for(int i=0;i<5;i++)  {
           		System.out.println(friends[i]);   
         	}
		System.out.println("\nthis is the end");
      }
}
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。过多的分支会导致程序的代码加长,可读性差。因此采用异常机制。

Java异常处理

Java采用异常处理机制,将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁,并易于维护。

Java提供的是异常处理的抓抛模型。

Java程序的执行过程中如出现异常,会生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。

异常对象的生成

由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出
由开发人员手动创建:Exception exception = new ClassCastException();——创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

为保证程序正常执行,代码必须对可能出现的异常进行处理。

如果一个方法内抛出异常,该异常对象会被抛给调用者方法中处理。如果异常没有在调用者方法中处理,它继续被抛给这个调用方法的上层方法。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获(catch)异常。

如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。

程序员通常只能处理Exception,而对Error无能为力。

异常处理是通过try-catch-finally语句实现的。

try{
	......	//可能产生异常的代码
}
catch( ExceptionName1 e ){
	......	//当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e ){
...... 	//当产生ExceptionName2型异常时的处置措施
}  
[ finally{
......	 //无论是否发生异常,都无条件执行的语句
		}  ]
           

try

捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。

catch (Exceptiontype e)

在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。

如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。

比如:可以用ArithmeticException类作为参数的地方,就可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。

捕获异常的有关信息:

与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。

getMessage()   获取异常信息,返回字符串
printStackTrace()  获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

finally

捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。

不论在try代码块中是否发生了异常事件,catch语句是否执行,catch语句是否有异常,catch语句中是否有return,finally块中的语句都会被执行。

finally语句和catch语句是任选的

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念
public class Test7_2{
    	  public static void main(String[] args)    {
     		String friends[]={"lisa","bily","kessy"};
      	try {
      	       for(int i=0;i<5;i++) {
              		System.out.println(friends[i]);
         	       }
      	} 
		catch(ArrayIndexOutOfBoundsException e)  {
                      System.out.println("index err");
      	}
      	System.out.println("\nthis is the end");
       }
}
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

前面使用的异常都是RuntimeException类或是它的子类,这些类的异常的特点是:

即使没有使用try和catch捕获,Java自己也能捕获,并且编译通过  ( 但运行时会发生异常使得程序运行终止 )。
           

如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常

捕获和处理IOException异常

编译、运行应用程序Test7_3.java,体会java语言中异常的捕获和处理机制。

相关知识:FileInputStream类的成员方法read()的功能是每次从相应的(本地为ASCII码编码格式)文件中读取一个字节,并转换成0~255之间的int型整数返回,到达文件末尾时则返回-1。

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

声明抛出异常是Java中处理异常的第二种方式

如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
           

声明抛出异常举例:

public void readFile(String file)  throws FileNotFoundException {
		……
		// 读文件的操作可能产生FileNotFoundException类型的异常
		FileInputStream fis = new FileInputStream(file);
		 ..……
     }
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

重写方法声明抛出异常的原则

重写方法不能抛出比被重写方法范围更大的异常类型。在多态的情况下,对methodA()方法的调用-异常的捕获按父类声明的异常处理。

public class A {
public void methodA() throws IOException {
      ……
}  }
public class B1 extends A {
public void methodA() throws FileNotFoundException {
      ……
}  }
public class B2 extends A {
public void methodA() throws Exception {   //报错
        ……
	}  }
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用人工创建并抛出。

首先要生成异常类对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。

IOException e = new IOException();
throw e;
           

可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:

throw new String("want to throw");
           

Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用人工创建并抛出。

首先要生成异常类对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。

IOException e = new IOException();
throw e;
           

可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:

throw new String("want to throw");
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

一般地,用户自定义异常类都是RuntimeException的子类。

自定义异常类通常需要编写几个重载的构造器。

自定义的异常通过throw抛出。

自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

用户自定义异常类MyException,用于描述数据取值范围错误信息。用户自己的异常类必须继承现有的异常类。

class MyException extends Exception {
   	static final long serialVersionUID = 1L;
	private int idnumber;
 	public MyException(String message, int id) {
		super(message);
		this.idnumber = id;
 	} 
	public int getId() {
		return idnumber;
 	}
}
           
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念
JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

附加:自定义异常处理练习题

实现注册信息验证

要求用户名的长度必须是3位或2位

要求密码的长度必须是6位

要求年龄必须>18并且<60

如果满足条件,则提示注册成功!否则提示异常信息

笔者代码(初学Java,勿喷):

package JavaCoreAPI.Exception;



import java.util.Scanner;

/*
@author 黄佳豪
@create 2019-07-22-17:30
实现注册信息验证

要求用户名的长度必须是3位或2位
要求密码的长度必须是6位
要求年龄必须>18并且<60

如果满足条件,则提示注册成功!否则提示异常信息

*/
@Deprecated
public class Homework1 {
    public static void main(String[] args) throws LoginException {
        Scanner input = new Scanner(System.in);
        String username;
        int password;
        int age;
        while (true) {//用户名判断
            System.out.print("username:");
            username = input.nextLine();
            if (username.length() == 2||username.length() == 3) {
                break;
            }
            //随便写的英语,勿喷
            LoginException loginException = new LoginException("username's lenght must 2 or 3!");
            System.out.println(loginException.getMessage());

        }while (true) {//密码长度判断
            System.out.print("password:");
            password = input.nextInt();
            //将int类型转换成可识别长度的string型
            if (String.valueOf(password).length()== 6) {
                break;
            }
            LoginException loginException = new LoginException("password's length must 6!");
            System.out.println(loginException.getMessage());
        }
        while (true) {//年龄判断
            System.out.print("age:");
            age = input.nextInt();
            if (age > 0 && age <= 120) {
                break;
            }
            LoginException loginException = new LoginException("age length must 0-120 years-old!");
            System.out.println(loginException.getMessage());

        }
        //输出username、password、age到控制台,实际项目中无需该操作
        System.out.println(new LoginVerivication(username,password,age));
    }

}

class LoginVerivication{
    String username;//为简化暂不进行封装
    int password;
    int age;

    public LoginVerivication(String username, int password, int age) {
        this.username = username;
        this.password = password;
        this.age = age;

    }

    @Override
    public String toString() {
        return "LoginVerivication{" +
                "username='" + username + '\'' +
                ", password=" + password +
                ", age=" + age +
                '}';
    }
	}
	//自定义异常
	class LoginException extends Exception {
	    //此处省略serialVersionUID
	    public LoginException(String message) {
	        super(message);
	    }
	}
           

测试运行

JavaSE面向对象:内部类、枚举、注解、异常处理、自定义异常、throw与throws枚举注解常见的运行异常介绍异常处理的概念

继续阅读