黑马程序员——Java基础---IO(输入输出)(上)

来源:互联网 发布:聚宝盆软件官网 编辑:程序博客网 时间:2024/05/14 09:27

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

IO(流)目录:
一、异常
1、异常概述
2、异常分类
3、JVM默认是如何处理异常的
4、异常处理的基本语句_try_catch
5、异常处理_多catch语句
6、JDK7对多catch语法的改进
7、Throwable的常用方法
8、方法内处理异常的方式一_throws语句
9、throws和throw的区别
10、到底如何处理异常
11、finally语句
12、try_catch_finally的常见组合
13、面试题之final_finally和finalize的区别
14、面试题之finally中有return语句
15、面试题之finally中有return语句
16、自定义异常
17、重写父类方法时的异常处理
二、File类
1、File类概述
2、File类创建功能
3、File类删除功能
4、File类重命名功能
5、File类重判断功能
6、File类获取功能
7、File类高级获取功能
8、输出指定目录下指定后缀名的文件(练习)
9、批量修改文件名称案例(练习)
10、文件过滤器
三、递归
1、递归的概念
2、递归练习_求5的阶乘
3、递归练习_不死神兔问题案例
4、递归练习_递归输出指定目录下所有的java文件的绝对路径
5、递归练习_删除带内容的目录案例

总结

IO(流)知识详解:

讲解IO流之前为什么先讲解异常和File类呢?

因为File表示的是IO流将来要操作的文件,所以我们需要学习File类。

而操作文件无非就是上传文件和下载文件,在这个操作的过程中可能出现问题,

出现问题后,我们需要对对应的代码进行处理。所以我们需要学习异常异常。

一、异常

1、异常概述

 * 1.我们的程序有些时候存在一些潜在的危险,这些危险常常来自于外部;
 * 例如:正在读取硬盘数据时,硬盘突然出现坏道,导致我们的程序无法读取;
 *       正在读取网络数据时,网络突然中断,也会导致我们的程序出现异常情况;
 * 2.当出现这种异常情况时,JVM通常的做法是:
 * 1).JVM会识别出这个异常,并在类库中找到这个异常类;
 * 2).将异常信息打印到控制台;
 * 3).将我们的程序停止;(这种情况不是我们想要的)
 * 3.Java中提供了一种处理这种异常情况的机制:异常处理机制;
 * 4.Java中的异常处理机制:
 * 1).异常处理的语法;
 * 2).异常类;
 * 5.我们的程序加入了"异常处理"后,可以使我们的程序更加在健壮,即使出现异常情况时
 *   我们的程序也不至于"崩溃",仍然能够继续健康的活下去。

public class Demo {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个数:");int n = sc.nextInt();System.out.println("n = " + n);int a = 10;int b = 0;System.out.println("a / b = " + (a / b));}}

2、异常分类

 * Throwable(类):它是所有Java错误和异常基类
 * |--Error(类):错误:Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
 * |--Exception(异常):
 * |--运行时异常:所有的RuntimeException及其子类类型的异常;
 * |--非运行时异常(编译时异常):除RuntimeException及其子类类型的异常外,其它异常都是非运行时异常;


异常分三类:

骑车去旅行:

  Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是班长能够立马解决的。

  Exception:出门前,班长要看看车轮子以及车链子等是否还在

  RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路

1,编译时异常

除了RuntimeException及其子类,Exception中所有的子类都是,这种异常必须要处理,要不编译通不过

2,运行是异常

RuntimeException及其子类都是,这种异常不用处理,编译会通过,不过这样的程序会有安全隐患,遇到这种异常是需要改代码的

3,严重错误问题

用Error进行描述,这个问题发生后,一般不编写针对代码进行处理,而是要对程序进行修正.通常都是由虚拟机抛出的问题

编译时异常和运行时异常的区别:

Java中的异常被分为两大类:编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常
编译时异常
Java程序必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常
无需显示处理,也可以和编译时异常一样处理

3、JVM默认是如何处理异常的

