【JavaSE(十二)】JavaIO流(上)

1 异常

1.1 异常概述

异常就是Java程序在运行过程中出现的错误。

程序的异常:Throwable类是 Java 语言中所有错误或异常的超类,其子类有两个分别是

  • 严重问题:Error类,不处理。用于指示合理的应用程序不应该试图捕获的严重问题。比如说内存溢出
  • 问题:Exception类指出了合理的应用程序想要捕获的条件,其分为两种
    • 编译期问题:非RuntimeException类的异常必须显式处理,否则程序就会发生错误,无法通过编译
    • 运行期问题:RuntimeException类无需显示处理(也可以和编译时异常一样处理),因为这个问题出现肯定是我们编写的代码不够严谨,需要修正代码的(比如ArithmeticException异常的运算条件)

异常的处理:

  • 1.JVM默认处理:如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理:把异常的名称,原因及出现的问题等信息输出在控制台,同时会结束程序。
  • 2.自行处理
    • A:try...catch...finally 捕获异常
    • B:throws 抛出异常

1.2 try...catch...finally 捕获异常

捕获异常格式:

//格式一
try {
    可能出现问题的代码;
}catch(异常名 变量) {
    针对问题的处理;
}finally {
    释放资源;
}

//格式二
try {
    可能出现问题的代码;
}catch(异常名 变量) {
    针对问题的处理;
}

下面来看一个简单的捕获异常例子。

public class ExceptionDemo {
    public static void main(String[] args) {
        int a = 10; int b = 0;

        try {
            System.out.println(a / b);
        } catch (ArithmeticException ae) {
            System.out.println("除数不能为0");
        }

        System.out.println("程序结束");
    }
}

/*运行结果:
除数不能为0
程序结束*/

Java中,一旦 try 里面出了问题,就会在这里把问题给抛出去,然后和 catch 里面的问题进行匹配。一旦有匹配的,就执行 catch 里面的处理,然后结束了 try...catch ,继续执行后面的语句。

如果 try 语句块中可能会出现多个问题,则可以使用多个 catch 语句进行捕获异常。比如:

public class ExceptionDemo2 {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int[] arr = { 1, 2, 3 };

        try {
            System.out.println(a / b);
            System.out.println(arr[3]);
            System.out.println("出现异常");
        } catch (ArithmeticException e) {
            System.out.println("除数不能为0");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("你访问了不该的访问的索引");
        } catch (Exception e) {
            System.out.println("出问题了");
        }
    }
}

注意:

  • A:能明确的尽量明确,不要用大的来处理。
  • B:平级关系的异常谁前谁后无所谓;如果出现了继承关系的异常,父类异常必须在后面

JDK7出现了一个新的异常处理方案:

try{
    可能出现问题的代码;
}catch(异常名1 | 异常名2 | ...  变量 ) {
    针对问题的处理;
}

而上述捕获异常部分的代码就可以改进为

try {
    System.out.println(a / b);
    System.out.println(arr[3]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
    System.out.println("出问题了");
}

这个方法虽然简洁,但是也不够好。因为使用这种方式时多个异常间必须是平级关系。也就是这多个异常处理方式需一致(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)。

1.3 异常的方法

Throwable中的方法:

  • public String getMessage():返回异常的消息字符串
  • public String toString():返回异常的简单信息描述
    • 此对象的类的 name(全路径名) + ": "(冒号和一个空格)+ 调用此对象 getLocalizedMessage()方法的结果(默认返回的是getMessage()的内容)
  • public void printStackTrace():返货异常类名和异常信息,以及异常出现在程序中的位置,把信息输出在控制台
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {
    public static void main(String[] args) {
        String s = "2014-11-20";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date d = sdf.parse(s); // 创建了一个ParseException对象,然后抛出去,和catch里面进行匹配
            System.out.println(d);
        } catch (ParseException e) { // ParseException e = new ParseException();
            //e.printStackTrace();

            // getMessage()
            System.out.println(e.getMessage()); // 输出Unparseable date: "2014-11-20"

            // toString()
            System.out.println(e.toString()); // 输出java.text.ParseException: Unparseable date: "2014-11-20"
        }

        System.out.println("over");
    }
}

