云霞资讯网

Java代码总出错?编译器防不住运行时漏洞,程序员如何自救.

学Java的人都知道,编完代码不报错才能运行。可有时候程序跑起来还是崩,比如访问空对象或找不到类。这种错编译期根本发现不

学Java的人都知道,编完代码不报错才能运行。可有时候程序跑起来还是崩,比如访问空对象或找不到类。这种错编译期根本发现不了,统称运行时异常。今天说说怎么认清楚这些坑。

Java的异常分为两种,Error和Exception。Error一般是运行时JVM出问题,比如内存不够或者栈溢出。这类问题基本靠改代码结构解决,比如减少递归层数或者加大内存。Exception是程序里的业务错误,比如读文件找不到或者网络中断。

Throwable是所有异常的爹。所有能被抛出的东西都继承它。Exception和Error都是它的孩子。Exception下面分两种,检查型异常和未检查型。检查型必须处理,比如读文件时要用try catch。但像空指针这种未检查型,可以不用处理,但程序照样会崩溃。

处理异常就这几个关键字。throws写在方法后面,告诉外面这个方法可能抛错。throw用来主动抛错。try包着可能报错的代码,catch接住错误。finally不管有没有错都会执行,比如关闭数据库连接。

以前处理资源关闭麻烦。比如读文件要写try catch finally,要是开两个文件就得嵌套两层,代码乱得很。Java7开始支持try with resources,把资源直接写在try后边。这样自动关闭,代码清爽很多。

有个常见的面试题,NoClassDefFoundError和ClassNotFoundException啥区别?前者是编译时能找到类,运行时突然没了,可能是jar包漏了。后者是用反射加载类失败,比如手动调用Class.forName没找到。前者是Error,不用try catch;后者是检查型异常,必须处理。

堆栈溢出经常发生在无限递归。比如写个计数器,忘记改终止条件,栈就会越堆越大,直到崩溃。这时候要么改递归逻辑,要么加参数-Limit调整堆大小。

处理异常有三条铁律。第一别用catch(Exception)一把抓,得具体抓比如IOException。第二别把错误吃了,至少打个日志。第三函数式编程别用检查型异常,否则会影响链式调用。

最近项目遇到个问题,用反射加载第三方类总是报ClassNotFoundException。后来发现依赖jar包没放进lib目录。试了下改成try catch加上日志,再发生错误就能直接看到具体缺少哪个类了。

写代码时多想想哪些地方可能出错。比如文件路径是否正确,数据库连接是否超时。该检查的地方加try catch,资源记得用try with资源。遇到报错先看堆栈,找到具体哪行代码出问题。慢慢积累经验,总能找到解决办法。