黑马程序员————java基础--------IO输入输出之异常、File类和递归

来源:互联网 发布:js贪吃蛇程序设计报告 编辑:程序博客网 时间:2024/05/30 05:15
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


第一部分 异常

异常按照情况的严重性,可以分为Error和Exception。Error是比较严重的情况,比如内存溢出,不是写程序本身的情况。Exception则又按照其出现的时间,分为编译期异常和运行期异常。运行期异常是:RuntimeException,非RuntimeException的异常都属于编译期异常。
运行期异常是代码不够严谨。


如果程序出现了问题,我们没有做任何处理,最终JVM就会做出默认的处理。将异常的名称,原因及出现的问题等信息输出控制台。同时会结束程序。虽然JVM给出了我们提示信息,但是其同时也结束了程序运行。这就导致程序不能执行完,为了能够将一些无关紧要或者局部问题排除掉,并且程序继续执行,这个时候就需要自己处理,抛出异常。
处理异常两种方式:
(一)、try...catch....finally
(二)、throws 抛出


前者的处理格式为
try{
可能出现问题的代码;
}catch(异常名 变量){
针对问题的处理;
}finally{
释放资源;
}
注意:try里面的问题越少越好。因为这里的代码越多,需要处理的信息就会越多,JVM就要分配更多的资源来处理。

catch里面必须有内容,哪怕是给出一个简单的提示


第一种格式:


try{
...
}catch(异常类名 变量名){
...
}


try{
...
}catch(异常类名 变量名){
...
}
...


第二种格式:
try{
...
}catch(异常类名 变量名){
...
}catch(异常类名 变量名){
...
}


能明确的尽量明确异常类型,如果抛出Exception父类,父类就要再子类中逐一查询。降低了效率。


第三种:jdk1.7之后出现

try{


}catch(异常名1|异常名2|异常名3 变量){
...
}
这里需要注意的是异常名必须是平级关系。不能有父类如Exception。


编译期异常与运行期异常的区别:
运行期异常:只要程序足够严谨,就不会发生运行期异常。
编译期异常:必须处理,否则无法运行。


异常中的方法:
public String getMessags(); 返回该消息的详细信息字符串
public String toStrng():返回异常的简单信息描述
printStackTrace()




(二)、throws:定义功能方法时,需要把出现的问题暴露出来让调用者去处理。就是通过throws在方法上标示。


格式:throws 异常类名
这个格式必须跟在方法的括号后面。
当我们不想处理异常,或者没有能力去处理这个异常的时候,就可以在方法声明上将异常通过throws抛出。这样在调用该方法时,调用者会来处理这个异常。如果调用者也不处理这个异常,而是将这个异常抛给了main方法,结果main方法就给了虚拟机,这样就没有意义了。因为虚拟机会在遇到异常时,终止程序。最好能在被调用的时候将异常处理掉,避免在main方法上抛出异常。

