@w460461339
2016-11-16T07:04:59.000000Z
字数 4939
阅读 917
Java基础
今天学习的是异常以及File类。这些都是为了之后学习file IO做的预备工作。另外,由于毕设时间迫近,还需要开始申请一些学校,所以这段时间会暂停一下Java的学习工作
下面这张图片很好的介绍了异常的分类:
可以看到,异常的顶层接口是Throwable,下面分error以及exception;exception下面又分RuntimeException以及非RuntimeException的。其中Error是诸如内存溢出的严重错误,我们不需要考虑。RuntimeException是运行时的错误,通常是由于我们程序不严谨的造成的,所以一般也不用异常处理。剩下的Exception中非RuntimeException的部分,就是在编译时会产生的异常。这个编译时会产生的异常就是我们需要考虑修正的部分了。
对于异常的处理,我们大致有两种方法,介绍如下。
这个比如说我们数组越界,尝试用0作为除数时都会遇到,在控制台创空中显示超多红红的东西,那个就是JVM自己做的异常处理。注意到,一旦JVM进行异常处理之后,所有后面的程序都不会再被运行。
public stativ void main(String args[]){
int a=10;
int b=0;
int c=a/b;//JVM在此处抛出默认异常
System.out.println("HI");//由于上一句有异常,这句不会执行
}
若我们希望在抛出异常之后,之后的程序继续运行,就需要自己写异常处理。异常处理有两种格式:try...catch..finally;以及throws。
Way1:try..catch..finally
格式:
/*
try{
有可能出问题的语句;
}catch(异常名称 变量名){
处理方式;
}finally{
处理方式;
}
*/
int a=10;
int b=0;
int c=0;
try{
c=a/b;
}catch(ArithmeticException e){
System.out.println("Not zero");
}finally{
System.out.println("Fool");
}
异常名称可以通过运行下看来得到。比如除数为0的异常就是:ArithmeticException 当然这是个RuntimeException,所以我们一般通过修改代码而非异常的方式解决问题。
之前讲的是最标准的格式,还有其他的变种格式可以使用:
try...catch...finally
try...catch...
try...catch...catch...
try...catch...catch...fianlly
try...finally
另外,关于finally,它是一定会执行的语句,主要用于释放资源。在特殊情况下, 比如catch执行完了,结束了JVM(System.exit(0)),那它就不会执行了。
Way2:throws
throws主要是用在声明这个方法有问题的情况下,该方法自己解决不了,因此抛出一个异常,让调用它的“人”去解决。
这里说明下,throws用在方法头上,表示该方法有可能出错,需要调用者解决。这个错误可能没有,可能有一颗,可能有两个(之间用逗号隔开就好)……所以这个不保证一定有异常。
另外,根据之前说的运行异常以及编译异常,当throws的异常是RuntimeException时,调用者可以选择解决,也可以忽视(就是什么也不管)。但是如果throws的是编译时异常,那么调用者一定要用try..catch..finally(自定义方法)去解决它(后续程序可以继续运行)或者用throws抛向上一级(相当于执行JVM默认异常处理方法,后续程序不可进行)。两者必选其一,不然不给过编译。
另外,方法抛出的异常种类可以直接进源码中去查看,这样catch就知道是什么类型的异常了。
//这个是SimpleDateFormat下的parse方法,可以看到,它抛出一个异常
//那么,调用它的时候就需要对这个异常处理
public static void main(String args[]) throws ParseException{
SimpleDateFormat ss=new SimpleDateFormat();
ss.parse(source);//会报错,要么用下面的,要么用上面的只能选一个
//实际工作中,点旁边的灯泡,看提示就好
/*try{
ss.parse(source);
}catch(ParseException e){
System.out.println("HI");
}*/
//可以不写finally
}
public Date parse(String source) throws ParseException
{
ParsePosition pos = new ParsePosition(0);
Date result = parse(source, pos);
if (pos.index == 0)
throw new ParseException("Unparseable date: \"" + source + "\"" ,
pos.errorIndex);
return result;
}
另外再说一点,还有一个叫做throw的东西,它和throws最大的区别,就是,throws用在方法头上,throw则用在方法内部。使用throw表示一定会出现异常。它抛出的是一个具体的异常对象(所以需要new),不想throws只抛出一个异常类型名称。
同样,若抛出的是一个RuntimeException,可以不写throws,在调用的时候也可不管,但是若是编译时异常,则throws和调用的时候都要管!!!
继承自Exception或者RuntimeException,只需要提供无参构造和一个带参构造即可。带参构造函数一般传递一个String类型对象,只要用super传回父类中去就好。
父类异常和子类异常:
A:父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常
B:父的方法没有异常抛出,子的重写方法不能有异常抛出
C:父的方法抛出多个异常,子的重写方法必须比父少或者小
File类对象得到的只是一个文件和目录路径名的抽象表示形式。所以文件存在不存在跟这个没关系。对文件的创建,修改,获取等操作可以通过它定义的方法来实现。
它一共有四个构造方法,这里指放三个:
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例(文件或者文件夹都可以)。
File(String parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例(文件或者文件夹都可以)。
File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例(文件或者文件夹都可以)。
public static void main(String args[]){
File file1=new File("E:\\demo\\a.txt");//注意两个‘\’。
File file2=new File("E:\\demo","a.txt");
//这三种方法效果一样
File file3=new File("E:\\demo");
File file4=new File(file3,"a.txt");
}
这里注意,此时无论是文件还是文件夹都没有被创建,只是定义了一个抽象路径名。
创建功能有三个:
public boolean creatNewFile();//创建文件(只能是文件)
public boolean mkdir();//创建文件夹(一次创建一个)(只能是文件夹)
public boolean mkdirs();//创建多层文件夹(只能是文件夹)
这里不一一尝试了。另外需要注意,不能在不存在的目录下创建文件或者文件夹。
public static void main(String args[]){
File file1=new File("E:\\test");
file1.mkdir();//可以,在E盘下创建了test文件夹
File file2=new File("E:\\test\\aaa");
file2.mkdir();//不行,因为E盘下没有test文件夹。
//创建文件什么的同理。这里不演示。
}
无论是“demo”还是“a.txt”这样的名称,都可以作为文件或者文件夹的名字。所以在构造的时候,无所谓你取什么名字。(即,既可以存在a.txt的文件夹,也可以存在demo的文件,具体类型只是看创建是创建啥。)
代码:
public boolean delete();
它是不管文件还是文件夹通删,但是注意只能从最内层往外面删,不能直接删了一个里面还有东西的文件夹。
另外,它的删除是不经过回收站的,所以就是直接全删除了,用的时候注意!
public static void main(String args[]){
File file1=new File("D:\\test\\aaa\\bbb");
file1.mkdirs();//在D盘下创建test\aaa\bbb三层文件夹
File file2=new File(file1,"a.txt");
file2.creatNewFile();//在D盘下test\aaa\bbb下创建文件a.txt
file2.delete();//此时file2储存的是D:\test\aaa\bbb\a.txt;
//所以删除的是a.txt;
File file3=new File("D:\\test\\aaa");
file3.delete();//并不会删除成功,返回false
File file4=new File("D:\\test\\aaa\\bbb");
file4.delete();//返回true
}
代码:
public boolear renameTo(File dest);
相当于把原来File对象的值填到现在的dest中。可以同目录,也可以跨目录做。
public static void main(){
File file=new File("D:\\test\\aaa");
File file1=new File("D:\\test\\aaa\\a.txt");
File file2=new File("D:\\test\\aaa\\b.txt");
File file3=new File("D:\\test\\c.txt");
//注意,并不存在test以及a.txt以及b.txt文件
file.mkdirs();//创建文件夹
file1.createNewFile();//创建文件
file1.renameTo(file2);//同一目录,相当于重命名
file1.renameTo(file3);//不同目录,相当于剪切+重命名
}
代码:
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数组