1.4 throws 抛出异常

有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出

格式:throws 异常类名。注意,这个格式必须跟在方法的括号后面,而且尽量不要在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();
        }
        //如果将ParseException抛出给main方法,即交给JVM解决
        //最终运行method();完之后程序就结束了,不会输出下面这句话
        System.out.println("但是就是不该有雾霾"); 

        method2();
    }

    // 运行期异常的抛出 不会提示解决方案
    public static void method2() throws ArithmeticException {
        int a = 10;
        int b = 0;
        System.out.println(a / b);
    }

    // 编译期异常的抛出 会提示解决方案
    // 在方法声明上抛出,是为了告诉调用者,你注意了,我有问题。
    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);
    }
}
//运行结果:
今天天气很好
java.text.ParseException: Unparseable date: "2014-11-20"
    at java.text.DateFormat.parse(Unknown Source)
    at cn.i1.demo.method(demo.java:32)
    at cn.i1.demo.main(demo.java:11)
Exception in thread "main" 但是就是不该有雾霾
java.lang.ArithmeticException: / by zero
    at cn.i1.demo.method2(demo.java:24)
    at cn.i1.demo.main(demo.java:17)

除了throws还有throw。如果出现了异常情况,我们可以使用 throw 把该异常抛出,这个时候的抛出的应该是异常的对象

throws和throw的区别:

  • throws:表示抛出异常,由该方法的调用者来处理
    • 用在方法声明后面,跟的是异常类名
    • 可以跟多个异常类名,用逗号分隔开
    • throws表示的是出现异常的一种可能性,并不一定会发生这些异常
  • throw:表示抛出异常,由方法体内的语句进行处理
    • 用在方法体内,跟的是异常对象名
    • 只能抛出一个异常对象名
    • 执行throw则一定抛出了某种异常
public class ExceptionDemo {
    public static void main(String[] args) {
        // method();

        try {
            method2();
        } catch (Exception e) { //3.最后由main方法捕获Exception
            e.printStackTrace();
        }
    }

    public static void method() {
        int a = 10;
        int b = 0;
        if (b == 0) {
            throw new ArithmeticException();
        } else {
            System.out.println(a / b);
        }
    }

    public static void method2() throws Exception { //2.然后method2()方法又将Exception抛出给main方法
        int a = 10;
        int b = 0;
        if (b == 0) {
            throw new Exception(); //1.首先这里抛出Exception给method2()方法
        } else {
            System.out.println(a / b);
        }
    }
}

上述代码中,首先在 methon2() 方法中的 if 语句里这里抛出 Exception 给 method2() 方法。然后在 methon2() 方法声明上又将 Exception 抛出给 main 方法。最后由main方法捕获 Exception。

小结:

  • A:运行期异常抛出,调用可以不用处理,其总是由虚拟机接管(另外,出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由 Thread.run() 抛出 ,如果是单线程就被 main() 抛出 。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了)
  • B:编译期异常抛出,JAVA 编译器强制调用者必须处理

异常注意事项:

  • A:子类重写父类方法时,子类的方法必须抛出相同的异常或者父类 异常的子类
  • B:如果父类抛出多个异常,子类重写父类时,只能抛出相同的异常或者是父类 异常的子集,且子类不能抛出父类没有的异常
  • C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常。如果子类内有异常发生,则只能捕获不能抛出

1.5 finally关键字

finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行(特殊情况:在执行到finally之前jvm退出了)。在 finally 代码块中,可以释放资源等收尾善后性质的语句,在IO流操作和数据库操作中会见到。

finally 代码块出现在 catch 代码块最后,格式:try...catch...finally...

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FinallyDemo {
    public static void main(String[] args) {
        String s = "2014-11-20";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date d = null;
        try {
            d = sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
            //System.exit(0); // 在执行到finally之前jvm退出了就不会执行finally语句块
        } finally {
            System.out.println("这里的代码是可以执行的");
        }

        System.out.println(d);
    }
}