 * 1.发现异常;
 * 2.识别异常;
 * 3.封装异常对象:在类库中找到对应的"异常类",并实例化此类的对象
 * 4.向控制台打印异常信息:
 * Exception in thread "main" java.lang.ArithmeticException: / by zero
at cn.itcast.demo15_JVM默认是如何处理异常的.Demo.main(Demo.java:7)
 *  5.将我们的程序结束;

jvm发现运算是已经违反了数学运算规则,java将这种常见的问题进行描述,并封装成了对象叫做ArithmeticException

当除0运算发生后,jvm将该问题打包成了一个异常对象.

并将对象抛给调用者main函数,newArithmeticException("/by zero")

main函数收到这个问题时,有两种处理方式:

1,自己将该问题处理,然后继续运行

2,自己没有针对的处理方式,只有交给调用main的jvm来处理

jvm有一个默认的异常处理机制,就将该异常进行处理.并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上

同时将程序停止运行

public class Demo {public static void main(String[] args) {int a = 10;int b = 0;System.out.println(a / b);System.out.println("程序结束!");}}

4、异常处理的基本语句_try_catch

 * 异常处理的基本语句:
 * try{
 * //可能会出现异常的代码
 * }catch(异常类型 变量名){
 * //如果出现异常了,告诉JVM怎么做--JVM会执行这里面的代码;
 * //一般情况下我们在这里做什么:
 * 1.开发阶段:可以打印异常异常信息,有助于调试;
 * 2.程序交付使用后:将错误信息写入日志文件;后期供开发人员维护升级使用;
 * }
 * 异常处理机制的执行流程:
 * 1.执行try中的代码;
 * 2.如果没有发生异常,执行完try后,不执行catch,跳过catch直接执行后续语句;
 *   如果发生异常:
 *   1).JVM先识别异常;
 *   2).JVM封装异常;
 *   3).看我们的代码,有没有相应的catch语句,而且要匹配catch中的"异常类型";
 *   如果匹配到,执行此catch种的代码,执行完毕后,执行catch的后续语句;

import java.util.InputMismatchException;import java.util.Scanner;public class Demo {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");try{int n = sc.nextInt();System.out.println(n);}catch(InputMismatchException e){System.out.println("对不起,你输入的不是一个整数,请输入一个整数!");}System.out.println("程序结束");}}
5、异常处理_多catch语句
 * 多catch语句:
 * 1.一段代码可能会产生多种异常;
 * 2.我们可以写一个try语句,后面跟多个catch语句,表示捕获多种异常;
 * try{
 * //可能会出现异常的代码
 * }catch(异常类型1 变量名){
 * //如果发生"异常类型1"异常时,会执行这里的代码
 * }catch(异常类型2 变量名){
 * //如果发生"异常类型2"异常时,会执行这里的代码
 * }catch(异常类型3 变量名){
 * //如果发生"异常类型3"异常时,会执行这里的代码
 * }
 * 3.注意:
 * 1).多catch种的异常类型,可以是"同级别"异常类型,也可以是"子父"异常类型;
 * 2).如果是"子父关系"的异常类型,父级别的异常类型,一定要放在catch列表的末尾;

public class Demo {public static void main(String[] args) {/*try{int a = 10;int b = 0;System.out.println(a / b);int[] array = {14,2,43};System.out.println(array[3]);String str = null;System.out.println(str.length());//后边还有其他代码,可能产生其它异常;但不知道是具体什么异常了}catch(ArithmeticException e){System.out.println("除数不能为0!");}catch(ArrayIndexOutOfBoundsException e){System.out.println("数组下标越界!");}catch(NullPointerException e){System.out.println("空指针!");}catch(Exception e){System.out.println("发生未知异常,请与系统管理员联系!");}*/}}
6、JDK7对多catch语法的改进

 * JDK7对多catch语法的改进:
 * try{
 * }catch(异常类型1 | 异常类型2  | 异常类型3  变量名){
 * }
 * 注意:并列catch的异常类型中,不能有子父的关系的异常类型;
 *     但可以写多个catch()