import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class ExceptionDemo {public static void main(String[] args) {System.out.println("我要去黑马");try {method();} catch (ParseException e) {e.printStackTrace();}System.out.println("去黑马有肉吃");}// 编译期异常的抛出// 在方法声明上抛出,是为了告诉调用者,方法有问题public static void method() throws ParseException {String s = "2014-11-20";SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date d = sdf.parse(s);System.out.println(d);}}




上面的这个例子在main方法中调用method();但是method()方法是有异常抛出的,如果调用者直接在main方法上直接抛异常,就会导致程序在运行到method()时就停止了。但是如果通过try..catch..来处理这个异常,最终程序还可以走到"去黑马有肉吃"。


注意:在调用方法时,如果方法声明上有异常,调用者最好处理(编译期异常)。但是如果这种异常是运行期异常,我们就可以不处理。


关键字:throw与throws的区别:
 throw:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。只能抛出一个异常对象名,执行throw,则一定会抛出异常。throws用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开,throws表示出现异常的一种可能性,并不一定会发生。
public static void method(){int a=10;int b=0;if(b==0){throw new ArithmeticException();}else{System.out.println(a/b);}}






finally:
被finally控制的语句体一定会执行。只要虚拟机不退出,就会执行。
public static void show(){int a=10;try{System.out.println(a/0);a=20;}catch{a=30;return a;//走到这一步return 30;//又走回来,return 30.}finally{a=40;//第二步此时a为40}return a;}






第二部分File类
文件和目录路径名的抽象表示形式。


File类的常用操作及演示


构造方法:
public File(String pathname) 根据一个路径得到File对象
public File(String parent,String child)根据一个目录和一个子文件得到一个对象
public File(File parent,String child) 根据一个父File对象和一个子文件/目录得到File对象。
通过构造方法,我们可以建一个File类的对象,通过File类的对象,可调用其方法。


第一种File构造方法:


import java.io.File;public class FileDemo{public static void main(String [] args){//创建一个对象file1,其指向e盘的itheima文件夹。File file1=new File("e:\\itheima");//在E盘创建一个文件夹,命名为itheima;file1.mkdir();}}



第二种File构造方法


//创建一个对象file。
File file=new File("E:\\itheima","it.txt");
File file2=new File("e:\\itheima\\a.java");
//通过调用创建文件的方式创建文件。
file.createNewFile();
file2.createNewFile();
上面的第一种构造方法创建的对象,通过调用创建文件的方法,先是在E盘里创建了一个名为itheima的文件夹,然后又在该文件夹中创建了一个it.txt的文件。第二种构造方法创建的对象,调用createNewFile()方法时,在已经存在的itheima文件夹中又创建了一个a.java的文件。file2创建文件时,该目录必须已经存在,不然就会报出,“系统找不到指定路径”的异常。




创建功能
public boolean createNewFile()创建文件  抛异常的方法
public boolean mkdir()创建文件夹  不抛异常的方法
public boolean mkdirs())创建多层文件夹


如果要创建多层文件夹时,可以调用mkdirs()。
File file=new File("e\\it\\黑马\\安卓");
file.mkdirs();
系统将会在e盘创建这样一个多层文件夹。
如果在创建File对象时,没有写盘符,将会在当前文件夹中创建。


注意:
File file=new File("e\\黑马\\a.txt");
file.mkdirs();
这里将会在e盘创建一个黑马文件夹,并且在该文件夹的里面再创建一个名为“a.txt”的文件夹。


删除功能
public boolean delete()
例:File file=new File("e:\\heima");
file.delete();
file.delete()方法将会删除e盘中的heima文件夹。








重命名功能
public boolean renameTo(File dest)


File file =new File("e:\\andriod.txt");
file.createNewFile();
File file2=new File("d:\\heima.txt");
file.renameTo(file2);
如果两个路径相同,则是重命名如果两个路径不同,则是重命名并且剪切。上面这个例子,就是将E盘中的andriod.txt文件剪切到D盘根目录下,并且重命名为heima.txt。


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


获取功能:
public String getAbsolutePath() 获取绝对路径
public String getPath()获取相对路径
public String getName()获取文件名
public long length()获取文件长度
public long lastModified()获取最后一次修改毫秒值


高级获取功能
public String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
public File[] listFiles() 获取指定目录下的所有文件或者文件夹的File数组 


public static void main(String [] args){//将e盘目录封装成对象File file=new File("e:\\");//对象调用方法,并且返回给数组str;String [] str=file.list();for(String s:str){//将会把E盘根目录下的文件及文件夹的名称都输出。System.out.println(s);}}


导包运行上面的程序,我们就会发现其输出了e盘根目录下的所有内容,包括隐藏文件等。
另外还有一种方法也能达到这种效果
File [] array=file.listFiles();for(File f:array){//由于f为File类型,因此可以调用其方法getName()来获取文件名。System.out.println(f.getName());}


虽然上面两种方法输出结果一致,但是后者由于返回的是文件对象数据,因此其能够调用更多的方法,用途也更广泛。


注意:绝对路径和相对路径的区别,绝对路径是从盘符开始直到文件名,但是相对路径,则是在当前文件夹下的路径。也就是相对路径,加上当前文件夹的绝对路径,才是这个文件的绝对路径。




练习题:输出D盘根目录下后缀名为.txt的文件。


方法一:
import java.io.File;class FileDemo{public static void main(String [] args){//将E盘根目录转为对象File file=new File("e:\\");File [] array=file.listFiles();for(File f:fileArray){//判断是否为文件if(f.isFile()){//如果是文件,那么它是不是以“.txt”结尾呢?if(f.getName().endsWith(".txt"){//满足上面的条件,就是我们需要输出的。System.out.println(f.getName());}}}}}




方法二:这个方法区别于上面的本质在于不是先获取所有元素,再判断,而是在获取的时候,已经是判断过后满足条件的啦。这里就要用文件过滤器,其方法如下:
public String [] list(FilenameFilter filter) 这个返回的是String数组
public File [] listFiles(FilenameFilter filter) 返回的是File数组


import java.io.File;class FileDemo{public static void main(String [] args){//封装E盘目录File file=new File("e:\\");//通过文件过滤器的匿名实现类对象来创建对象String [] str=file.list(new FilenameFilter(){//重写方法public boolean accept(File dir,String name){//通过File的第三种构造方法,封装目录。File file =new File(dir,name);//判断该文件名是不是文件boolean flag=file.isFile();//判断该文件是不是以".txt"结尾boolean flag2=name.endsWith(".txt");return flag&&flag2;}});for(String s:str){System.out.println(s);}}}






第三部分 递归
定义:方法定义中调用方法本身的现象。(自己调自己,而不是别人调)。


注意:递归一定要有出口,不然就是死递归
递归的次数不能太多,否则就内存溢出
构造方法不能递归使用
5!=5*4*3*2*1;
5!=5^*4!

递归解决问题的思想:

递归方法在加载到栈内存后,由于方法本身调用方法,第一个进栈的递归,将在最下面,他的上面,由于是在不停地调用方法本身,将会形成一种链式结构,直到方法的最终参数值,这是方法的分解。


当到达方法的最终值时,方法就开始运算,然后逐层消失,直到回到最高层的递归方法。

练习题:

输出斐波拉契数列:1,1,2,3,5,8,13.21,34,55

public class Test8 {public static void main(String [] args){for(int x=1;x<21;x++){System.out.println(show(x));}System.out.println("*********");System.out.println(array(20));}//数组实现public static int array(int n){int[] arr = new int[n];arr[0] = 1;arr[1] = 1;int s=2;// arr[2] = arr[0] + arr[1];// arr[3] = arr[1] + arr[2];// ...for (int x = 2; x < arr.length; x++) {arr[x] = arr[x - 2] + arr[x - 1];s=arr[x];}return s;}//递归方法。不是if...else连用,还需要在方法体外面实现返回。public static int show(int n){int s=2;if(n==1||n==2){return 1;} if(n>2){s= (show(n-2)+show(n-1));}return s;}//递归方法。如果是if...else连用,就不用再在方法体外面return返回值了。public static int fib(int n) {if (n == 1 || n == 2) {return 1;} else {return fib(n - 1) + fib(n - 2);}}//for循环变量第一种public static int ForDemo(int n){if(n==1||n==2){return 1;}int a=1;int b=1;int c=2;for(int x=2;x<n;x++){c=a+b;a=b;b=c;}return c;}//for循环变量第二种public static int ForDemo1(int n){if(n==1||n==2){return 1;}int a=1;int b=1;for(int x=2;x<n;x++){int temp=a;a=b;b=temp+b;}return b;}}



输出e盘下的所有.java文件的绝对路径。
public static void main(String [] args){File file=new File("e:\\");getAlljava(file);}public static void getAlljava(File file){File [] fileArray=file.listFiles();for(File file1:fileArray){if(file1.isDirectory()){getAlljava(file1);}else{if(file1.getName().endsWith(".java")){System.out.println(file1.getAbsolutePath());}}}}



删除e盘下所有内容:
public static void main(String[] args) {// 封装目录File srcFolder = new File("demo");// 递归实现deleteFolder(srcFolder);}private static void deleteFolder(File srcFolder) {// 获取该目录下的所有文件或者文件夹的File数组File[] fileArray = srcFolder.listFiles();if (fileArray != null) {// 遍历该File数组,得到每一个File对象for (File file : fileArray) {// 判断该File对象是否是文件夹if (file.isDirectory()) {deleteFolder(file);} else {System.out.println(file.getName() + "---" + file.delete());}}System.out.println(srcFolder.getName() + "---" + srcFolder.delete());}}


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
0 0
原创粉丝点击