/*运行结果:
java.text.ParseException: Unparseable date: "2014-11-20"
    at java.text.DateFormat.parse(Unknown Source)
    at cn.i1.demo.main(demo.java:14)
这里的代码是可以执行的
null
*/

1.fina,finally和finalize的区别?

  • final:最终的意思,可以修饰类,成员变量,成员方法
    • 修饰类,该类不能被继承
    • 修饰成员变量,变量变为自定义常量,不能被改变
    • 修饰成员方法,该方法不能被重写
  • finally:是异常处理的一部分,用于释放资源
    • 一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
  • finalize:是Object类的一个方法,用于垃圾回收

2:如果catch里面有return语句,请问finally里面的代码还会执行吗?如果会,请问是在return前,还是return后?

  • 会运行,在return前
public class FinallyDemo2 {
    public static void main(String[] args) {
        System.out.println(getInt());
    }

    public static int getInt() {
        int a = 10;
        try {
            System.out.println(a / 0);
            a = 20;
        } catch (ArithmeticException e) {
            a = 30;
            return a;
            /*
             * return a在程序执行到这一步的时候,这里不是return a而是return 30; 。此时返回路径就形成了
             * 但是后面还有finally,所以继续执行finally的内容,a=40
             * 最后再次回到以前的返回路径,继续走return 30;
             */
        } finally {
            a = 40;
        }
        return a;
    }
}

3.异常处理的变形

  • try...catch...finally
  • try...catch...
  • try...catch...catch...
  • try...catch...catch...fianlly
  • try...finally

1.6 自定义异常

Java不可能对所有的情况都考虑到,所以在实际的开发中我们可能需要自己定义异常。而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或者RuntimeException,提供无参构造和一个带参构造即可

import java.util.Scanner;

public class demo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生成绩:");
        int score = sc.nextInt();

        Teacher t = new Teacher();
        try {
            t.check(score);
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

class Teacher {
    public void check(int score) throws MyException {
        if (score > 100 || score < 0) {
            throw new MyException("分数必须在0-100之间");
        } else {
            System.out.println("分数没有问题");
        }
    }
}

class MyException extends Exception {
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}

/*运行结果:
请输入学生成绩:
-2
cn.i1.MyException: 分数必须在0-100之间
    at cn.i1.Teacher.check(demo.java:23)
    at cn.i1.demo.main(demo.java:13)
*/

2 File类

2.1 File类概述

IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件。File类是文件和目录路径名的抽象表示形式。

其构造方法有:

  • File(String pathname):根据一个路径得到File对象
  • File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
  • File(File parent, String child):根据一各父目录对象和一个子文件/目录得到File对象
import java.io.File;
public class FileDemo {
    public static void main(String[] args) {
        // File(String pathname):根据一个路径得到File对象
        // 把e:\\demo\\a.txt封装成一个File对象
        File file = new File("E:\\demo\\a.txt");

        // File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
        File file2 = new File("E:\\demo", "a.txt");

        // File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象
        File file3 = new File("e:\\demo");
        File file4 = new File(file3, "a.txt");

        // 以上三种方式其实效果一样
    }
}

2.2 File类功能

创建功能:

  • public boolean createNewFile():如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false
  • public boolean mkdir():创建此抽象路径名指定的目录
  • public boolean mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录

注意:如果路径没有写盘符,默认操作在项目路径下。

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        // 需求:在e盘目录下创建一个文件夹demo
        File file = new File("e:\\demo");
        System.out.println("mkdir:" + file.mkdir());

        // 需求:在e盘目录demo下创建一个文件a.txt
        File file2 = new File("e:\\demo\\a.txt");
        System.out.println("createNewFile:" + file2.createNewFile());

        // 需求:在e盘目录test(不存在的目录)下创建一个文件b.txt
        // 报错:Exception in thread "main" java.io.IOException: 系统找不到指定的路径。
        // 注意:要想在某个目录下创建内容,该目录首先必须存在。
        // File file3 = new File("e:\\test\\b.txt");
        // System.out.println("createNewFile:" + file3.createNewFile());

        // 一次性创建多级目录
        File file4 = new File("e:\\aaa\\bbb\\ccc\\ddd");
        System.out.println("mkdirs:" + file4.mkdirs());
    }
}