public class Demo {public static void main(String[] args) {try{int a = 10;int b = 0;System.out.println(a / b);int[] array = {14,2,43};System.out.println(array[3]);String str = null;System.out.println(str.length());//后边还有其他代码,可能产生其它异常;但不知道是具体什么异常了}catch(ArithmeticException | ArrayIndexOutOfBoundsException | NullPointerException  e){System.out.println("被除数不能是零");System.out.println("数组下标越界");System.out.println("空指针!");}catch(Exception e){}}}
7、Throwable的常用方法

 * String getMessage():获取异常信息,返回字符串。
 * String toString():获取异常类名和异常信息,返回字符串。
 * void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。在调试时,此方法很有用;

*printStackTrace(PrintStream s)通常用该方法将异常内容保存在日志文件中,以便查阅。 

public class Demo {public static void main(String[] args) {int a = 10;int b = 0;try{//System.out.println( a / b);fun1();}catch(ArithmeticException e){System.out.println("getMessage() : " + e.getMessage());System.out.println("toString() : " + e.toString());e.printStackTrace();}}private static void fun1() {fun2();}private static void fun2() {fun3();}private static void fun3() {System.out.println(10 / 0);}}

8、方法内处理异常的方式一_throws语句

 * 方法内怎样处理异常:
 * 1.总原则:在方法内如果发生异常情况,尽量不要"处理",而是抛给调用者去处理;
 * 2.抛出的方式有两种:
 * 1).在方法声明时,在形参列表之后,使用throws关键字,后面跟一个,或多个异常类型名称;
 *        抛出的异常类型:
 * A.运行时异常:调用方 可以不捕获,编译能通过。但是如果真的发生异常,JVM仍然是结束掉程序;
 * B.非运行时异常:调用方法必须捕获,或者抛出;
 * 2).在方法内部,手动的"抛出"一个"异常对象";使用关键字:throw
 *       抛出的异常类型:
 * A.运行时异常:1.方法可以不声明throws此类型异常;2.调用方可以不捕获;
 * B.非运行时异常:1.方法声明处,必须显示的throws此类型异常;2.调用方必须捕获或者抛出;

public class Demo {public static void main(String[] args) {try{//System.out.println(getMax(null));//getMax()方法抛出的是:运行时异常。调用方可以不捕获,编译能通过;//System.out.println(getMax2(null));System.out.println(getMax3(null));}catch(NullPointerException e){System.out.println("异常信息:" + e.getMessage());}/*String str = "2015-09-20";try {Date date = stringToDate(str);//stringToDate()方法抛出的是:非运行时异常。调用方必须捕获,或者抛出;} catch (ParseException e) {// TODO Auto-generated catch blocke.printStackTrace();}*/}public static int getMax(int[] array) throws NullPointerException,<span style="white-space:pre"></span>ArithmeticException,ArrayIndexOutOfBoundsException{int max = array[0];//产生异常,JVM实例化一个NullPointerException对象;for(int i = 0;i < array.length ; i++){max = array[i] > max ? array[i] : max;}return max;}//将String转换为Datepublic static Date stringToDate(String str) throws ParseException{SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date date = sdf.parse(str);return date;}//测试throwpublic static int getMax2(int[] array){try{int max = array[0];//产生异常,JVM实例化一个NullPointerException对象;for(int i = 0;i < array.length ; i++){max = array[i] > max ? array[i] : max;}return max;}catch(NullPointerException e){e = new NullPointerException("大哥,你给我传了一个空指针!你这是要害我啊!!");throw e;}}public static int getMax3(int[] array) {if(array == null){throw new NullPointerException("空指针异常!");}int max = array[0];//产生异常,JVM实例化一个NullPointerException对象;for(int i = 0;i < array.length ; i++){max = array[i] > max ? array[i] : max;}return max;}}

9、throws和throw的区别

 * throws和throw都是用于处理方法内的异常的;而且都是抛出;
 * 1.throws :
 * 1).用在"方法声明处";它表示:此方法"可能"会抛出某种类型的异常;
 * 2).后面跟的是"异常类型名称",而且可以有多个,用逗号隔开;

