首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
编程语言
> 详细
[Java解惑]异常
时间:
2015-01-29 01:21:49
阅读:
278
评论:
0
收藏:
0
[点我收藏+]
标签:
异常
...
17
26.
finally
与中断
...
17
27.
catch
捕获异常规则
...
18
28.
重写时方法异常范围
...
19
29.
静态与非静态
final
常量不能在
catch
块中初始化
...
19
30.
System.
exit
()
与
finally
.
20
31.
递归构造
...
21
32.
构造器中的异常
...
21
33.
StackOverflowError
22
异常
26.
finally
与中断
//
该方法返回
false
static
boolean
f() {
try
{
return
true
;
}
finally
{
return false;
}
}
不要用
return
、
break
、
continue
或
throw
来退出
finally
语句块,并且千万不要允许受检查的异常传播到
finally
语句块之外。也就是说不要在
finally
块内终止程序,而是执行完
finally
块后,要将控制权移交给
try
块,由
try
最终决定怎样结束方法的调用。
对于任何在
finally
语句块中可能抛出的受检查异常都要进行处理,而不是任其传播,下面流拷贝程序在关闭流时没有防止异常的传播,这会有问题:
static
void
copy(String src, String dest)
throws
IOException {
InputStream in =
null
;
OutputStream out =
null
;
try
{
in =
new
FileInputStream(src);
out =
new
FileOutputStream(dest);
byte
[] buf =
new
byte
[1024];
int
n;
while
((n = in.read(buf)) >= 0) {
out.write(buf, 0, n);
}
}
finally
{
//
这里应该使用
try-catch
将每个
close
包装起来
if
(in !=
null
){in.close();}
if
(in !=
null
){out.close();}
}
}
catch
块中的
return
语句是不会阻止
finally
块执行的,那么
catch
块中的
continue
和
break
能否阻止?答案是不会的,与
return
一样,
finally
语句块是在循环被跳过(
continue
)和中断(
break
)之前被执行的:
int
i = 0;
System.
out
.println("--continue--");
while
(i++ <= 1) {
try
{
System.
out
.println("i=" + i);
continue
;
}
catch
(Exception e) {
}
finally
{
System.
out
.println("finally");
}
}
System.
out
.println("--break--");
while
(i++ <= 3) {
try
{
System.
out
.println("i=" + i);
break
;
}
catch
(Exception e) {
}
finally
{
System.
out
.println("finally");
}
}
27.
catch
捕获异常规则
捕获
RuntimeException
、
Exception
或
Throwable
的
catch
语句是合法,不管
try
块里是否抛出了这三个异常。但如果
try
块没有抛出或不可能抛出检测性异常,则
catch
不能捕获这些异常,如
IOException
异常:
public
class
Test {
public
static
void
main(String[] args) {
try
{
//...
}
catch
(Exception e) {
}
catch
(Throwable e) {
}
/* !!
编译出错
try{
//...
}catch (IOException e) {
}
*/
}
}
28.
重写时方法异常范围
重写或实现时不能扩大异常的范围,如果是多继承,则异常取所有父类方法异常的交集或不抛出异常:
interface
I1 {
void
f()
throws
Exception;
}
interface
I2 {
void
f()
throws
IOException;
}
interface
I3
extends
I1, I2 {}
class
Imp
implements
I3 {
//
不能编译通过,多继承时只能取父类方法异常交集,这样就不会扩大异常范围
// !! void f () throws Exception;
// void f();//
能编译通过
//
能编译通过,
Exception
与
IOException
的交集为
IOException
public
void
f()
throws
IOException {
}
}
29.
静态与非静态
final
常量不能在
catch
块中初始化
静态与非静态块中如果抛出了异常,则一定要使用
try-catch
块来捕获。
public
class
Test {
static
final
int
i
;
static
{
try
{
i
=
f
();
}
catch
(RuntimeException e) {
i =
1;
}
}
static
int
f() {
throw
new
RuntimeException();
}
}
上面的程序编译不能通过。表面上是可以的,因为
i
第一次初始化时可能抛出异常,所以抛异常时可以在
catch
块中初始化,最终还是只初始化一次,这正是空
final
所要求的,但为什么编译器不知道这些呢?
要确定一个程序是否不止一次地对一个空
final
进行赋值是很困难的问题。语言规范在这一点上采用了保守的方式。
30.
System.
exit
()
与
finally
try
{
System.
out
.println("Hello world");
System.
exit
(0);
//
或者使用
Runtime
退出系统
// Runtime.getRuntime().exit(0);
}
finally
{
System.
out
.println("Goodbyte world");
}
上面的程序会打印出
"Goodbyte world"
吗?不会。
System.exit
将立即停止所有的程序线程,它并不会使
finally
语句块得到调用,但是它在停止
VM
之前会执行关闭挂钩操作(这此挂钩操作是注册到
Runtime.addShutdownHook
上的线程),这对于释放
VM
之外的资源很有帮助。使用挂钩程序修改上面程序:
System.
out
.println("Hello world");
Runtime.
getRuntime
().addShutdownHook(
new
Thread() {
public
void
run() {
System.
out
.println("Goodbyte world");
}
});
System.
exit
(0);
对象回收时,使用
VM
调用对象的
finalize()
方法有两种:
System.runFinalization()
:该方法让虚拟机也只是尽最大努力去完成所有未执行的
finalize()
终止方法,但不一定会执行。
System.runFinalizersOnExit(true)
:该方法一定会回收,但不安全,已被废弃。因为它可能对正在使用的对象调用终结方法,而其他线程同时正在操作这些对象,从而导致不正确的行为或死锁。
为了加快垃圾回收,使用
System.gc()
,但不一定马上执行加收动作,由虚拟机决定,实质上是调用
Runtime.getRuntime().gc()
。
System
的很多方法都是调用
Runtime
类的相关方法来实现的。
31.
递归构造
public
class
S {
privat
e S instance =
new
S();
public
S() {}
}
如果在程序外面构造该类的实例,则会抛出
java.lang.StackOverflowError
错误。其原因是实例变量的初始化操作将先于构造器的程序体而运行。
32.
构造器中的异常
如果父类构造器抛出了检测异常,则子类也只能抛出,而不能采用
try-catch
来捕获:
public
class
P {
public
P()
throws
Exception {}
}
class
S
extends
P {
public
S()
throws
Exception {
try
{
//
不能在
try
块中明确调用父类构造器,因为构造的
//
明确调用只能放在第一行
// !! super();
//try-catch
不能捕获到父类构造器所抛出的异常,子类只能抛出
}
catch
(Exception e) {
}
}
}
如果初使化实例属性时抛出了异常,则构造器只能抛出异常,在构造器中捕获不起作用:
public
class
A {
private
String str = String.
class
.newInstance();
public
A()
throws
InstantiationException, IllegalAccessException {}
public
A(
int
i)
throws
Exception{
try
{
}
catch
(Exception e) {
}
}
}
33.
StackOverflowError
Java
虚拟机对栈的深度限制到了某个值,当超过这个值时,
VM
就抛出
StackOverflowError
。一般
VM
都将栈的深度限制为
1024
,即当方法调用方法的层次超过
1024
时就会产生
StackOverflowError
。
[Java解惑]异常
标签:
原文地址:http://www.cnblogs.com/jiangzhengjun/p/4257578.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
Spring Cloud 从入门到精通(一)Nacos 服务中心初探
2021-07-29
基础的排序算法
2021-07-29
SpringBoot|常用配置介绍
2021-07-29
关于 .NET 与 JAVA 在 JIT 编译上的一些差异
2021-07-29
C语言常用函数-toupper()将字符转换为大写英文字母函数
2021-07-29
《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
2021-07-28
4-1 YAML配置文件 注入 JavaBean中
2021-07-28
【python】 用来将对象持久化的 pickle 模块
2021-07-28
马拉车算法
2021-07-28
用Python进行冒泡排序
2021-07-28
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!