删除功能:public boolean delete():删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。执行此操作时,永久性删除(不会丢到回收站)。

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        // 创建文件、文件夹
        File file = new File("e:\\a.txt");
        System.out.println("createNewFile:" + file.createNewFile());
        File file = new File("b.txt");
        System.out.println("createNewFile:" + file.createNewFile());
        File file2 = new File("aaa\\bbb\\ccc");
        System.out.println("mkdirs:" + file2.mkdirs());

        // 删除a.txt这个文件
        File file3 = new File("a.txt");
        System.out.println("delete:" + file3.delete());

        // 删除ccc文件夹
        File file4 = new File("aaa\\bbb\\ccc");
        System.out.println("delete:" + file4.delete());

        // 删除aaa文件夹
        // File file5 = new File("aaa");
        // System.out.println("delete:" + file5.delete()); //返回false,因为aaa下还有bbb文件夹

        File file6 = new File("aaa\\bbb");
        File file7 = new File("aaa");
        System.out.println("delete:" + file6.delete());
        System.out.println("delete:" + file7.delete());
    }
}

重命名功能:public boolean renameTo(File dest):如果路径相同,就是重命名;如果路径不同,就是重命名并剪切。

import java.io.File;
public class FileDemo {
    public static void main(String[] args) {
        // 创建一个文件对象
        File file = new File("林青霞.jpg");
        // 需求:我要修改这个文件的名称为"东方不败.jpg"
        File newFile = new File("东方不败.jpg");
        System.out.println("renameTo:" + file.renameTo(newFile));

        File file2 = new File("c:\\东方不败.jpg");
        File newFile2 = new File("e:\\林青霞.jpg");
        System.out.println("renameTo:" + file2.renameTo(newFile2));
    }
}

判断功能:

  • public boolean isDirectory():判断是否是目录
  • public boolean isFile():判断是否是文件
  • public boolean exists():判断是否存在
  • public boolean canRead():判断是否可读
  • public boolean canWrite():判断是否可写
  • public boolean isHidden():判断是否隐藏
import java.io.File;
public class FileDemo {
    public static void main(String[] args) {
        // 创建文件对象
        File file = new File("a.txt");

        System.out.println("isDirectory:" + file.isDirectory());
        System.out.println("isFile:" + file.isFile());
        System.out.println("exists:" + file.exists());
        System.out.println("canRead:" + file.canRead());
        System.out.println("canWrite:" + file.canWrite());
        System.out.println("isHidden:" + file.isHidden());
    }
}

基本获取功能:

  • public String getAbsolutePath():获取绝对路径
  • public String getPath():获取相对路径
  • public String getName():获取名称
  • public long length():获取长度。字节数
  • public long lastModified():获取最后一次的修改时间,毫秒值
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileDemo {
    public static void main(String[] args) {
        // 创建文件对象
        File file = new File("demo\\test.txt"); //记住首先得有文件存在,因为 new File() 只是在内存中创建File文件映射对象

        System.out.println("getAbsolutePath:" + file.getAbsolutePath());
        System.out.println("getPath:" + file.getPath());
        System.out.println("getName:" + file.getName());
        System.out.println("length:" + file.length());
        System.out.println("lastModified:" + file.lastModified());

        Date d = new Date(file.lastModified());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = sdf.format(d);
        System.out.println(s);
    }
}

高级获取功能:

  • public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
  • public File[] listFiles():获取指定目录下所有文件或者文件夹的File数组