  *3)表示抛出异常,由该方法的调用者来处理
 * 2.throw:
 * 1).用在"方法体内";它表示:真正的抛出一个"异常对象";
 * 2).后面跟的是"异常对象",只能有一个;

*3)表示抛出异常,由方法体内的语句处理

*4)throw则是抛出了异常,执行throw则一定抛出了某种异常

10、到底如何处理异常

 * 1.在main()方法内,使用try_catch语句,捕获并且处理异常;
 * 2.在某个方法内:可以捕获,但不要处理异常,一般都是抛给调用者处理:
 * 抛出的方式有两种:
 * 1).throws:
 * 2).throw:


11、finally语句

 * finally语句:
 * try{
 * //可能会出现异常的代码
 * }catch(异常类型 变量名){
 * //如果出现异常,会被执行的代码;
 * }finally{
 * //无论是否出现异常,都会被执行的代码;
 * //一般,这里用来释放一些很占用空间的"资源";
 * }


public class Demo {public static void main(String[] args) {fun();}public static void fun(){try{int a = 10;int b = 10;System.out.println(a / b);}catch(Exception e){System.out.println("catch");}finally{//无论是否发生异常,这里的代码都会被执行的到;System.out.println("finally");}}}

12、try_catch_finally的常见组合

 * 1.try...catch...:
 * 2.try...catch....catch...catch:
 * 3.try...catch....finally
 * 4.try...catch....catch...catch...finally:
 * 5.try...finally:

13、面试题之final_finally和finalize的区别

 * final:最终的,可以修饰:
 * 类:最终类,不能被继承
 * 方法:最终方法,不能被重写
 * 变量:拥有最终的值,只能被赋值一次,之后不能被更改:
 * 基本类型:值不能更改;
 * 引用类型:地址不能被更改;
 * finally:异常处理的关键字。无论是否出现异常,都会被执行的代码块;
 * finalize:Object类的一个方法。当垃圾回收器回收此对象空间之前,会调用的一个方法;

14、面试题之finally中有return语句

public class Demo {
public static void main(String[] args) {
System.out.println(fun());
}
public static int fun(){
int n = 10;
try{
n = 20;
return n;//1.执行return语句,先将20缓存;2.执行finally;3.返回缓存中的值;
}catch(Exception e){
n = 30;
return n;
}finally{
System.out.println("finally");
n = 40;
return n;
}
}
}

15、面试题之finally中有return语句

public class Demo {public static void main(String[] args) {System.out.println(fun());}public static int fun(){int n = 10;try{n = 20;return n;//1.执行return语句,先将20缓存;2.执行finally;3.返回缓存中的值;}catch(Exception e){n = 30;return n;}finally{System.out.println("finally");n = 40;return n;}}}

16、自定义异常

 * 1.Java类库中的异常类,不足以满足我们的要求;
 * 2.有时候我们需要我们自己的异常类型:
 * 例如:接收一个年龄值,我们业务上要求年龄值必须在:15--50之间;
 * 3.自定义异常:
 * 1).自定义类,继承自某个异常类,或者Exception
 * 2).最好提供一个带String参数的构造方法,用于指定"异常消息";
 * 3).注意:如果我们的异常类直接继承自Exception,那么我们的异常是:非运行时异常;

class AgeException extends Exception{public AgeException(){super();}public AgeException(String message){super(message);}}class Student{private int age;public void setAge(int age) throws AgeException{if(age < 15 || age > 50){//抛出异常throw new AgeException("年龄必须在15--50之间");}}}public class Demo {public static void main(String[] args) {Student stu = new Student();try {stu.setAge(10);} catch (AgeException e) {System.out.println("异常了:" + e.getMessage());}}}

17、重写父类方法时的异常处理

 * 父类方法不抛出异常:
 * 子类:1.也可以不抛出;
 * 2.可以抛出任何的运行时异常;
 * 3.不能抛出任何的非运行时异常;
 * 父类方法抛出运行时异常:
 * 子类:1.可以不抛出任何异常;
 * 2.可以抛出任何的运行时异常;
 * 3.不能抛出任何的非运行时异常;
 * 父类方法抛出非运行时异常:
 * 子类:1.可以不抛出任何异常;
 * 2.可以抛出任何的运行时异常;
 * 3.不能抛出比父类更多的非运行时异常;
 * 
 * 综上所述:
 * 无论父类方法是否抛出任何类型异常:
 * 子类:1.可以不抛出任何异常;
 * 2.可以抛出任何的运行时异常;
 * 如果父类抛出非运行时异常,子类不能抛出比父类更多的非运行时异常;


二、File类

1、File类概述

