1.PrintWriter
PrintWriter是具有自动行刷新的缓冲该字符输出流
1.1 构造方法
PrintWriter(File file)
PrintWriter(String fileName)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFlush)
PrintWriter(Writer writer)
PrintWriter(Writer writer,boolean autoFlush)
其中参数为OutputStream与Writer的构造方法提供了一个可以传入boolean值参数,该参数用于表示PrintWriter是否具有自动行刷新
1.2 print和println方法
PrintWriter提供了若干重载的print与println方法,其中println方法是在写出数据后自动追加一个系统支持的换行符(使用PrintWriter写出字符串时我们通常不使用Writer提供的write()相关方法)
void print(int i)//打印整数
void print(char c)//打印字符
void print(boolean b)//打印boolean值
void print(char[] c)//打印字符数组
void print(double d)//打印double值
void print(float f)//打印float值
void print(long l)//打印long值
void print(String str)//打印字符串
println方法,参数与上面相同
通过println方法写出的内容都会被实际写出,print方法写出的内容会进行缓存,所以一般使用println写
代码演示
/**
* 直接使用PW写
*/
public class PrintWriter_println {
public static void main(String[] args) throws IOException {
/*
* PW提供了很多构造方法,其中有直接对文件
* 写操作的构造方法:
* PrintWriter(String path)
* PrintWriter(File file)
*
* 可以使用重载构造方法指定字符集
* PrintWriter(String path,String charsetName)
* PrintWriter(File file,String charsetName)
*/
PrintWriter pw = new PrintWriter("pw.txt","UTF-8");
pw.println("夜空中最亮的星,");
pw.println("能否听清,");
pw.println("那仰望的人心底的孤独和叹息。");
System.out.println("写出完毕!");
pw.close();
}
}
/**
* 在流连接中使用PrintWriter
*
*/
public class PrintWriter_println2 {
public static void main(String[] args) throws IOException {
PrintWriter pw
= new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("pw2.txt"),"UTF-8"
)
);
pw.println("你好!");
pw.println("再见!");
System.out.println("写出完毕!");
pw.close();
}
}
2.BufferedReader
BufferedReader是缓冲字符输入流,其内部提供了缓冲区,可以提高读取效率
2.1 BufferedReader的常用构造方法
BufferedReader(Reader reader)
2.2 使用BufferedReader读取字符串
String readLine() 连续读取一行字符串,直到读取到换行符为止,返回的字符串中不包含该换行符。若EOF则该方法返回null
代码演示
/**
* java.io.BufferedReader
* 缓冲字符输入流
* 可以按行读取字符串
*
*/
public class BufferedReader_readLine {
public static void main(String[] args) throws IOException {
/*
* 将当前源代码输出到控制台
*/
FileInputStream fis
= new FileInputStream(
"."+File.separator+
"src"+File.separator+
"day08"+File.separator+
"BufferedReader_readLine.java"
);
InputStreamReader isr
= new InputStreamReader(fis);
BufferedReader br
= new BufferedReader(isr);
/*
* BufferedReader提供了读取一行字符串的方法:
* String readLine()
* 该方法会顺序读取若干字符,直到读取了换行符
* 为止,然后将换行符之前的所有字符以一个字符串
* 形式返回。
* 若返回值为null,则表示文件末尾
*/
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
3.异常处理
3.1 异常处理机制
当程序中抛出一个异常后,程序从程序中导致异常的代码处跳出,java虚拟机检测寻找和try关键字匹配的处理该异常的catch块,如果找到,将控制权交到catch块中的代码,然后继续往下执行程序,try块中发生异常的代码不会被重新执行。如果没有找到处理该异常的catch块,在所有的finally块代码被执行和当前线程的所属的ThreadGroup的uncaughtException方法被调用后,遇到异常的当前线程被中止
3.2 异常的捕获和处理
Java异常结构中定义有Throwable类,Exceotion和Error是其派生的两个子类
Exception表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常,这类异常是可以通过Java异常捕获机制处理的
Error表示Java运行时环境出现的错误,例如:JVM内存溢出等
3.3 使用try-catch
try {…} 语句指定了一段代码,该段代码就是一次捕获并处理例外的范围。在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句分别对这些异常做相应的处理(如果没有列外产生,所有的catch代码段都被略过不执行)
在catch语句块中是对异常进行处理的代码
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常 (catch捕获的异常类型由上至下的捕获异常类型的顺序应是子类到父类的)
代码演示
public class Exception_try_catch {
public static void main(String[] args) {
System.out.println("程序开始了");
try{
String str = "a";
System.out.println(str.length());
System.out.println(str.charAt(0));
System.out.println(Integer.parseInt(str));
//try块中出错的代码以下内容都不在运行
System.out.println("!!!!!");
}catch(NullPointerException e){
System.out.println("出现了空指针!");
}catch(StringIndexOutOfBoundsException e){
System.out.println("字符串下标越界了!");
/*
* catch可以定义多个,根据不同异常有不同处理
* 办法时,应当分别捕获这些异常。
* 但应当养成一个好习惯,在最后catch最大的异常
* Exception,这样可以避免因为代码抛出一个未知
* 的异常导致程序中断。
* 当捕获的异常存在继承关系时,应当将子类异常
* 在上先行捕获,父类异常在下。
*/
}catch(Exception e){
System.out.println("反正就是出了个错!");
}
System.out.println("程序结束了");
}
}
3.4 finally的作用
finally语句为异常处理提供一个统一的出口,无论try所指定的程序块中是否抛出例外,finally所指定的代码都要被执行(通常在finally语句中可以进行资源的消除工作,如关闭打开的文件、删除临时文件等)
注:finally语句块只能定义在try语句块之后,或者最后一个catch语句块之后,且只能定义一次
3.5 throw关键字
当程序发生错误而无法处理的时候,会抛出对应的异常对象,除此之外,在某些时刻,您可能会想要自行抛出异常,例如在异常处理结束后,再将异常抛出,让下一层异常处理区块来捕捉,若想要自行抛出异常,您可以使用“throw”关键词,并生成指定的异常对象
throw new ArithmeticException()—代码中一般写 throw e;
3.6 throws关键字
程序中会声明许多方法(Method),这些方法中可能会因某些错误而引发异常,但您不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理,这时候您可以使用“throws”关键词来声明这个方法将会抛出异常
public static void show(String str) throws Exception{}
3.7 重写方法时的throws
当使用继承时,在父类的某个方法上声明了throws抛出某些异常,而在子类中重写该方法时,可以做以下的操作:
不处理异常(重写方法时不声明throws)
可仅在throws中声明父类中声明的部分异常
可在throws中声明父类方法中抛出的异常的子类异常
4.Java异常API
4.1 RuntimeException
Java异常可以分为可检测异常,非检测异常
可检测异常:可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译
非检测异常:非检测异常不遵循处理或者声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已经解决了这样一个异常
(RuntimeException 类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在java应用程序中会频繁出现。因此它们不受编译器检查与处理或声明规则的限制 )
4.2 常见RuntimeException
IllegalArgumentException
抛出的异常表明向方法传递了一个不合法或不正确的参数
NullPointerException
当应用程序试图在需要对象的地方使用 null 时,抛出该异常
ArrayIndexOutOfBoundsException
当使用的数组下标超出数组允许范围时,抛出该异常
ClassCastException
当试图将对象强制转换为不是实例的子类时,抛出该异常
NumberFormatException
当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常
5.序列化/反序列化流
序列化:将对象中的信息完整的存储下来的过程 (存到硬盘上–持久化)
注意:
5.1 一个对象要想被序列化,这个对象对应的类必须实现一个接口,Serializable 这个接口中没有任何方法和属性(仅仅用来标识这个类产生的对象可以被序列化)
5.2 被static/transient修饰的属性没有被序列化出去
5.3 一个对象在反序列化的时候会自动的比较这个对象的版本号和当前类中的版本号是否一致,如果一致才能反序列化回来 如果一个类中没有手动指定版本号,JVM在运行的时候会根据当前类中的属性和方法自动计算机的版本号 版本号默认使用 private static final long serialVersionUID (private可以改 值可以改 其他都不能变)
5.4 每个文件中只能存储一个序列化的对象