异常处理
什么是异常:
程序中产生的错误就为异常
语法错误:编译时错误
程序运行过程中出现的错误:运行时异常
什么是异常处理:
防止程序出现错误而终止
为什么需要异常处理:
保证程序的键壮性
常用的异常类:
Exceiption类:异常类的父类,但它又继承自Throwable
子类:
RuntimeException
:运行时异常类
子类:
NullPointerException :空指针异常
ArrayIndexOutOfBoundsException :数组下标越界
ArithmeticException :算术异常
ClassCastException :类型转换异常
…
IOException
:IO异常类(与文件相关的异常)
SQLException
:SQL类(与数据库相关)
显示异常信息:
toString()
getMessage()
printStackTrace()
异常处理语法:
try{
可能发生异常的代码...........
}catch(异常类 对象名){
发生异常会执行的代码(捕捉异常,能捕捉什么异常取决于异常类)
}finally{
不管是否发生错误都会执行的代码
}
语法:
1.try{....}catch{....}finally{...}
2.try{...}catch{...}catch{....}
3.try{...}finally{......}
总结一点:必须要有try
抛异常:throw throws
解释:
throw:抛出一个具体的异常对象
throws:声明要抛出的异常
语法:
public void 方法名(...) throws 异常类{
......
throw new 异常类();
}
注意事项:
异常谁调用,谁处理
自定义异常类:
步骤1:
创建一个普通类,让它继承自Exception类
步骤2:
重写toString()方法–>为了将错误信息响应给用户
语法:
public class 类名 extends Exception{
//重写
public String toString(){
return "错误信息";
}
}
文件流的输入,输出
File类
在java中,表示文件和目录 (在C#中,文件和目录是用不同类来表示的)
所在的包:
IO
创建的语法:
File 对象名 = new File("文件的路径及文件名称");
对象名.方法名();
常用方法:
getName():获取名称,返回String
getAbsolutePath():获取绝对路径,返回String
length():获取文件大小,以字节为单位,返回long
isFile():判断是否一个文件,返回boolean
,是文件返回true
exists():判断文件是否存在,返回boolean
,文件存在返回true
listFiles():获取目录中的所有文件,返回File[]
获取指定目录下的文件:
File file = new File("D:\\test"); //D盘下的test文件夹
File[] files = file.listFiles(); //获取test中的所有文件夹
for(int i=0;i<file.length;i++){
files[i].方法名 //通过循环可访问每个文件的方法
}
获取指定目录下的所以文件:
public static void main(String[] args) {
getfile("D:\\");
}
public static void getfile(String str) {
File file = new File(str);
File[] files = file.listFiles();
System.out.println(str+"下的文件如下:");
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
System.out.println("文件名称:" + files[i].getName());
System.out.println("文件路径:" + files[i].getAbsolutePath());
}else{
//使用递归获取到所以文件夹
getfile(files[i].getAbsolutePath());
}
}
}
文件夹操作:
mkdir():创建目录,要求目录已经存在
mkdirs():创建多级目录都可以,没有要求目录必须已经存在(按照层次结构创建)
字节流与字符流
分类:
字节流(byte):可以读写二进制文件、文本文件
单位是8位,直接操作的是文件
使用类:
InputStream OutputSeaream
字符流(char):只能读写文本文件
单位是16位,先写入数据到缓冲区,再写入文件
使用类:
Reader Writer
字节流的写
:
//步骤1:创建输出流
FileOutputStream out = new FileOutputStream("路径及文件名称"); //如:D:\\test.txt 可以可以是File
//步骤2:将内容转为一个字节数组
byte[] data = 内容字符串.getBytes();
//步骤3:写入内容到文件中去(将内容输出到文件中)
out.write(data);
//步骤4:关闭文件流
out.close();
字节流的读
:
//步骤1:创建输入流
FileInputStream input = new FileInputStream(file或("路径及文件名称");
//步骤2:读取文件中的数据
byte[] data = new byte[1024]; 表示每次读取多少数据,可以不是1024
int length;
while((length=input.read(data)) != -1){ //input.read(data)表示读取数据
//将字节数组转为字符串
String str = new String(data,0,legnth); //将data字节数组中的所有数据转为字符串
//输出str........
}
//步骤3:关闭文件流
input.close();
解释:
如果在D:\test.txt一共有1028字节
第1次读取:1024
再次读取:4
再次读取:-1
字符流写
:
//步骤1:创建文件流
FileWriter fw = new FileWriter("文件及路径");
//步骤2:创建缓冲区对象
BufferedWriter bw = new BufferedWriter(fw); //fw指向的是目录文件
//步骤3:写入内容
bw.write(内容);
bw.newLine();换行
//步骤4:刷新缓冲区及关闭文件流(如果没有此步骤,内容只写入到缓冲区,文件中没有内容)
bw.flush();
bw.close();
字符流读
:
//步骤1:创建文件流
FileReader fr = new FileReader("文件及路径");
//步骤2:创建缓冲区对象
BufferedReader br = new BufferedReader (br);
//步骤3:读取数据
String str="";
while((str = br.readLine()) != null){
//内容在str中,具体操作.......
}
//步骤4:关闭缓冲区及文件流
br.close();
fr.close();
二进制文件的读写
:只能是字节流
二进制文件的写
:
//步骤1:创建输出流
FileOutputStream fs = new FileOutputStream("路径名称"或者File);
//步骤2:创建二进制对象
DataOutputStream out = new DataOutputStream(fs);
//步骤3:写入内容到文件(输出)
out.writexxx(内容); //区分数据类型
//步骤4:关闭
out.close();
fs.close();
二进制文件的读
:
//步骤1:创建输入流
FileInputStream fs = new FileInputStream ("路径名称"或者File);
//步骤2:创建二进制对象
DataInputStream input= new DataInputStream (fs);
//步骤3:读取文件内容
数据类型 变量名 = input.readxxx(); //区分数据类型
//步骤4:关闭
input.close();
fs.close();
对象的序列化与反序列化
序列化内容到文件中去
//步骤1:创建输出流
FileOutputStream fs = new FileOutputStream("路径名称"或者File);
//步骤2:创建序列化对象
ObjectOutputStream out = new ObjectOutputStream(fs);
//步骤3:序列化
out.writeObject(内容); //内容可以是任意类型
//步骤4:关闭
out.close();
fs.close();
返回序列文件内容到程序中来
//步骤1:创建输入流
FileInputStream fs = new FileInputStream ("路径名称"或者File);
//步骤2:创建序列化对象
ObjectInputStream input = new ObjectInputStream(fs);
//步骤3:返序列化
数据类型 变量名 = (目标类型)out.readObject(); //强制转换成需要的类型
//步骤4:关闭
input.close();
fs.close();
注意:一个类如果要序列化,一定要实现Serializable 接口
public class 类名 implements Serializable {
}
泛型
简单的理解:动态的“<数据类型>”
优点:
1.避免了强制数据类型转换
2.程序的安全性更好
缺点:
缩小了使用的范围
注解
给“编译器”看的(计算机)
3个注解:
(1) @Override:重写
(2)@SuppressWarnings:抑制警告
(3) @Deprecated:方法过期,不建议使用
语法:
注解
public void 方法(参数){
.......
}
注意区分注解与注释:
注释:给“程序员”看的
注解:给“编译器”看的(计算机)
增强for循环
语法:
for(数据类型 变量名 : 集合名或数组){
相关代码....
}
可变参数
:
在方法调用时参数没有固定数量,可灵活调用
语法:
public void 方法名(参数1,参数n(数据类型... 参数名)){ 注意:可变参数必须是最后一个
......
}
静态导入
:
使用静态导入之后,静态方法不需要类型.方法名来调用,可通过方法名直接调用
注意:
静态导入的包,对应的方法要是静态的
语法:
import static 包名..........
pubic class 类名{
…………
}
枚举
:
简单理解:自定义的数据类型,这个数据类型的取值范围由你决定
也可以:限制取值范围
语法:
访问修饰符 enum 枚举名称{
成员1,成员2,成员n
}
使用枚举成员:
枚举名称.成员名
枚举的输出:
for(枚举名 变量名 : 枚举名.values()) -->values()方法:返回的是一个数组,因此可以用循环来操作
{
输出变量名…………
}
装箱与拆箱
:
何为装箱:
将 基本数据类型 转为 引用类型
何为拆箱:
将引用类型 转为 基本数据类型