 * java.io.File(类):代表磁盘上的一个文件或目录:
 * 
 * 此类的一个对象,可以获取文件的大小、绝对路径、是否可读、是否可写.....
 * 
 * 构造方法:
 * public File(String pathname):使用一个String封装的目录构造一个File对象
 * public File(String parent,String child):使用父级目录和子目录构造一个File
 * public File(File parent,String child):使用File表示的父目录和String的子目录构造一个File
 * 
 * 绝对路径:带盘符的全路径的文件名;
 * 相对路径:指在当前项目运行的目录下;

public class Demo {public static void main(String[] args) {//File file = new File("D:\\test\\test.txt");//使用绝对路径构造File file = new File("C:\\Java\\java.txt");//File file2 = new File("test.txt");//使用相对路径构造////File file3 = new File("C:\\test","test.txt");//此对象跟file表示的路径相同;////File file4 = new File("C:\\test");//File file5 = new File(file4,"test.txt");}}
2、File类创建功能

 * 创建功能
 * public boolean createNewFile():创建文件
 * public boolean mkdir():创建单级目录;
 * public boolean mkdirs():创建多级目录;

public class Demo {public static void main(String[] args) {File file = new File("demo30.txt");try {System.out.println("创建文件:" + file.createNewFile());} catch (IOException e) {e.printStackTrace();}File file2 = new File("test\\aaaa");//file2.createNewFile();//建立的仍然是文件System.out.println("创建单级目录:" + file2.mkdir());File file3 = new File("test2\\aaa2\\bbb2\\ccc2");System.out.println("创建多级目录:" + file3.mkdirs());}}
3、File类删除功能
 * public boolean delete():用于删除文件,和"空目录":不走Windows回收站;
 * 如果是多级目录,或者非空目录,一定要先清理目录下的所有内容后,才能删除,后边我们做练习会使用递归删除;

public class Demo {public static void main(String[] args) {File file = new File("demo30.txt");System.out.println("删除文件:" + file.delete());File file1 = new File("test");System.out.println("删除目录:" + file1.delete());}}
4、File类重命名功能

 * public boolean renameTo(File dest)
 * 相同目录:重命名文件;
 * 不同目录:剪切,并重命名;(自己试了,得在同一磁盘下可以)

public class Demo {public static void main(String[] args) {File file = new File("C:\\test\\test.txt");//System.out.println("重命名文件:" + file.renameTo(new File("C:\\test\\myFile.txt")));System.out.println("重命名文件:" + file.renameTo(new File("myFile.txt")));}}
5、File类重判断功能

 * public boolean isDirectory():判断是否是目录
 * public boolean isFile():判断是否是文件
 * public boolean exists():文件或目录是否存在
 * public boolean canRead():是否可读;
 * public boolean canWrite():是否可写
 * public boolean isHidden():是否隐藏;

public class Demo {public static void main(String[] args) {File file = new File("Myfile.txt");//对于文件名,这里和磁盘上的文件名不区分大小写;System.out.println("是否是一个目录:" + file.isDirectory());System.out.println("是否是一个文件:" + file.isFile());System.out.println("文件或目录是否存在:" + file.exists());System.out.println("是否可读:" + file.canRead());System.out.println("是否可写:" + file.canWrite());System.out.println("是否隐藏:" + file.isHidden());}}

6、File类获取功能