import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        // 指定一个目录
        File file = new File("e:\\");

        // public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
        String[] strArray = file.list();
        for (String s : strArray) {
            System.out.println(s);
        }
        System.out.println("------------");

        // public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
        File[] fileArray = file.listFiles();
        for (File f : fileArray) {
            System.out.println(f.getName()); // 直接打印 f 的话实际上调用的是f.getPath()
        }
    }
}

案例:判断E盘目录下是否有后缀名为 .jpg 的文件,如果有,就输出此文件名称。

分析:

  • A:封装e判断目录
  • B:获取该目录下所有文件或者文件夹的File数组
  • C:遍历该File数组,得到每一个File对象,然后判断
  • D:是否是文件
    • 是:继续判断是否以.jpg结尾
      • 是:就输出该文件名称
      • 否:不搭理它
    • 否:不搭理它
import java.io.File;
public class FileDemo {
    public static void main(String[] args) {
        // 封装e判断目录
        File file = new File("e:\\");
        // 获取该目录下所有文件或者文件夹的File数组
        File[] fileArray = file.listFiles();
        // 遍历该File数组,得到每一个File对象,然后判断
        for (File f : fileArray) {
            // 是否是文件
            if (f.isFile()) {
                // 继续判断是否以.jpg结尾
                if (f.getName().endsWith(".jpg")) {
                    System.out.println(f.getName());
                }
            }
        }
    }
}

其实Java还提供了一个接口:文件名过滤器直接获取满足要求的文件名。

过滤器功能:

  • public String[] list(FilenameFilter filter):返回满足指定过滤器的文件和目录的名称数组
  • public File[] listFiles(FilenameFilter filter):返回满足指定过滤器的文件和目录的File数组
import java.io.File;
import java.io.FilenameFilter;

public class FileDemo2 {
    public static void main(String[] args) {
        // 封装e判断目录
        File file = new File("e:\\");

        // 获取该目录下所有文件或者文件夹的String数组
        // public String[] list(FilenameFilter filter)
        String[] strArray = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isFile() && name.endsWith(".jpg");
            }
        });

        // 遍历
        for (String s : strArray) {
            System.out.println(s);
        }
    }
}

2.3 File类案例

把 E:\评书\三国演义 下的视频(三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi)名称修改为:00?_介绍.avi

分析:

  • A:封装目录
  • B:获取该目录下所有的文件的File数组
  • C:遍历该File数组,得到每一个File对象
  • D:拼接一个新的名称,然后重命名即可
import java.io.File;
public class FileDemo {
    public static void main(String[] args) {
        // 封装目录
        File srcFolder = new File("E:\\评书\\三国演义");

        // 获取该目录下所有的文件的File数组
        File[] fileArray = srcFolder.listFiles();

        // 遍历该File数组,得到每一个File对象
        for (File file : fileArray) {
            String name = file.getName(); // 三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi

            int index = name.indexOf("_");
            String numberString = name.substring(index + 1, index + 4); //截取001部分

            int endIndex = name.lastIndexOf('_');
            String nameString = name.substring(endIndex);//截取介绍部分

            String newName = numberString.concat(nameString); // 拼接成 001_桃园三结义.avi

            File newFile = new File(srcFolder, newName); // E:\\评书\\三国演义\\001_桃园三结义.avi

            // 重命名即可
            file.renameTo(newFile);
        }
    }
}

3 递归

3.1 递归概述

递归:方法定义中调用方法本身的现象。

注意事项:

  • A:递归一定要有出口,否则就是死递归
  • B:递归的次数不能太多,否则就内存溢出
  • C:构造方法不能递归使用

3.2 递归案例-阶乘

需求:请用代码实现求5的阶乘。

分析:

  • A:循环实现
  • B:递归实现
    • a:做递归要写一个方法
    • b:出口条件
    • c:规律
public class DiGuiDemo {
    public static void main(String[] args) {
        int jc = 1;
        for (int x = 2; x <= 5; x++) {
            jc *= x;
        }
        System.out.println("5的阶乘是:" + jc);
        System.out.println("5的阶乘是:"+jieCheng(5));
    }

