一 内部类
Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。
内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。
内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。另外,由于内部类的外嵌类的成员变量在内部类中仍然有效,使得内部类和外嵌类的交互更加方便。
某种类型的农场饲养了一种特殊种类的牛,但不希望其他农场饲养这种特殊种类的牛,那么这种类型的农场就可以将创建这种特殊种牛的类作为自己的内部类。
注意:
内部类对应的字节码文件的名字格式是“外嵌类名$内部类名”,因此,当需要把字节码文件复制给其他开发员时,不要忘记了内部类的字节码文件。
二 匿名类
2.1 和子类有关的匿名类
Java允许我们直接使用一个类的子类的类体创建一个子类对象。
创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类。
假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类)创建对象:
new Bank () {
匿名类的类体
};
2.2 和接口有关的匿名类
假设Computable是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
下列代码就是用实现了Computable接口的类(匿名类)创建对象:
new Computable() {
实现接口的匿名类的类体
} ;
如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给方法的参数,类体必须要重写接口中的全部方法。
例如,对于void f(ComPutable x)
其中的参数x是接口,那么在调用f时,可以向f的参数x传递一个匿名对象,例如:
f(new ComPutable() {
实现接口的匿名类的类体
})
三 异常类
异常:阻止当前方法或作用域继续执行的问题,称之为异常
5.1 异常分类
1.Java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;
2.其中Error类中包括虚拟机错误(VirtualMachineError)和线程死锁(ThreadDeath),一旦Error出现了,程序就彻底的挂了,被称为程序终结者;
3.Exception类主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类,非检查异常(RuntimeException)和检查异常(其他的一些异常)
4.RuntimeException异常主要包括以下四种异常:空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算术异常(ArithmeticException)。
5.其他异常 (检查异常)、文件异常(IOException)、SQL异常(SQLException)
5.2 处理异常
a、 try-catch 以及 try-catch-finally(最终将要执行的代码)
b、 try-catch-catch用于多个异常处理(先子类异常后写父类异常)
c、抛出异常
d、 自定义异常
e、 异常链
5.3 Throwable 类
java.lang.Throwable Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。
两个子类的实例,Error 和 Exception,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中新近创建的,因此包含了相关的信息(比如堆栈跟踪数据)。
5.4 return在try-catch-finally中
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的;详细见这篇文章当try、catch中有return时,finally中的代码会执行么?
4、finally中也可以包含return,最终返回值就会变成finally中return返回的值
其他注意事项:
1.e.printStackTrace()可以输出异常信息
2.-1为抛出异常的习惯写法
3.如果方法中try,catch,finally中没有返回语句,则会调用这三个语句块之外的return结果
4.finally块无论如何,不管前面是正常还是异常,都要执行。
5.finally 在try中的return之后 在返回主调函数之前执行。
5.5 Java中的异常抛出以及自定义异常
5.5.1 Java中的异常抛出
throw——将产生的异常抛出(动作)
throws——声明将要抛出何种类型的异常(声明)
public void 方法名(参数列表)throws 异常列表{
//调用会抛出异常的方法或者:
throw new Exception();
}
5.5.2 自定义异常
class 自定义异常类 extends 异常类型{
//构造器
public 自定义异常类(String message){
super();//继承父类的构造方法
}
}
5.6 异常链
e.printstackrace();在命令行打印异常信息在程序中出错的位置及原因
.initcause();新的异常包含所有异常信息,可以抛出一个统一的异常,便于追究bug
public void test2(){
try {
test1();
} catch (DrunkException e) {
// TODO Auto-generated catch block
RuntimeException newExc =
new RuntimeException(e);
// newExc.initCause(e);//和上面把e传进去类似,用于初始化异常原因
throw newExc;
}
}
}
异常链:一个导致另一个 ,根据异常追查发生异常的最初位置
5.7 java 异常总结
JAVA中的异常处理是通过5个关键字来实现的:try catch finally throw throws
try:当某段代码执行过程中,可能会发生异常的话,我们应该把这段代码放进try语句块中
catch:在catch语句块中捕获异常。catch语句块的参数类似于方法的声明,包含一个异常类型和异常对象。异常类型一般是java.lang.Exception类或者它的子类。
finally:无论是否产生异常,finally所指定的代码都要执行。通常在finally语句块中可以进行资源清理工作,如关闭打开的文件等。
throw:总是出现在方法体中,用来抛出一个异常。
throws:总是出现在方法的声明中,用来表明该方法可能抛出的各种各样的异常。
try-catch程序块中的执行流程以及执行的结果是比较简单的,首先执行的是try语句块中的语句。这时可能会有以下3种情况:
(1)如果try语句块中的所有语句都正常执行完毕,那么catch块中的所有语句都会被忽略。
(2)如果try语句块中在执行过程中碰到异常,并且这个异常与catch中声明的异常类型相匹配。那么在try块中剩余的代码都将被忽略。而相应的catch块都将被执行。通过异常对象的printStackTrace()方法可以得到异常的堆栈信息。
(3)如果try语句块在执行过程中碰到异常,而抛出的异常在catch块里面没有被声明,那么方法立刻退出。
try-catch-finally块的执行流程大致分为两种情况:
(1)如果try块中所有语句正常执行完毕。那么finally块就会被执行。
(2)如果try块中所有语句碰到了异常,那么finally块中的语句也会被执行。
多重catch块一段代码可能会引发多种类型的异常。这时,我们可以在一个try语句块后紧跟多个catch语句块,分别处理不同的异常。
这里,需要注意的是:多个catch块中处理的异常类型必须是从特殊到一般,最后一个一般是Exception类
实际应用中的经验与总结
1.处理运行时异常时,采用逻辑规避同时辅助try-catch处理
2.在多重catch块后面,可以加上一个catch(Exception)来处理被遗漏的异常
3.对于不确定的代码,也可以加上try-catch,处理潜在的异常
4.尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出
5.具体如何处理异常,要根据不同的业务需求和异常类型去决定
6.尽量添加finally去释放占用的资源
//因为continue不影响switch,因此影响到外面的循环,continue的意思就是,本次循环不再执行下去,直接跳到下一个循环,break用于结束当前循环或switch语句,switch语句是一个类似于if-else语句的判断条件而并非循环
5.8常见异常及处理方法
四 断言
断言语句用于调试代码阶段。在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程又需要调试,可以重新启用断言语句。
使用关键字assert声明一条断言语句,断言语句有以下两种格式:
assert booleanExpression;
assert booleanExpression:messageException;
注意:当Java解释器直接运行程序时,默认关闭断言语句,在调试程序时可以使用-ea启用断言语句,例如:
java -ea mainClass