 * public String getAbsolutePath():获取绝对路径;
 * public String getPath():获取File封装的路径;
 * public String getName():获取文件/目录的名称
 * public long length():获取文件/目录的大小;单位:字节
 * public long lastModified():获取文件/目录的最后修改时间;单位:毫秒

public class Demo {public static void main(String[] args) {File file = new File("myFile.txt");System.out.println("绝对路径:" + file.getAbsolutePath());System.out.println("File封装的路径:" + file.getPath());System.out.println("文件名:" + file.getName());System.out.println("文件大小:" + file.length() + " 字节");System.out.println("最后修改时间:" + file.lastModified() + " 毫秒");long time = file.lastModified();Date date = new Date(time);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String str = sdf.format(date);System.out.println("最后修改时间:" + str);}}

7、File类高级获取功能
 * 高级获取功能
 * public String[] list():获取当前目录下所有的文件、目录的名称;
 * public File[] listFiles():获取当前目录下所有文件、目录的File数组
 * 这两个方法区别:
 * 1.第一个方法简单的返回了此目录下所有文件/目录的"名称";
 * 2.第二个方法是将目录下的每个文件/目录又封装为一个File对象,并存到一个File[]数组中。
 *  如果我们需要在获取后,对每个文件需要进一步的操作,可以使用此方法比较方便;

public class Demo {public static void main(String[] args) {File file = new File("C:\\20150822");String[] fileArray = file.list();for(String s : fileArray){System.out.println(s);}System.out.println("-----------------------------------------------------");File[] fileArray2 = file.listFiles();for(File f : fileArray2){System.out.println(f.getAbsolutePath());}}}
8、输出指定目录下指定后缀名的文件(练习)

* 输出C:\\test\\所有的.java文件
 * 1.封装初始目录:File file = new File("C:\\test");
 * 2.获取目录下的所有的文件/目录的名称-->File[]数组
 * 3.遍历File[]数组,分别判断每个File是否是文件:
 * 是:判断是否.java结尾;
 * 是:输出:
 * 否:--
 * 否:---

public class Demo {public static void main(String[] args) {File file = new File("C:\\test");File[] fileArray = file.listFiles();for(File f : fileArray){if(f.isFile() && f.getName().endsWith(".java")){System.out.println(f.getAbsolutePath());}}}}
9、批量修改文件名称案例(练习)

 * 将C:\\20150822\\day18下的所有的avi文件,
 * 存储到:"c:\\20150822\\day18\\avi"目录下;
 * 并且要将原文件名中的所有的"集合框架"字样去掉。
 * 步骤:
 * 1.封装原目录:
 * 2.封装目标目录:
 * 3.判断目标目录是否存在,如果不存在,则创建;
 * 4.获取原目录下的所有的.avi文件:使用文件过滤器;
 * 5.遍历所有.avi文件的数组:
 * 1).获取每个avi文件的文件名;
 * 2).将文件名中的"集合框架"字样去掉;
 * 3).重命名到新目录;

public class Demo {public static void main(String[] args) {File srcFile = new File("C:\\20150822\\day18");File destFile = new File("C:\\20150822\\day18\\avi\\");//判断目标目录是否存在if(!destFile.exists()){destFile.mkdir();}//获取原目录下所有的.avi文件File[] fileArray = srcFile.listFiles(new FilenameFilter(){@Overridepublic boolean accept(File dir, String name) {File file = new File(dir,name);if(file.isFile() && file.getName().endsWith(".avi")){return true;}return false;}});//遍历数组for(File f : fileArray){//获取原文件名String name = f.getName();//去掉集合框架字样name = name.replace("集合框架", "");f.renameTo(new File(destFile,name));}System.out.println("复制结束!");}}
10、文件过滤器

