1.异常
异常:程序中一些程序处理不了的特殊情况。java中异常会以类的形式出现,当程序中出现异常,就会中断程序,代码不会继续运行。
异常分类:
1.检查型异常(编译异常):在编译时就会抛出的异常(在代码上报错),需要在代码中编写处理方式,和程序之外的资源访问,直接继承Exception。
2.运行时异常:在代码运行阶段可能会出现的异常,可以没有明文处理,可以通过代码避免异常的发生。继承RunTimeException。
处理异常:
1.throws:
在方法声明的位置上使用 throws 关键字抛出,谁调用我这个方法,我就抛给谁。抛给调用者来处理。这种处理异常的态度:上报。
throws的抛出范围更小,可以为空。声明方法中可能抛出的异常,声明抛出多种异常。
方法重写的约束:返回值类型,方法名,参数列表不能变,访问权限只能更开放。
代码:
package com.easy723;
public class EasyExceptionA {
}
class BigStudent extends Student{
@Override
public void info () throws StudentNameIsNullException{
//throws抛出范围更小,可以为空
}
}
//自定义异常
class Student {
String name;
//throws 声明方法中可能抛出的异常
//throws 声明抛出多种异常
//方法重写:子类对父类中继承过来的方法进行重新定义
//约束:返回值类型,方法名,参数列表不能变,访问权限只能更开放。重写的方法抛出的异常,只能更精确,范围更小,不能扩大。
public void info() throws StudentNameIsNullException,NullPointerException{
//name==null是一种特殊情况,不符合业务需求
if (name==null){
throw new StudentNameIsNullException("student name is null");
}
System.out.println("我的名字是:"+name);
}
//运行时异常可以不声明抛出
public void infoA(){
if (name==null){
throw new NullPointerException("name is null");
}
}
}
//检查型异常 是Exception的直接子类
class StudentNameIsNullException extends Exception{
public StudentNameIsNullException(){
}
public StudentNameIsNullException(String msg){
super(msg);
}
}
2.try…catch...finally:
这个异常不会上报,自己把这个事儿处理了。异常抛到此处为止,不再上抛了。
注意:
只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行。当try处理多种异常时,遇到第一个异常就中断,跳转到catch。
try语句块中的某一行出现异常,该行后面的代码不会执行。try不能单独编写,必须有其他语句块。
try…catch捕捉异常之后,后续代码可以执行。
finally块无论是否出现异常都会执行的代码块,一般用在关闭资源。如果只有finally,try中不能有检查型异常。try块中没有检查型异常,不能再catch块中随意捕捉。
catch块是合并处理方案,一个catch块捕捉多种异常。可以通过声明父类异常来捕捉所有子类异常,catch异常捕捉的顺序:子类异常优先处理(前放),父类异常后处理。如果catch块抛出异常,没有finally就会中断程序,如果有,运行finally并且正常返回,此方法结束。
代码:
package com.easy723;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EasyException {
//异常 程序中一些程序处理不了的特殊情况
//异常类 Exception
//见过的异常:Null Pointer Exception,ArrayIndexoutOf...
public static void main(String[] args) {
String str=null;
// String name="张三";
// boolean b=str.equals(name);
// b=name.equals(str);//把确定不为空的放前面避免异常
//System.out.println(str.length());
int i=12;
int a=0;
if(a!=0) {
System.out.println(i / a);//没有if判断直接运行会报错:ArithmeticException
}else {
System.out.println("a不能做除数");
}
System.out.println("++++++++++++");
//当程序中出现异常,就会中断程序,代码不会继续运行
//异常分类:
//1.检查型异常(编译异常):在编译时就会抛出的异常(在代码上报错),需要在代码中编写处理方式
//和程序之外的资源访问 直接继承Exception
//2.运行时异常:在代码运行阶段可能会出现的异常,可以没有明文处理,可以通过代码避免异常的发生
//继承RunTimeException
//处理异常
//try...catch...finally
//声明抛出 throws
//声明异常
//处理文件
File file=new File("D:\\easy.test");
//检查型异常(编译异常)
FileInputStream fis=null;//因为finally要调用fis,所以在外部声明
try {
//尝试捕捉异常 其中可能会抛出异常的代码
fis=new FileInputStream(file);
}catch (FileNotFoundException e){
//捕捉到异常后要处理的代码
e.printStackTrace();//打印异常日志
}finally {
//无论是否出现异常都会执行的代码块 一般用在关闭资源
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//try 处理多种异常
try {
System.out.println(12/0);//第一个异常就中断,跳到catch,后两个异常不会运行
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
}catch (ArithmeticException e){
//出现ArithmeticException要执行的代码
System.out.println("出现ArithmeticException");
}catch (ClassCastException e){
System.out.println("出现ClassCastException");
}catch (FileNotFoundException e){
System.out.println("出现FileNotFoundException");
}finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//catch 合并处理方案 一个catch块捕捉多种异常
//1.
try {
System.out.println(12/0);
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
}catch (ArithmeticException|ClassCastException|FileNotFoundException e){
}
//2.通过声明父类异常,捕捉所有子类异常
try {
System.out.println(12/0);
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
}catch (Exception e){
}
//catch异常捕捉的顺序 子类异常优先处理(前放),父类异常后置处理
try {
List list=new ArrayList<>();
list.remove(8);//Indexout
int[] arr=new int[2];
arr[8]=22;//ArrayIndex
String strA="abc";
strA.charAt(8);//Stringindex
}catch (ArithmeticException e){
e.printStackTrace();
}catch (StringIndexOutOfBoundsException e){
e.printStackTrace();
}catch (IndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println(test());//3
}
//如果catch块抛出异常,没有finally就会中断程序
//如果有finally,会运行finally并且正常返回,此方法正常运行结束
public static int test(){
try {
System.out.println(12/0);
return 1;
}catch (Exception e){
return 2;
}finally {
return 3;
}
}
//try不能单独编写,必须有其他语句块
public static void testA(){
try {
System.out.println(12/0);
}catch (Exception e){
}
}
public static void testB(){
FileInputStream fis=null;
File file=null;
try {
System.out.println(12/0);
//如果只有finally,try中不能有检查型异常
//比如fis=new FileInputStream(file);
}finally {
}
}
//try块中没有检查型异常,不能在catch块中随意捕捉
public static void testC(){
try {
int a=12+8;
}catch (NullPointerException e){
//可以
}
// catch (FileNotFoundException e){
// 不行
// }
}
}
2.文件(IO流)
java中对文件的处理通过java.io包。
在声明一个文件时,传入字符串当作文件地址。
注意:创建文件时,mkdir创建必须前面的路径都存在,mkdirs不用。删除文件夹时,文件夹必须是空的。
一些常用操作代码:
package com.easy723;
import java.io.File;
import java.io.IOException;
public class EasyFile {
//java中对文件的处理
//java.io包
public static void main(String[] args) {
//在java中声明一个文件 传入字符串当作文件地址
File f=new File("D:\\easy.txt");
//是否存在该文件
boolean bool=f.exists();
System.out.println(bool);
//创建文件
if (!bool){
try {
bool=f.createNewFile();
if (bool){
System.out.println("成功创建文件");
}
}catch (IOException e){
e.printStackTrace();
}
}else {
//删除文件夹时,文件夹必须是空的文件夹
bool=f.delete();
System.out.println("成功删除文件"+bool);
}
//获取是否是文件
bool=f.isFile();
System.out.println(bool);
//是否是文件夹
bool=f.isDirectory();
System.out.println(bool);
//创建文件
//mkdir创建必须前面的路径都存在,mkdirs不用
//f.mkdir();
}
}
IO流(输入/输出流)
流:流动的数据,是二进制。
分类:根据流动的方向不同:输入流(向java程序流)和输出流。
根据流动的介质(单位)不一样:字符流和字节流(字符流只能读取文本txt .xml .html .properties。字节流可以读取所有的文件类型)。
根据功能(作用)不一样:节点流和工具流 (打印流 数据流 对象流)
总结:创建对象的方式
1.new 2.克隆 3.反序列化 4.反射
序列化和反序列化:
序列化:将内存对象转换成序列(流)。这个对象必须是可序化的。
优点:
实现了数据的持久化,通过序列化可以把数据持久地保存在硬盘上(磁盘文件)。
利用序列化实现远程通信,在网络上传输字节序列。
反序列化:将对象序列读入程序,转换成对象的方式。反序列化会创建新对象,与之前的不是一个数据。
工具流:
1.转换流
字符流比字节流在操作上更加方便,Java提供了转换流来实现字节流向字符流的转换。
2.缓冲流
缓冲流:增强基本流的功能,在基本流的基础上演变而来。
按照数据类型进行分类分为:
字节缓冲流:BufferedInputStrem BufferedOutputStream
字符缓冲流:BufferedReader BufferedWriter
缓冲流的基本原理:是在创建流对象时会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统的IO次数,提高读写的效率。
代码:
package com.easy723;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.io.*;
public class EasyFileIO {
//IO 输入流/输出流
//流动的是数据 二进制
//分类:根据流动的方向不同 输入流(向java程序流) 输出流
//根据流动的介质(单位)不一样 字符流和字节流
//字符流只能读取文本txt .xml .html .properties
//字节流可以读取所有的文件类型
//根据功能(作用)不一样 节点流和工具流 打印流 数据流 对象流
public static void main(String[] args) {
//字节输入流
InputStream is;
//字节输出流
OutputStream os;
//字符输入流
Reader r;
//字符输出流
Writer w;
//
//readFile();
//writeFile();
//readFileBuffer();
//writeObject();
readObject();
//总结:创建对象的方式
//1.new
//2.克隆
//3.反序列化
//4.反射
}
public static void readObject(){
//将对象序列读入程序,转换成对象的方式:反序列化
//反序列化会创建新的对象
FileInputStream fis=null;
ObjectInputStream ois=null;
try {
fis=new FileInputStream("D:\\easy.txt");
ois=new ObjectInputStream(fis);
Object obj=ois.readObject();
System.out.println(obj);
}catch (Exception e){
e.printStackTrace();
}finally {
if (ois!=null){
try {
ois.close();
}catch (IOException e){
e.printStackTrace();
}
}
if (fis!=null){
try {
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public static void writeObject(){
//将内存对象转换成序列(流),叫做序列化
//这个对象必须是可序列化的
Staff staff=new Staff();
staff.name="张三";
staff.sex="男";
staff.salary=3500;
ObjectOutputStream oos=null;
FileOutputStream fos=null;
try {
fos=new FileOutputStream("D:\\easy.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(staff);
}catch (IOException e){
e.printStackTrace();
}finally {
if (oos!=null){
try {
oos.close();
}catch (IOException e){
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public static void writeFile(){
String str="哈哈哈哈哈";
byte[] arr=str.getBytes();
FileOutputStream fos=null;
try {
fos=new FileOutputStream("D:\\easy.txt",true);
fos.write(arr);
}catch (IOException e){
e.printStackTrace();
}finally {
if (fos!=null){
try {
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public static void readFileBuffer(){
FileInputStream fis=null;//文件字节输入流
// 工具流
//转换流:字节流转换成字符流
InputStreamReader isr=null;
//缓冲流:
BufferedReader br=null;
try{
fis=new FileInputStream("D:\\easy.txt");
isr=new InputStreamReader(fis);
br=new BufferedReader(isr);
String line=br.readLine();
System.out.println(line);
}catch (IOException e){
e.printStackTrace();
}finally {
if (fis!=null){
try {
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public static void readFile(){
FileInputStream fis=null;
try{
fis=new FileInputStream("D:\\easy.txt");
byte[] arr=new byte[6];
//读取多少转换多少
int length=0;
while((length=fis.read(arr))!=-1){
//arr中就是读取的数据
String str=new String(arr,0,length);
//或者String.valueOf(arr);
System.out.print(str);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (fis!=null){
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}