    public static int jieCheng(int n){
        if(n==1){ return 1; }
        else { return n*jieCheng(n-1);}
    }
}

3.3 递归案例-斐波那契数列

斐波那契数列:1,1,2,3,5,8... 从第三项开始,每一项是前两项之和。

public class DiGuiDemo2 {
    public static void main(String[] args) {
        int a = 1;
        int b = 1;
        for (int x = 0; x < 18; x++) {
            int temp = a;
            a = b;
            b = temp + b;
        }
        System.out.println(b);
        System.out.println("----------------");

        System.out.println(fib(20));
    }

    public static int fib(int n) {
        if (n == 1 || n == 2) {
            return 1;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }
}

3.4 递归案例-扫描文件

需求:把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。

分析:

  • A:封装目录
  • B:获取该目录下所有的文件或者文件夹的File数组
  • C:遍历该File数组,得到每一个File对象
  • D:判断该File对象是否是文件夹
    • 是:回到B
    • 否:继续判断是否以.java结尾
      • 是:就输出该文件的绝对路径
      • 否:不搭理它
import java.io.File;
public class FilePathDemo {
    public static void main(String[] args) {
        // 封装目录
        File srcFolder = new File("E:\\JavaSE");
        // 递归功能实现
        getAllJavaFilePaths(srcFolder);
    }

    private static void getAllJavaFilePaths(File srcFolder) {
        // 获取该目录下所有的文件或者文件夹的File数组
        File[] fileArray = srcFolder.listFiles();

        // 遍历该File数组,得到每一个File对象
        for (File file : fileArray) {
            // 判断该File对象是否是文件夹
            if (file.isDirectory()) {
                getAllJavaFilePaths(file);
            } else {
                // 继续判断是否以.java结尾
                if (file.getName().endsWith(".java")) {
                    // 就输出该文件的绝对路径
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的SOD蜜

在C++中反射调用.NET(二) 定义数据接口 绑定委托方法 使用SOD DTO 对象 将.NET对象转换到C++结构体为何不使用序列化的问题

反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET...

2027
来自专栏专注 Java 基础分享

访问权限控制

访问权限控制又称「隐藏具体实现」,也就是说,我们可以通过它来决定某个类或者类中的成员在程序中的可见范围。例如,被修饰为 public 的元素在全局范围可见,而被...

3095
来自专栏青枫的专栏

java基础学习_IO流01_异常、File类_day19总结

491
来自专栏Java技术分享

反射类的main方法

有时候我们需要调用一个类的Main方法,也可说是执行这个类的代码。但是这时候这个类我们还没有写好,或者这个类是通过网络运行时传给我们的,我们就不可能在程序中知道...

1806
来自专栏精讲JAVA

Java异常面试问题

异常是在程序执行期间可能发生的错误事件,并且会中断它的正常流程。异常可能来自不同类型的情况,例如用户输入的错误数据,硬件故障,网络连接故障等。

663
来自专栏青青天空树

spring基础(1:基本概念)

本系列笔记来自对《Spring实战》第三版的整理,Spring版本为3.0   spring是为了解决企业级应用开发的复杂性而创建的,spring最根本的...

672
来自专栏Java学习123

Java transient关键字使用小记

2122
来自专栏云瓣

JS 装饰器解析

随着 ES6 和 TypeScript 中类的引入,在某些场景需要在不改变原有类和类属性的基础上扩展些功能,这也是装饰器出现的原因。 装饰器简介 作为一种可以动...

2945
来自专栏林德熙的博客

C# const 和 readonly 有什么区别

在写常量的时候,是选择使用 const 还是 static readonly 是一个让人难以决定的问题,本文告诉大家这两个方法的区别。

552
来自专栏何俊林

从面试题中看Java的Reference(引用)

前言:四大引用,是一个古老的知识,今天看下 Harlber 授权公众号独家推送的文章, Harlber 的简书地址 :http://www.jianshu.co...

25710

扫码关注云+社区