图片展示:
一、异常
- Throwable是所有错误和异常的超类
- 错误:一般情况下不是因为我们的代码有问题,而是因为外部因素导致的,比如我说了我程序必须要2G内存才可以运行,但是用户的电脑是512M的内存
- 编译时期异常:就是没有满足java语法或者调用的方法中声明了可能会发送异常,这个异常通常都是需要处理的
- 运行时期异常:就是java代码运行之后才会产生的异常,一般情况下是因为数据的原因导致的,可以处理,也可以不处理,一般情况下是更换数据
代码实现:
package cn.edu360;
import java.text.SimpleDateFormat;
public class ClassDemo {
public static void main(String[] args) throws Exception {
//运行时异常
int i = 1/0;//java.lang.ArithmeticException
int[] arr = {1, 2};
System.out.println(arr[4]);// java.lang.ArrayIndexOutOfBoundsException
//编译时期异常
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.parse("");// java.text.ParseException
}
}
- JVM默认处理异常的方式
- 终止程序运行
- 将错误信息、错误位置、错误异常的名字打印输出在控制台
总而言之,JVM默认处理异常的方式不是我们需要的,而我们可以通过以下几种方式来处理;
(1)try…catch()…finally
注意事项:
- 合并多个异常,如果try里面会发送多个异常,那么最终只会有一个异常发送
- 如果多个catch中捕获的异常存在子父类关系,那么最大的那个异常捕获必须放在最后面位置
- JDK1.7新特性可以用“|”将多个异常连接起来,用一个catch处理,也就是说多个异常共享同一种处理方式,这种处理方式不能存在子父类异常关系
- 在开发中不管有多少异常,只捕获一个最大异常(Exception)就可以啦
Throwable里面的方法
- public String getMessage()返回此throwable的详细信息字符串
- toString()返回此throwable的简短描述
- printStackTrace()将此throwable及其追踪输出至标准输出流
- public void printStackTrace(PrintWriter s)将此throwable及其追踪输出到指定的PrintWriter
代码实现:
package cn.edu360;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.sun.org.apache.bcel.internal.generic.NEW;
public class ClassDemo {
public static void main(String[] args){
try {
new SimpleDateFormat().parse("");
} catch (ParseException e) {
//System.out.println(e.getMessage());//Unparseable date: ""
//System.out.println(e.toString());//java.text.ParseException: Unparseable date: ""
//e.printStackTrace();
/**
* java.text.ParseException: Unparseable date: ""
at java.text.DateFormat.parse(DateFormat.java:366)
at cn.edu360.ClassDemo.main(ClassDemo.java:10)
*/
PrintWriter pw;
try {
pw = new PrintWriter("D:/"+System.currentTimeMillis()+".log");
e.printStackTrace(pw);
pw.flush();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
}
}
异常
- 编译时期异常:非RuntimeException及其子类的异常都是编译时期的异常,必须手动处理,不然运行不了程序
- 运行时期异常:RuntimeException及其子类,可以显示处理,也可以不处理;一般是因为数据的原因,需要将数据进行更改
finally
finally:最终的,一定会的
注意事项:放在finally里面的代码一定会执行
代码实现:
package cn.edu360;
public class ClassDemo {
public static void main(String[] args){
try {
int i = 1/0;
} catch (Exception e) {
e.printStackTrace();
//程序在结束main方法之前会先去看一下finally里
//面有没有代码需要执行,如果有,执行完毕后再结束方法
//return;
//JVM挂掉了,没有人来检查finally里面的代码了,所以就不执行
System.exit(0);
}finally{
System.out.println("over");
}
}
}
(2)throws
抛出某个异常的类名,表示一种可能;可以跑出运行时期异常,也可以抛出编译时期异常
- 跟在方法的后面
- 抛出的是异常的类名,如果是多个异常用“,”隔开
- 它抛出的异常都是由调用者处理
- 表示抛出的异常,抛出的是一种可能
(3)throw
- 在方法内部使用
- 后面跟的是一个异常对象,而且每次只能抛出一个对象
- throw抛出的是一个具体的异常对象,所以这个方法肯定是存在异常的
- 是在方法内部进行处理
处理异常的方式的使用场景
- 如果方法体内部能将异常处理,就使用try…catch自己处理,如果自己处理不了就使用throws
- 如果后续代码需要继续运行就用try…catch
- 如果后续代码不需要运行就使用throws
使用异常时候的注意事项
- 子类重写父类的方法时,可以抛出父类异常的自身或者父类异常的子类
- 当父类中有多个异常时,子类只能抛出父类中异常的子集,不能抛出父类没有的异常
- 当父类中的方法没有抛出异常时,子类的重写方法也不能抛出任何异常,遇到异常只能使用try…catch内部处理
二、File类
文件和目录路径名的抽象表示形式,并不代表文件一定存在
- 构造方法
- File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
- File(String parent, String child)根据将parent路径名字符串和child路径名字符串创建一个新File实例
- File(File parent, String child)根据parent抽象路径名和child路径名字符串创建一个新File实例
代码实现:
package cn.edu360;
import java.io.File;
public class ClassDemo {
public static void main(String[] args){
String pathName = "G:\\aa.txt";
File file = new File(pathName);
String parent = "G:\\";
String child = "aa.txt";
File file2 = new File(parent, child);
}
}
- File类功能
- 创建功能
①public boolean createNewFile()
在硬盘上创建文件对象所表示的路径文件,如果创建成功返回true,创建失败返回false
②public boolean mkdir()
创建单级文件夹
③public boolean mkdirs()
创建多级文件夹 - 删除功能
①public boolean delete()
删除一个文件 - 重命名功能
①public boolean renameTo(File dest)
剪切并重命名文件
代码实现:
package cn.edu360;
import java.io.File;
public class ClassDemo {
public static void main(String[] args) throws Exception{
File file = new File("G:\\haha.txt");
System.out.println(file.createNewFile());
file = new File("G:\\haha");
System.out.println(file.mkdir());
file = new File("G:\\aa\\bb\\cc");
System.out.println(file.mkdirs());
file = new File("G:\\haha.txt");
System.out.println(file.delete());
file = new File("G:\\haha");
System.out.println(file.delete());
file = new File("G:\\aa");
//多级文件夹是不能直接删除的,需要将里面的所有子文件删除之后才能删除最外面的文件夹
System.out.println(file.delete());
file = new File("G:\\aa.txt");
file.renameTo(new File("E:\\gaimin.txt"));
}
}
- 判断功能
①public boolean isDirectory()
判断当前文件是否是一个文件夹
②public boolean isFile()
判断当前文件是否是一个标准文件
③public boolean exits()
判断当前文件是否存在
④public boolean canRead()
判断当前文件是否可读
⑤public boolean canWrite()
判断当前文件是否可写
⑥public boolean isHidden()
判断当前文件是否隐藏
代码实现:
package cn.edu360;
import java.io.File;
public class ClassDemo {
public static void main(String[] args) throws Exception{
File file = new File("G:\\haha.txt");
System.out.println(file.isDirectory());//false
System.out.println(file.isFile());//true
System.out.println(file.exists());//true
System.out.println(file.canRead());//true
System.out.println(file.canWrite());//true
System.out.println(file.isHidden());//false
}
}
- 基本获取功能
①public String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串;也就是返回的是全路径名,开发中经常用这个
②public String getPath()
返回相对路径名字符串
③public String getName()
返回由此抽象名表示的文件或目录的名称
④public long length()
返回由此抽象路径名表示的文件的长度
⑤public long lastModified()
返回此抽象路径名表示的文件最后一次被修改的时间 - 高级获取功能(主要用于文件夹操作)
①public String[] list()
返回的是子文件的路径的数组
②public File[] listFiles()
返回的是子文件对象数
代码实现:
package cn.edu360;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ClassDemo {
public static void main(String[] args) throws Exception{
File file = new File("./src/cn/edu360/Person.java");
System.out.println(file.getAbsolutePath());//D:\spongeCity\ClassDemo\.\src\cn\edu360\Person.java
System.out.println(file.getPath());//.\src\cn\edu360\Person.java
System.out.println(file.getName());//Person.java
System.out.println(file.length());//776
long time = file.lastModified();
String s = new SimpleDateFormat().format(new Date(time));
System.out.println(s);//18-11-28 下午5:17
}
}
案例展示
1、判断单级目录下是否有后缀名为.jpg的文件,如果有,如果有则输出此文件名
代码实现:
①第一种方式
package cn.edu360;
import java.io.File;
public class ClassDemo {
public static void main(String[] args) throws Exception{
//1、将目标目录封装成目标对象
File file = new File("G:/");
//2、获取目录下的所有的文件名称
String[] list = file.list();
//3、遍历所有的文件名数组
for(String value: list){
//4、判断是否以.jpg结尾
if(value.endsWith(".jpg")){
System.out.println(value);
}
}
}
}
②第二种方式
package cn.edu360;
import java.io.File;
import java.io.FilenameFilter;
public class ClassDemo {
public static void main(String[] args) throws Exception{
//1、将目标目录封装成目标对象
File file = new File("G:/");
//2、使用过滤器获取指定后缀名结尾的文件
//boolean accept(File dir,String name)测试指定文件是否应该包含在某一文件列表中
//参数:dir---被找到的文件所在的目录;name---文件的名称
//当且仅当该名称应该包含在文件列表中时返回true,否则返回false
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//判断当前的文件是否是一个标准文件,然后判断是否以后缀名.jpg结尾
return new File(dir, name).isFile() && name.endsWith(".jpg");
}
});
for (String value : list) {
System.out.println(value);
}
}
}
三、递归
就是方法内部调用方法自身的一种现象
注意事项:
- 递归需要有出口,不然就是死递归
- 递归次数不能太多,就会内存溢出
- 构造方法不能递归
案例展示:
- 求5的阶乘:5 * 4 * 3 * 2 * 1
package cn.edu360;
public class ClassDemo {
public static void main(String[] args) throws Exception{
int sum = 1;
//普通的for循环实现
for (int i = 1; i <= 5; i++) {
sum *= i;
}
System.out.println(sum);
//递归去实现
sum = digui(5);
System.out.println(sum);
}
private static int digui(int i) {
if(i == 1){
return 1;
}else{
return i*digui(i-1);
}
}
}
- 兔子问题(斐波那契数列)
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月每个月又生一对兔子,假如兔子都不死,问第十个月的兔子对数为多少?
package cn.edu360;
/**
- @author Zhang
- 规律:从第三个月开始兔子的对数是前两个月之和
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//普通方法实现
int[] arr = new int[10];
arr[0] = 1;//第一个月的兔子对数
arr[1] = 1;//第二个月的兔子对数
//从第三个月开始兔子的对数是前两个月之和
for (int i = 2; i < arr.length; i++) {
arr[i] = arr[i-1] + arr[i-2];
}
System.out.println(arr[arr.length-1]);//55
//递归实现
int count = getCount(10);
System.out.println(count);//55
}
private static int getCount(int i) {
if(i == 1 || i == 2){
return 1;
}else{
return getCount(i-1)+getCount(i-2);
}
}
}
- 猴子吃桃
小猴第一天摘下若干桃子,当即吃掉一半,又多吃一个。第二天早上又将剩下的桃子吃一半,又多吃一个。以后每天早上吃前一天剩下的一半另一个。到第10填早上猴子想再吃时发现,只剩下一个桃子了。问第一天猴子共摘多少个桃子?
package cn.edu360;
/**
* @author Zhang
* 规律:前一天的桃子树 = (后一天桃子树+1)*2
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//递归实现
int count = getCount(1);
System.out.println(count);//1534
}
private static int getCount(int i) {
if(i == 10){
return 1;
}else {
return (getCount(i+1)+1)*2;
}
}
}