NumberFormatException异常
如果我在 Java 中对字符串和数字直接进行类型转换的话,我们有可能会遇到。
在将String字符串转换为数字的时候,如果遇到不能转换的情况
例如:1.将一个不是数字的字符串转换为Integer类型就会出现这个异常,此时我们修改一下字符串为整数即可。
2.另外,不仅仅是输入字符串本身不是数字的问题,有可能输入的字符串可能有一些奇怪的字符,包括有空格,下划线等。
我出现的问题是在结束工作代码,我在兼职集合里面没有对象的情况下去结束兼职,导致我的这一段代码:
long job_time=Long.parseLong(jobtime);
获取到的是null;因此发生了该类异常。
NullPointerException异常
1、字符串变量未初始化
2、接口类型的对象没有用具体的类初始化,比如:
Map map // 会报错
Map map = new Map(); //则不会报错了
3、当一个对象的值为空时,你没有判断为空的情况。
4、字符串与文字的比较,文字可以是一个字符串或Enum的元素,如下会出现异常
String str = null;
if(str.equals(“Test”)){
//这里的代码将不会被触发,因为会抛出java.lang.NullPointerException异常。
}
5、优先使用String.valueOf()方法代替toString()
当程序代码需要对象的字符串表示形式时,请避免使用该对象的toString方法。如果你的对象的引用等于null,NullPointerException则会抛出,使用静态String.valueOf方法,该方法不会抛出任何异常并打印"null"
6、class被声明了类型, 默认 class = null; 这样在调用class中方法的时候系统只能给你个空指针异常, 给其实例化就好了:class = new Class();
7、返回null,方法的返回值不要定义成为一般的类型,而是用数组。这样如果想要返回null的时候就能避免许多不必要的NullPointerException
NullPointerException由RuntimeException派生出来,是一个运行时异常。其意指可能会在运行的时候才会被抛出,一个变量是null,及只有其名,没有实值内容,也没分配内存,当你要去取他的长度,对他进行操作就会出现NullPointException,所以声明变量时最好给它分配好内存空间,给予赋值,例如拿该变量与一个值比较时,要么先做好该异常的处理要么给它进行判断先: if (str !=null && str “”){ …}
判断一个String的实例s是否等于“a”时,不要写成s.equals(“a”),这样容易抛NullPointerException,而写成"a".equals(s)就可以避免这个问题,不过对变量先进行判空后再进行操作更好,尽量避免返回null,方法的返回值不要定义成为一般的类型,用数组。这样如果想要返回null的时候,就返回一个没有元素的数组。就能避免许多不必要的NullPointerException
我的问题时属于第四种,没有对取不到值的异常抛出,也没有做对应处理,这里抛出异常提示要先进行数据的插入。
StreamCorruptedException异常
ObjectOutPutStream源码
protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC);MAGIC:模数
bout.writeShort(STREAM_VERSION);VERSION:版本
}
public void writeShort(int val) throws IOException {
bout.writeShort(val);
}
public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
writeStreamHeader();
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
每次序列化创建 ObjectOutputStream 类的对象时都会在构造器中调用 writeStreamHeader()
方法写入流的信息。
ObjectInputStream源码:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
}
而反序列化创建 ObjectInputStream 类的对象的时候会在构造器中读取流的信息。
我在创建输出流写入对象之后写入一次流信息,再一次创建输出流写入对象,又写入一次流信息,
一共写入了两个流信息。而创建对象输入流时只能读取到第一次写入的流信息,因而在尝试读取第二次追加保存的对象信息时,由于未读取文件中第二次写入的流信息而直接读取对象,从而抛出了异常。
这时我在网上搜索了一下解决方案:
1.不写入新的流信息
2.新建一个自定义的 AppendObjectOutputStream 类,让其继承自 ObjectOutputStream 类,重写父类的 writeStreamHeader() 方法,当创建 AppendObjectOutputStream 类的对象的时候进行判断,以达到文件中只存在一个 StreamHeader 的目的。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* 解决 java.io.StreamCorruptedException: invalid type code: AC 异常
*
* @author Spring-_-Bear
* @version 2021-10-30 21:48
*/
public class AppendObjectOutputStream extends ObjectOutputStream {
/**
* The path of the file
*/
private static File file = null;
public static File getFile() {
return file;
}
public static void setFile(File file) {
AppendObjectOutputStream.file = file;
}
/**
* 调用父类的构造器,初始化父类
*
* @param file
* @throws IOException
*/
public AppendObjectOutputStream(File file) throws IOException {
super(new FileOutputStream(file, true));
}
/**
* 重写父类的 writeSteamHeader() 方法以实现文件中只存在一个StreamHeader
*
* @throws IOException I/O 异常
*/
@Override
public void writeStreamHeader() throws IOException {
// 如果文件为空直接写入 StreamHeader
if (file == null || file.length() == 0) {
super.writeStreamHeader();
} else {
// 文件中存在内容,则说明文件中已经存在了一个 StreamHeader,调用父类的 reset() 方法保证文件中只存在一个 StreamHeader
this.reset();
}
}
}
IOException:是Exception的子类。
I/O:inputstream/outputstream
常常出现的场景:一般在读写数据的时候会出现这种问题。
java内部读写数据实现逻辑:
java内部数据的传输都是通过流,或者byte来进行传递的。
就行一个文本文件。你可以通过in流写入到java中,同时也可以通过out流从java(计算机内存中)返还给具体的文件。
故: IOException是输入或输出异常(即写读异常)。
EOFException异常
表示流异常到底文件末尾。
就像是字节流读到文件末尾返回-1一样,对象流不是返回值,而是直接抛出异常,
所以说这个异常并不是程序错误导致的,而是表示正常读到了文件末尾。
直接异常捕获处理即可。