 * 在File中还有两个list()和listFiles()的重载方法:
 * public String[] list(FilenameFilter filter)
 *  public File[] listFiles(FilenameFilter filter)

public class Demo {public static void main(String[] args) {File file = new File("E:\\传智播客(上)");String[] fileNameArray  = file.list(new FilenameFilter(){@Overridepublic boolean accept(File dir, String name) {//return false;//全不匹配//return true;//全部匹配//写我们自己的匹配逻辑System.out.println("dir = " + dir + " name = " + name);//File file = new File(dir,name);//我们需要确定这个File要是一个文件,所以要构造一个File对象/*if(file.isFile() && file.getName().endsWith(".java")){return true;}*/return false;}});for(String s : fileNameArray){System.out.println(s);}}}
三、递归

 1、递归的概念

 * 递归:
 * 1.我们知道:在一个方法内,可以调用另一个方法;
 * 2.另外:在一个方法内,也可以调用它自身,这种方法调用本身的方式,就叫:方法的递归调用;
 * 递归的注意事项:
 * 1.要有出口,否则就是死递归;
 * 2.次数不能太多,否则就内存溢出;
 * 3.构造方法不能递归使用;在编译时,就会编译错误;

class Student{String name;public Student(){this("刘德华");}public Student(String name){//this();this.name = name;}}public class Demo {private static int num = 1;public static void main(String[] args) {fun1();}private static void fun1() {System.out.println("fun1()-->num = " + num);num++;fun2();}private static void fun2() {System.out.println("fun1()-->num = " + num);num++;fun3();}private static void fun3() {System.out.println("fun1()-->num = " + num);num++;fun4();}private static void fun4() {System.out.println("fun1()-->num = " + num);num++;fun5();}private static void fun5() {System.out.println("fun1()-->num = " + num);num++;}}

2、递归练习_求5的阶乘

 * 练习:求5的阶乘;
 * 1.5的阶乘,表示为:5!
 * 2.5的阶乘 = 5 * 4 * 3 * 2 * 1
 * 方式一:使用循环:
 * 方式二:使用递归调用:
 * 1).将问题进行分解:
 * 5!
 *   =5 * 4!
 *   =5 * 4 * 3!
 *   =5 * 4 * 3 * 2!
 *     =5 * 4 * 3 * 2 * 1!

public class Demo {public static void main(String[] args) {int num = 1;int result = 1;while(num <= 5){result *= num;num++;}System.out.println("循环结果:" + result);//System.out.println("阶乘结果:" + jieCheng5());System.out.println("阶乘结果:" + jieCheng(5));}public static int jieCheng(int num){if(num == 1){return 1;}return num * jieCheng(num - 1);}


3、递归练习_不死神兔问题案例

 * 不死神兔问题案例:
 * 有一对兔子,从第三个月开始,每月都会生一对小兔子;小兔子也是从第三个月开始,每月也会再生一对
 * 小兔子,问:假如兔子不死,第20个月,一共有多少对兔子?
 * 月份: 1 2 3 456....20
 * 兔子: 1 1 2 358....? (斐波那契数列)
 * 方式一:使用数组
 * [0] [1] [2] [3] [4] [5] ... [19]
 * 1 12358 ...[17] + [18]
 * 方式二:使用递归:

public class Demo {public static void main(String[] args) {int month = 20;int[] intArray = new int[month];for(int i = 0;i < intArray.length ; i++){if(i == 0 || i == 1){intArray[i] = 1;continue;}intArray[i] = intArray[i - 1] + intArray[i - 2];}System.out.println(month + " 月后,兔子一共有:" + intArray[intArray.length - 1] + " 对");System.out.println("递归求20个月兔子数:" + fib(20));}public static int fib(int m){if(m == 1 || m == 2){return 1;}return fib(m - 1) + fib(m - 2);}}


4、递归练习_递归输出指定目录下所有的java文件的绝对路径
* 递归输出指定目录下所有的java文件的绝对路径
 * 
 * 题目:列出C:\\20150822\\
 *        目录下所有的.java文件;
 * 
 * 步骤:
 * 1.封装初始目录:File file = new File("C:\\20150822");
 * 2.列出目录下所有的文件和目录的数组:File[] fileArray = file.listFiles();
 * 3.遍历数组:
 * 1).判断是否是文件,并且以.java结尾:
 * 是:输出;
 * 否:判断是否是目录:
 * 是:回到第2步;(从第2步到这里,就可以作为一个方法,来递归调用)

public class Demo {public static void main(String[] args) {File file = new File("C:\\20150822");listFiles(file);System.out.println("程序结束!");}private static void listFiles(File file){if(file == null){return;}File[] fileArray = file.listFiles();if(fileArray != null){for(File f : fileArray){if(f.isFile() && f.getName().endsWith(".java")){System.out.println(f.getAbsolutePath());}else if(f.isDirectory()){listFiles(f);}}}}}
5、递归练习_删除带内容的目录案例

* 递归删除带内容的目录案例:
 * 1.由于File的delete方法只能删除文件,或者一个"空目录";
 * 2.所以我们需要递归先删除某个目录下的所有文件,然后再删除此目录;
 * 注意:大家做练习时,一定要复制一个目录,删除复制的目录;
 * 步骤:
 * 1.封装初始目录;
 * 2.先判断是否文件:
 * 是:直接删除;
 * 否:1.获取目录下所有的文件和目录:listFiles();
 *   2.遍历数组;
 *   3.回到步骤2。(步骤2到这里,可以作为一个递归方法)

public class Demo {public static void main(String[] args) {File file = new File("c:\\test\\fdsaf.java");deleteFile(file);System.out.println("删除完毕!");}private static void deleteFile(File file) {if(file == null){return;}if(file.isFile()){//file是个文件file.delete();//删除文件}else{//file是目录File[] fileArray = file.listFiles();for(File f : fileArray){deleteFile(f);}file.delete();//删除目录}}}

总结:

一.异常处理:

         1.基本语法:try...catch

         2.多catch:try...catch...catch...catch

           注意:每个catch的异常类型可以是"平级的",不分先后顺序;

                   可以可以是"子父关系",父类的必须放在最后;

         3.JDK7的多catch语句:try...catch(异常类型1 |异常类型2 | 异常类型3  e)

           注意:一定要是"平级关系",不能是"子父关系"

         4.finally语句:

                   A:try...catch...finally

                   B:特点:无论在try中是否发生异常,都会被执行;

         5.throws和throw:

                   A:throws

                            1).用在方法声明处;

                            2).后面写类名;可以有多个;

                            3).如果抛出的是"运行时异常":

                                     调用处可以不捕获,也可以捕获;

                               非运行时:

                                     调用处必须捕获;

                   B:throw:

                            1).用在方法体内;

                            2).后面写对象的引用;只能有一个;

                            3).运行时:

                                     a).可以不用声明throws

                                     b).调用处可以处理,可以不处理;

