Java语言的特点
- 面向对象
- 安全性
-
- Java不支持指针
- Java 的安全措施,比如检查数组越界
- 平台无关性
- 编辑器编译成字节码
- 虚拟机解释字节码执行
- 多线程
- 语言本身提供多线程
- 内存管理
- 垃圾收集
Java语言的运行机制
![](http://sit.uibe.edu.cn/java/slides/ch1/images/mechanism.png)
包(Package)
- 为什么要引入包?
- 一个包
- cn.edu.uibe.oop
- 包对应的路径
- cn/edu/uibe/oop
main方法
- main方法是程序的入口,程序从此开始执行
- main方法是静态的
- 由于Java解释执行时需要指定Main Class,因此程序中可以有main方法,分别声明在不同的类里面
- Java中使用关键字class来声明一个类
public static void main(String[] args){
//程序从此开始执行
}
使用JDK开发第一个Java程序
- 编辑HelloWorld.java
- 使用cmd命令进入DOS命令提示符
- 使用javac命令编译源文件
- 使用java命令解释执行
package cn.edu.uibe.oop;
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
Eclipse开发环境
- 工作空间
- 项目
- 源码文件夹
- 输出文件夹
- Eclipse不使用CLASSPATH环境变量
- 需要设置Java构建路径(Java Build Path)
- 使用Eclipse开发第一个Java
- 新建工作空间(Workspace)
- 新建项目(Project)
- 新建包(Package)
- 新建类(Class)
- 实现main方法(main method)
基本数据类型(Primitive Type)
类型 | 说明 | 长度(bit) | 最小值 | 最大值 | 包装类 |
byte | 字节 | 8 | -128 | 127 | Byte |
char | 字符 | 16 | 0 | 216-1 | Character |
short | 短整数 | 16 | -215 | 215-1 | Short |
int | 整数 | 32 | -231 | 231-1 | Integer |
long | 长整数 | 64 | -263 | 263-1 | Long |
float | 单精度浮点数 | 32 | IEEE754 | IEEE754 | Float |
double | 双精度浮点数 | 64 | IEEE754 | IEEE754 | Double |
void | 空 | - | - | - | Void |
boolean | 逻辑型 | - | - | - | Boolean |
数组的创建
- 在Java中,数组也是对象,是在运行时动态创建的
- 使用new关键字创建数组
- 创建时指定数组的类型和元素个数
int[] nums = new int[20];
String[] names = new String[10];
数组的初始化
- 创建数组时,如果没有指定初始值,数组便被赋予默认的初始值
- 数值型的基本类型默认值为0
- boolean类型默认值为false
- 引用类型默认为null
- 声明数组时给出初始值
- int[] nums = {5,6,8,10,2,1,4,6,9};
- String[] names = {"张三","李四"};
多维数组
- 多维数组是数组的数组
- 高维数组的每个元素为一个低维数组
- Java不要求多维数组的每一维长度相同
int[][] a = new int[3][4];
for(int i=0;i<a.length;i++){
for(int j=0;j<a[i].length;j++){
a[i][j] = i*j;
}
}
面向对象的世界
- 面向对象世界是现实世界的抽象
- 一切都是对象
- 程序是由一组相互发送消息的对象构成的
- 对象具有属性和方法
- 一个对象内部可以有其它对象
- 对象具有类型
- 同类对象能够接收同样的消息
- 封装的目的在于将对象的设计者和使用者分开,使用者不必知道行为实现的细节,只需使用设计者提供的消息来访问对象
类的声明语法
[public] [abstract | final] class 类名称
[extends 父类名称]
[implements 接口名称列表]
{
变量成员声明及初始化;
方法声明及方法体;
}
- class是关键字,表明其后声明一个类
- class前的修饰符可以有多个,用来限制类的访问方式。public说明是公共类,abstract说明是抽象类,final说明是终结类 。
- 类名的命名一般要求多个英文单词首字母大写
- extends说明是从某一个父类派生而来,父类的名字写在extends之后
- implements说明类要实现哪些接口,多个接口用逗号分开
构造方法(Constructor)
构造方法是当对象创建时自动被调用的方法构造方法的主要作用是完成对象的初始化工作
构造方法的名字与类名同名
构造方法没有返回类型(修饰符void也不能有)
构造方法可以接受参数
构造方法通常被声明为公共的(public)
如果一个类没有声明构造方法,编译器会自动为这个类创建一个默认的构造方法
如果一个类声明了构造方法,编译器不会自动为这个类创建默认构造方法
构造方法不能在程序中显示地调用
一个构造方法可以使用this关键字调用另外一个构造方法
在构造方法中,可以使用supper关键字调用父类的构造方法
使用super调用父类构造方法的语句必须作为子类构造方法的第一个语句。
如果在子类的构造方法中,没有显式地调用父类的构造方法,则系统会在执行子类的构造方法前调用父类的默认构造方法(即无参数的构造方法)。
属性的隐藏
- 子类对从父类继承来的属性变量重新加以定义,则从父类继承的属性将隐藏。
- 此时子类拥有两个相同名字的变量,一个继承自父类,另一个是在子类中声明的。
- 在子类中访问这个名称的变量时,访问的是在子类中定义的那个变量,而在父类中定义的那个变量被隐藏了。
- 如果想在子类的方法中访问父类中定义的变量,可以使用“super.变量名”。
- 对于子类对象,用子类的引用访问的时候是访问是的在子类中定义的那个变量;用父类的引用访问的时候访问的是在父类中定义的那个变量。
方法的覆盖(Override)
- 覆盖:子类对从父类继承来的方法重新加以定义,即在子类中声明和父类中某个方法具有相同的方法名和参数表的方法。
- 如果想在子类的方法中调用父类中被覆盖的方法,可以使用“super.方法名”。
- 对于子类对象,无论使用子类的引用还是使用父类的引用来调用被覆盖的方法 ,调用的都是在子类里定义的那个方法。
- 对于子类对象,父类里其它方法调用被覆盖的方法时,调用的也是在子类中定义的那个方法。
- Java是使用动态绑定(后绑定)在运行时动态确定要调用哪个具体方法的。对于子类对象,无论从何处调用,调用的都是子类对象里的方法。
成员变量的默认值
- Java编译器会给类的成员变量默认值
- 在方法内部定义的局部变量用户必须自己初始化
- 默认值列表如下:
数据类型 | 默认值 |
boolean | false |
byte | (byte)0 |
char | '\u0000' |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
reference | null |
this
- this:当前对象的引用
- 在引用一个类的成员变量,this被编译器隐含传递过去
- this的用法
- 返回当前对象的引用
- 从一个构造函数中调用另外一个构造函数
- 区分同名的成员变量和参数变量
包(Package)
- 一个包可以包含若干个类文件,还可包含若干个包
- 类名的空间管理,利用包来划分名字空间,便可以避免类名冲突
- 每个包的名称必须是“独一无二”的
- Java中包名使用小写字母表示
- 命名方式建议将机构的Internet域名反序,作为包名的前导
- 默认包:不含有包声明的编译单元是默认包的一部分
- 为了使用其它包中的类,需要使用import语句引入所需要的类
- Java编译器为所有程序自动引入包java.lang.*
编译单元
- 一个Java源代码文件称为一个编译单元,由三部分组成
- 所属包的声明(省略,则属于默认包)
- import (引入)包的声明,用于导入外部的类
- 类和接口的声明
- 一个编译单元中只能有一个public类,该类名与文件名相同,编译单元中的其他类往往是public类的辅助类,经过编译,每个类都会产一个class文件
- 利用包来划分名字空间,便可以避免类名冲突
类的访问控制
- 类的访问控制只有public(公共类)及无修饰符(缺省类)两种
- public类可以在不同包里的类访问
- 非public类只能被同一个包的类访问
类成员的访问控制
- 共有(public):可以被其他任何对象访问(前提是对类成员所在的类有访问权限)
- 保护(protected):只可被同一包及其子类的对象访问
- 包(package省略):仅允许同一个包内的访问
- 私有(private):只能被这个类本身访问,在类外不可见
类型 | private | package | protected | public |
同一类 | yes | yes | yes | yes |
同一包中的子类 | no | yes | yes | yes |
同一包中的非子类 | no | yes | yes | yes |
不同包中的子类 | no | no | yes | yes |
不同包中的非子类 | no | no | no | yes |
对象销毁
- 对象的引用超出所在的范围就无法访问了
- 我们不必为对象释放存储空间
{ //beginning of scope
String s = new String(“Hello World”);
} //end of scope
//Reference has gone “out of scope”
//but the object itself still exists
垃圾收集(Garbage Collection)
- Java使用垃圾收集器来收集不再使用的对象的存储空间
- 一个对象没有引用指向它的时候被认为是不再使用的
- Java虚拟机自动选择合适的时机进行垃圾收集
- 程序也可以主动调用System.gc()来进行垃圾收集
finalize()方法
- Java中的每个类都有一个finalize()方法用于释放资源
- 在对对象进行垃圾回收前,Java虚拟机会自动调用对象的finalize()方法来释放系统资源
- finalize()方法在类java.lang.Object中声明,但并没有做任何事情。
- 如果一个类需要释放除内存以外的资源,则需要覆盖finalize()方法
继承哪些属性和方法
- 子类都能从父类继承哪些属性和方法呢?
- 子类不能从父类继承构造方法。
- private属性和方法是不能继承的。
- public和protected的属性和方法会被继承。
- 同一个包的子类会继承package属性和方法,不同包的子类不能继承package属性和方法。
private | package | protected | public | |
子类与父类同包 | no | yes | yes | yes |
子类与父类不同包 | no | no | yes | yes |
注:package是指属性或方法前没有访问修饰符。
Object类
- Object类是Java程序中所有类的直接或间接父类,处于类层次的最高点
- 所有其他类都是从Object类派生出来的,Object类包含了所有Java类的公共属性和方法
- Object类中主要有如下方法:
public final Class getClass()
public String toString()
public boolean equals(Object obj)
protected Object clone()
public int hashCode()
protected void finalize() throws Throwable
public void notify()
public void wait()
equals方法
- 如果两个对象具有相同的类型及相同的属性值,则称这两个对象相等(equal)
- 如果两个引用变量指向同一个对象,则称这两个变量同一(identical)
- 如果两个对象同一,则这两个对象肯定相等;反之,如果两个对象相等,则不一定同一
- 使用“==”判断两个对象同一
- 使用equals方法判断两个对象相等
- 覆盖(Override)在Object类里定义的equals方法,来自定义相等的概念。
toString()方法
- System.out.println(obj); 相当于 System.out.println(obj.toString());
- String s=""+obj; 相当于 s=obj.toString();
- 我们可以覆盖toString()方法,此时系统将调用我们实现的toString()方法。
final关键字
- final关键字可以放在变量名、方法、类的前面
- final在不同的上下文环境下用法不同,但都有“最终的”、“不变的”这样的意思
- final放在基本类型变量的前面,说明变量的值不变
- final放在引用类型变量的前面,说明引用变量本身不变
- final放在方法的前面,表示方法不能被覆盖(Override)
- final放在类的前面,表示类不能被继承
最终变量(Final Data)
- 对于基本数据类型的变量,final表示变量的值不能改变
- 对于引用类型的变量,final表示引用变量本身不能改变
- 当被final修饰的引用变量被初始化指向一个对象后,它不能再指向其他对象
- 然而,final引用变量指向的对象是能够被修改的,Java没有提供使得一个对象不变的机制
空白最终变量(Blank Finals)
- Java允许在声明一个final变量的时候不给出初始值,称为空白最终变量
- 空白最终变量提供了灵活地使用final关键字的方式
- 空白最终变量在使用前必须被初始化,定义时不用初始化
最终参数变量(Final Arguments)
- Java允许在参数变量前加上final
- 这意味着在方法内部不能修改final修饰的引用变量指向的对象(不能修改应用的指向)
最终方法(Final Method)
- 在方法前加上final说明这个方法是最终的,即这个方法不能被覆盖(Override)
- 声明一个方法是最终的可以避免子类改变这个方法的含义
- 编译器处理最终方法的调用时可以转换为inline调用,这能提高效率
- 私有方法默认是最终的
最终类(Final Class)
- 如果一个类被final修饰符所修饰和限定,说明这个类不能有子类(派生类)
- final类的存在有以下两个理由:
- 安全方面:阻止黑客通过继承来篡改已有类的功能
- 设计方面:概念上希望声明最终类
抽象类(Abstract Class)
- 抽象类是不能实例化成对象的类
- 当一个类被声明为抽象类时,要在这个类前加修饰符abstract
- 抽象类可以包含常规类能够包含的任何东西
- 抽象类也可以包含抽象方法,这种方法只有声明,没有实现(常规类是不能包含抽象方法的)
- 如果一个抽象类除了抽象方法什么都没有,则使用接口更合适
- 抽象类是用来被继承的,它存在的理由有:
- 抽象类是类层次中较高层次的概括
- 抽象类中可以包括它的所有子类共享的公共属性和公共行为
- 用户生成实例时强迫用户生成更具体的实例,保证代码的安全性
- 用abstract关键字修饰这个类就可以了
abstract class 类的名称{
}
抽象方法
- 抽象方法是在方法声明时加上abstract关键字
- 抽象方法只有声明,没有实现,abstract fun();
- 只有抽象类才能有抽象方法
- 一个抽象类的子类如果不是抽象类,则它必须覆盖父类中的所有抽象方法
接口
- 接口允许设计者规定一个类的基本形式:方法和属性列表,但不给出实现。
- 接口可以实现多重继承功能。
- 没有继承关系的类之间也会存在相同的属性和方法,可以将这些属性和方法组织成接口,需要这些属性和方法的类可以实现这个接口
接口的作用及语法
- 接口可以实现多继承,同时免除C++中的多继承的复杂性。
- 没有继承关系的类之间也会存在相同的属性和方法,可以将这些属性和方法组织成接口,需要这些属性和方法的类可以实现这个接口。
- 面向接口编程:接口定义功能,功能的实现由类来完成,使用者通过接口使用类。(例如JDBC)
- 接口中的方法都是抽象的,这些抽象方法由实现这一接口的不同类来具体完成。
- 接口包含的数据成员为static和final。
[接口修饰符] interface 接口名称 [extends 父接口] {
//方法的原形声明和常量
}
实现接口
- 接口中只有抽象方法,接口不能实例化。
- 必须利用接口的特性来构造新的类,再用它来创建对象,这称为接口的实现。
- 使用implements关键字来实现接口。
- 实现接口的类必须实现接口中的所有方法。
[类修饰符] class 类名称 implements 接口名称列表
{
接口方法的实现;
变量成员声明及初始化;
方法声明及方法体;
}
多重继承
- 多重继承:一个类同时继承自两个以上的父类。
- Java不允许多重继承,一个类只能继承自一个父类。
- Java允许一个类实现多个接口,通过这种机制可以实现多重继承。
- 多个接口用逗号分开。
[类修饰符] class 类名
implements 接口1, 接口2, 接口3, ......
{
接口方法的实现;
变量成员声明及初始化;
方法声明及方法体;
}
接口的继承
- 接口可以通过继承(extends)来派生新的借口。
- 原来的接口称为基本接口(base interface)或父接口(super interface)。
- 派生出的接口称为派生接口(derived interface)或子接口(sub interface)。
- 一个接口可以继承多个接口,这与类的继承不同。
[public] interface extends 父接口1,父接口2, ......{
增加新的常量和方法原形;
}
类型转换的概念
- Java支持隐式(自动)类型转换和显式(强制)类型转换。
- 对象只能够被转换为:
- 任何一个父类类型
- 对象所属类实现的一个接口
- 回到它自己所在的类
- 隐式(自动)类型转换:
- 对于基本数据类型,相容类型之间存储容量低的自动向存储容量高的类型转换
- 对于引用变量,一个类需要转换成更一般的类或接口时,系统自动进行类型转换
- 显示(强制)类型转换:当隐式类型转换不可能时,需要进行显示的类型转换。
- 基本数据类型的类型转换和对象的类型转换不同:
- 对于基本数据类型,是将值从一种形式转换成令一种形式的过程
- 对于对象,实际上并没有进行转换,而仅仅是将对象暂时当成更一般的对象来对待,并没有改变其类型
类型转换的应用
- 赋值转换:在进行赋值运算时,赋值号右边的表达式类型或对象转换为左边的类型。
- 方法调用转换:在进行参数传递时,要将实参的类型转换为形参的类型。
- 算术表达式转换:在进行算术混合运算时,不同类型的项转换为相同的类型再进行运算。
- 字符串转换:在进行字符串连接运算时,其它类型的数据将自动转换为字符串。
- 当一个类的对象转换为父类对象后,它提供的方法会减少。
方法的查找
- 如果类型转换前后的类中都提供了相同的方法,那么通过转换后的引用变量调用这个方法,系统会调用哪一个类的方法呢?(父类的引用指向子类的对象)
- 对于实例方法,调用子类的。
- 对于静态(类)方法,调用引用变量所属类里面的。
多态的概念
- 将同一条消息发给不同的对象时,可能并不知道对象的具体类型是什么,但是采取的行动同样时正确的(不同的对象做出了不同的响应),这种情况称为多态性(Polymorphism)。
- 多态 :统一的接口,不同的响应。
多态的目的
- 通过类型转换,把一个对象当作它的基类对象对待。
- 从相同的基类派生出来的多个派生类可被当作同一个类型对待,可对这些不同的类型进行同样的处理。
- 这些不同派生类的对象响应同一个方法时的行为是有所差别的,这正是这些相似的类之间彼此区别的不同之处。
动态绑定
- 将一个方法调用和一个方法主体连接到一起称为绑定(Binding)。
- 根据绑定的时机不同,可将绑定分为“早期绑定”和“后期绑定”两种。
- 如果在程序运行之前进行绑定(由编译器和链接程序完成),称为早期绑定。
- 如果在程序运行期间进行绑定,称为后期绑定,后期绑定也称为“动态绑定”或“运行时绑定”。
- 在Java中,多态性是依靠动态绑定实现的,即Java虚拟机在运行时确定要调用哪一个同名方法。
多态的应用
- 由于多态性,一个父类的引用变量可以指向不同的子类对象,并且在运行时根据父类引用变量所指向对象的实际类型执行相应的子类方法。
- 利用多态性进行二次分发。(省去参数判断的麻烦,自动调用相应的方法)
- 利用多态性设计回调方法。(大部分时候是设计一个方法给用户去调用,但有时候设计一个类时需要调用用户设计的方法,回调——设计一个类,类有一个方法,使另一个方法调用这个方法,用户的类继承这个类,在用户这个类中实现第一个方法,实际调用时,由于多态会调用用户实现的方法。)
构造方法的调用顺序
- 父类的构造方法先于子类的构造方法被调用,调用是从最上层的父类开始,自上而下,类层次中的每个类的构造方法都会被调用。
- 在子类的构造方法中,可以使用super关键字调用父类的构造方法,必须作为子类构造方法的第一个语句。
- 如果在子类的构造方法中,没有显式地调用父类的构造方法,则系统会在执行子类的构造方法前调用父类的默认构造方法(即无参数的构造方法)。
构造方法中的多态方法
- 如果在构造方法内部调用一个动态绑定的方法,可能造成一些难于发现的程序错误。
- 从概念上讲,构造方法的职责是在创建对象时完成一些初始化工作。一个动态绑定方法的调用会调用位于子类中的一个方法。这种情况下,被调用方法要操作的成员可能不会正确的初始化。
- 在定义构造方法时,遵循以下原则能够有效地避免错误:
- 用尽可能少的动作把对象的状态设置好;
- 如果可以避免,不要调用任何方法;
- 在构造方法中能够安全调用自己所在类里面具有final属性的方法(private方法自动具有final属性),这是由于final方法不能被覆盖。
内部类(Inner Class)
- 将一个类的声明置于另一个类的声明中,称这种类为内部类。
内部类的概念
- 内部类是声明在另外一个类里面的类。
- 利用内部类可以将逻辑上相互联系的类进行分组。
- 利用内部类可以控制一个类在另一个类里的可见性,对于同一个包的其他类来说,内部类能够隐藏起来。
- 使用内部类可以非常方便地编写事件驱动程序。
内部类的声明
- 声明命名内部类:可以在类里面、方法里面、语句块中声明内部类。
- 声明匿名内部类:可以在new关键字后声明内部类,并立即创建一个对象,而不给出类名。
- 假设外层类名为MyClass,内部类名称为C1,则会生成文件MyClass$C1.class;对于匿名内部类,第一个匿名内部类为MyClass$1.class,第二个为MyClass$2.class。
异常的基本概念
- 异常(Exception)又称为例外,是特殊的运行错误对象,对应着Java语言特定的运行时错误处理机制。
- 作为面向对象的语言,异常与其他语言要素一样,是面向对象语言的一部分,是异常类的对象,一场也是一个对象。
- Java中声明了很多异常类,每个异常类都代表了一种运行错误。
- 每当Java程序运行过程中发生一个可识别的运行错误时,系统就会产生一个相应的异常类的对象,即产生了一个异常。
- 一旦一个异常产生了,系统中就要有相应的机制来处理它,从而保证整个程序的安全运行。
- 常见的异常有:空指针异常、被零除异常、数组越界、文件未找到、IO异常、SQL异常等。
Java处理错误的方法
- Java通过面向对象的方法来处理程序错误,为可能发生的非致命性错误设计错误处理模块,将错误作为预定义好的“异常”捕获,然后传递给专门的错误处理模块进行处理。
- 在一个方法中,可以根据特定的条件抛出一个异常对象,并把它交给运行时系统。
- 运行时系统便在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到包含相应异常处理的代码为止,这一个过程称为异常的捕获。
- Java的异常处理机制有以下优点:
- 将错误处理代码从常规代码中分离出来;
- 错误处理代码可以按错误类型进行分组;
- 把错误传递给调用堆栈,可以选择合适的位置捕获异常;
- 克服了传统方法的错误信息(返回值如-1)有限的问题。
错误的分类
- 通常程序中的错误可以分为三种类型,即编译错误、运行错误和逻辑错误。
- 编译错误是编译器能够检测到的错误,一般为语法错误;
- 运行错误是运行时产生的错误,如被零除、数组下标越界等;
- 逻辑错误是机器本身无法检测的,需要人对运行结果及程序逻辑进行认真分析,逻辑错误可能导致运行错误。
- 在Java中,根据错误的严重程度不同,将错误分为两类:
- 错误:是致命性的,即程序遇到了非常严重的不正常状态,不能简单地恢复执行。
-
- Error类是所有错误类的父类,它是Throwable类的子类。
- Error类下的错误都是严重的错误,用户程序无法进行处理。
- 异常:非致命性的,通过某种修正后程序还能继续执行。
- Exception类是所有异常类的父类,它是Throwable类的子类。
- Exception类下的异常又分为两类:检查型异常和非检查型异常。
- 非检查型异常继承自RuntimeException,编译器不检查这类异常;其他异常是检查型异常,对于任何方法,如果它调用的方法抛出一个类型为E的检查型异常,那么调用者就必须捕获E或者也声明抛出E(或者E的一个父类),对此编译器要进行检查。
异常的处理
- 对于检查型异常,Java强迫程序必须进行处理,处理的方式有以下两种:
- 声明抛出异常:不在当前方法内处理异常,而是把异常抛出到调用方法中;
- 捕获异常:使用try、catch和finally构成的语句块,捕获所发生的异常,进行相应的处理。
声明抛出异常
- 如果程序员不想在当前方法内处理异常,可以使用throws语句声明将异常抛出到调用方法中。
- 调用方法也可以将异常再抛给其他调用方法。
- 如果所有的方法都选择了抛出此异常,最后Java虚拟机将捕获它,输出相关的错误信息,并终止程序的运行。
- 在异常被抛出的过程中,任何方法都可以捕获异常并进行相应的处理
捕获异常
- 捕获异常需要使用try、catch、finally构成的语句块。
- try语句块中是可能抛出异常的代码,如果一条语句抛出了异常,其后续语句不会继续执行,而是转到catch进行异常类型匹配。
- catch语句块负责捕获指定类型的异常并进行处理,一般要释放一些资源。
- finally语句块是可选的,一般用于释放资源,无论是否发生异常,finally语句块总会执行。
- 由于继承,在有多个异常需要捕获时,异常类型的顺序很重要,先子类后父类,如Exception异常要放最后。
- getMessage()方法返回一个对发生的异常进行描述的字符串。
- printStackTrace()方法打印方法的调用序列,一直到异常的产生位置。
try{
//可能抛出异常的代码
}catch(ExceptionType1 e1){
//抛出异常ExceptionType1时的异常处理代码
}catch(ExceptionType2 e2){
//抛出异常ExceptionType2时的异常处理代码
}finally{
//无论是否抛出异常,都会执行的代码
}
抛出异常
- 不仅Java系统的类可以抛出异常,用户程序也可以抛出异常。
- 通过throw语句来抛出异常对象。
throw new ExceptionType1();
声明异常类
- 除了使用系统预定义的异常类外,用户还可以声明自己的异常类。
- 用户自定义的异常类必须是Exception的子类。
public class MyException extends Exception{
public MyException(){
super("发生异常了!");
}
}