                               非运行时:

                                     a).方法必须声明throws这个类型的异常;

                                     b).调用处必须处理;

                  

         6.Throwable的几个常用方法:

                   1).getMessage():获取异常信息;

                   2).toString():调用重写的toString()方法

                   3).printStackTrace():打印堆栈异常;

         7.自定义异常:

                   1).我们可以根据我们的业务逻辑,编写我们自己的异常类;

                   2).自定义一个类,继承自Exception或其它子类即可;

                   3).通常会添加一个带String参数的构造方法:指定异常信息;

         8.子类重写父类方法时:

                   无论父类方法是否抛出异常,子类方法都可以不抛出任何异常;

                   也可以抛出任何的运行时异常;

                   如果父类抛出的是"非运行时异常",子类不能抛出比父类更多的"非运行时异常"       

二.File类:

         1.它代表了磁盘上的一个文件或者文件夹;

         2.构造一个File对象,文件或者目录可以不存在:后期可以通过一些方法验证文件是否存在;

                   File file = new File("r34fsfdsf;");//可以构造的

         3.File类的常用方法:

二.File类:

         1.构造方法:

                   public File(String pathname)

                   public File(String parent,String child)

                   public File(File parent,String child)

         2.创建功能

                   public boolean createNewFile():

                   public boolean mkdir()

                   public boolean mkdirs()

         3.删除功能

                   public boolean delete()

         4.重命名功能

                   public boolean renameTo(File dest)

         5.判断功能

                   public boolean isDirectory()

                   public boolean isFile()

                   public boolean exists()

                   public boolean canRead()

                   public boolean canWrite()

                   public boolean isHidden()

         6.基本获取功能

                   public String getAbsolutePath()

                   public String getPath()

                   public String getName()

                   public long length()

                   public long lastModified()

         7.高级获取功能

                   public String[] list()

                   public File[] listFiles()












0 0
原创粉丝点击