java学习(9)(异常,输入输出)

异常处理
异常类

都是Throwable类的子类,定义在java.lang包中。有两个子类,一个是Error类,另一个是Exception类。Exception类的子类可分为非检查异常(运行时异常)和检查异常。

非检查异常是RuntimeException类及其子类异常,在程序运行时检测到的,编译器不做处理,系统会把异常对象交给默认的异常处理程序,在控制台显示。

NullPointException:空指针异常。
ArithmeticException:算数异常,整数运算时除数为0时产生。
ClassCastException:对象转换异常。
ArrayIndexOutOfBoundsException:数组下标越界异常。
NumberFormatException:数字格式错误异常,字符串转换为数值时,不能正确转换时产生该异常。

检测异常是除RuntimeExceptionL类及其子类以外的异常类,必须捕获或声明抛出,否则编译不能通过。

异常处理

异常都是在方法中产生的,方法运行过程中若产生了异常,在这个方法中就生成一个代表该异常类的对象,并交给系统,称为抛出异常。

系统在方法的调用栈中查找,从产生异常的方法开始进行回溯,直到找到包含相应异常处理的方法为止,称为捕获异常。

public void method() throws IOException{
    try{
        //需要处理的代码,可能会抛出一种或多种异常
    }catch(ExceptionType1 exceptionObject){
        //异常处理代码
    }finally{
        //最后处理代码
    }
}
//若有多个catch块,子类异常放在前面,父类异常放在后面,否则产生编译错误。
//一个try块必须有一个catch块或finally块,catch块或finally块也不能单独使用,必须于try块搭配使用。
//catch块中可以写任何语句,只要有一对大括号,系统就认为异常被处理了。
//捕获多个异常
catch(ArithmeticException | ArrayIndexOutOfBoundsException e)

异常类的跟类Throwable中定义的方法。

public void printStackTrace():在标准错误输出流上输出异常调用栈的轨迹。
public String getMessage():返回异常对象的细节描述。
public void printStackTrace(PrintWriter s):在指定输出流上输出异常调用栈的轨迹。
public String toString():返回异常对象的简短描述。
自定义异常类
public class CustomException extends Exception{
    public CustomException(){}
    public CustomException(String message){
        super(message)
    }
}

输入输出

并不是存储对象的数据结构。仅用来移动数据,不能向流中添加元素。

Stream API定义在java.util.stream包中,Stream接口是最常用的类型,Stream对象可以用来传输任何类型的对象。

Stream的有些方法执行中间操作,有些方法执行终止操作。中间操作是将一个流转换成另一个流,sorted、filter、map方法执行中间操作。终止操作产生一个最终结果,count、forEach方法执行终止操作,值得注意的是,流操作时延迟的,在源上的计算只有当终止操作开始时才执行。

二进制I/O流

java支持文件I/O和流式I/O,流式I/O分为输入流和输出流。

为了获得外部数据,可以在数据源(文件、内存及网络套接字)上创建一个输入流,用ready()方法顺序读取数据。在输出设备创建一个输出流,用write()方法将数据写到输出流中。

所有数据流都是单向的,输入流只能读数据,输出流只能写数据。

数据流分为二进制流(字节流)和文本流(字符流)。

File类

java.io.File类用来表示物理磁盘上的实际文件或目录,但它不表示文件中的数据。

try{
    boolean success = false;
    File file = new File("Hello.txt");
    System.out.println(file.exists());//输出文件是否存在
    success = file.createNewFile();//创建文件是否成功
    System.out.println(success);
    System.out,println(file.exists());//输出文件是否存在
}catch(IOException e){
    System.out.println(e.toString());
}
//输出结果
//false(创建File对象并不实际在磁盘上创建一个文件)
//true(调用方法时实际创建一个文件)
//true
//File常用方法
public boolean exists():测试File对象是否存在。
public long length():返回指定文件的字节长度,文件不存在时返回0。
public boolean createNewFile():当文件不存在时,创建一个空文件时返回true,否则返回false。
public boolean renameTo(File newName):重命名指定的文件对象,正常重命名时返回true,否则返回false。
public boolean delete():删除指定的文件。若为目录,当目录为空时才能删除。
public long lastModified():返回文件最后被修改的日期和时间,计算的是从1970年1月1日0时0分0秒开始的毫秒数。
InputStream类和OutputStream类

InputStream类是二进制输入流的根类。

public int read():从输入流中读取下一个字节并返回它的值,返回值是0~255的整数值,如果读到输入流末尾,返回-1。
public int read(byte[] b):从输入流中读取多个字节,存入字节数组b中,如果输入流结束,返回-1。
public int available():返回输入流中可读或可跳过的字节数。
public void close():关闭输入流,并释放相关的系统资源。

OutputStream类是二进制输出流的根类。

public void write(int b):报指定的整数b的低8位字节写入输出流。
public void write(byte[] b):把指定的整数b的b.length个字节写入输出流。
public void flush():刷新输出流,输出全部缓存内容。
public void close():关闭输出流,并释放系统资源。
常用二进制I/O流

FileInputStream类和FileOutputStream类

实现文件的输入输出处理,可以打开本机上的文件,并进行顺序读写。

//FileInputStream类构造方法
FileInputStream(String name):用表示文件的字符串创建文件输入流对象。
FileInputStream(File file):用File对象创建文件输入流对象。
//FileOutputStream构造方法
FileOutputStream(String name):用表示文件的字符串创建文件输出流对象。
FileOutputStream(String name,boolean append):用表示文件的字符串创建文件输出流对象。若append为true,指明打开的文件输出流不覆盖原来的内容,而是从文件末尾写入新内容,否则覆盖原来内容。
FileOutputStream(File file):用File对象创建文件输出流对象。

BufferedInputStream类BufferedOutputStream类

用来对流实现缓冲功能,可以减少读写数据的次数,加快输入输出的速度。

//BufferedInputStream构造方法
BufferedInputStream(InputStream in):使用参数in指定的输入流对象创建一个缓冲输入流。
BufferedInputStream(InputStream in,int size):使用参数in指定的输入流对象创建一个缓冲输入流,并且通过size参数指定缓冲区的大小,默认为512字节。
//BufferedOutputStream构造方法
BufferedOutputStream(OutputStream out):使用参数out指定的输出流对象创建一个缓冲输出流。
BufferedOutputStream(OutputStream out,int size):使用参数out指定的输出流对象创建一个缓冲输出流,并且通过size参数指定缓冲区的大小,默认为512字节。

DataInputStream类和DataOutputStream类

数据输入流和数据输出流,可以实现基本数据类型的输入输出。

//DataInputStream类的构造方法
DataInputStream(InputStream instream):参数instream是字节输入流对象。
//DataOutputStream类的构造方法
DataOutputStream(OutputStream outstream):参数outstream是字节输出流对象。
//常用方法

public byte readByte():从输入流读一个字节并返回该字节。
public int readInt():从输入流读4字节,返回一个int型值。
public long readLong():从输入流读8字节,返回一个long型值。
public boolean readBoolean():从输入流读一个字节,非0返回true,0返回false。
public String readLine():从输入流读下一行文本。
public String readUTF():从输入流读取UTF-8格式的字符串。
public void writeByte(int v):将v的低8位写入输出流。
public void writeInt(int v):向输出流写一个4字节的整数。
public void writeBoolean(boolean v):将一个布尔值写入输出流。
public void writeDouble(double v):向输出流写一个8字节的double型浮点数。
public void writeBytes(String s):将参数字符串每个字符的低位字节按顺序写到输出流中。
public void writeUTF(String s):将参数字符串按UTF-8的格式写到输出流中。

标准输入输出流

System.in:是InputStream类的实例。

System.out

System.err

是PrintStreamL类的实例。

文本I/O流

Reader类和Writer类

文本输入流和输出流的根类,实现字符的读写。

public int read():读取一个字符,返回0~65535的int型值,如果到达流的末尾返回-1。
public int read(char[] cbuf):读取多个字符到字符数组cbuf中,如果到达流的末尾返回-1。
public void close():关闭输入流。
public void write(int c):向输出流中写一个字符,实际是将int型的c的低16位写入输出流。
public void write(char[] cbuf):把字符数组cbuf中的字符写入输出流。
public void write(String str):把字符串str写入输出流中。
public void flush():刷新输出流。
public void close():关闭输出流。

FileReader类和FileWriter类

文件输入流和文件输出流。

BufferedReader类和BufferedWriter类

具有缓冲功能的字符输入输出流。

PrintWrite类

实现字符打印输出流。

//构造方法
PrintWrite(Writer out):使用参数指定的输出流对象out创建一个打印输出流。
PrintWrite(Writer out,boolean autoFlush):如果autoFlush指定为true,则在输出之前自动刷新输出流。
PrintWrite(OutputStream out):使用二进制输出流创建一个打印输出流。
PrintWrite(OutputStream out,boolean autoFlush):如果autoFlush指定为true,则在输出之前自动刷新输出流。
//常用方法
public void println(int i):输出一个int型数据。

Scanner类

//构造方法
public Scanner(String source):用指定的字符串构造一个Scanner对象。
public Scanner(InputStream source):用指定的输入流构造一个Scanner对象。
//常用方法
public byte nextByte():读取下一个标记并将其解析为byte型数。
public short nextShort():读取下一个标记并将其解析为short型数。
public int nextInt():读取下一个标记并将其解析为int型数。
public String next():读取下一个标记并将其解析为字符串。
public String nextLine():读取当前行作为string型字符串。
对象序列化与对象流

将程序中的对象输出到外部设备(磁盘,网络)中,称为对象序列化。

从外部设备将对象读入程序中称为对象反序列化。

一个类的对象要实现对象序列化,必须实现java.io.Serializable接口,还要创建对象输出流和对象输入流,通过对象输出流将对象状态保存下来,通过对象输出流恢复对象的状态。

ObjectInputStream类(对象输入流)和ObjectOutputStream(对象输出流)类。

FileOutputStream fos  = new FileOutputStream("data.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);//ObjectOutputStream必须建立在另一个字节流上。
oos.writeInt(2024);
oos.writeObject("hello");
oos.writeObjrct(LocalDate.now());
FileInputStream fis = new FileInputStream("data.ser");
ObjectInputStream ois = new ObjectInputStream(fis);//ObjectInputStream也必须建立在另一个字节流上。
int i = ois.reafInt();
String today = (String)ois.readObject();
LocalDate date = (LocalDate)ois.readObject();
  • 序列化只能保存对象的非static成员,不能保存任何成员方法和static成员变量,而且序列化保存的只是变量的值。

  • 用transient关键字修饰的变量为临时变量,也不能被序列化。

  • 对于成员变量为引用类型时,引用的对象也被序列化。

public class Customer implements Serializable{
    public int id;
    public String name;
    public String address;
    public Customer(int id,String name,String address){
        this.id = id;
        this.name = name;
        this.address = address;
    }
}
public class ObjectSerializeDemo{
    public static void main(String[] args){
        Customer customer = new Customer(1,"李华","北京");
        LocalDate today = LocalDate.now();
        //序列化
        try(
            OutputStream output = new FileOutputStream("D:\\study\\customer.dat");
            ObjectOutputStream oos = new  ObjectOutputStream(output)){
            oos.writeObject(customer);
            oos.writeObject(today);
        }catch(IOException e){
            e.printStackTrace();
        }
        //反序列化
        try(
            InuptStream input = new FileInputStream("D:\\study\\customer.dat");
            ObjectInputStream ois = new ObjectInputStream(input)){
            while(true){
                try{
                    customer = (Customer)ois.readObject();
                    System.out.println(customer.id);
                    System.out.println(customer.name);
                    System.out.println(customer.address);
                    today = (LocalDate)ois.readObject();
                    System.out.println(today); 
                }catch(EOFException e){
                    break;
                }
            }
        }catch(ClassNotFoundException | IOException e){
            e.printStackTrace();
        }
        }
    }
}
FileSystem类

表示一个文件系统,是一个抽象类,可以调用该类的getDefault()静态方法来获取当前的文件系统。

FileSystem fileSystem = FileSystem.getDefault();
//常用方法
abstract Path getPath(String first,String...more):返回字符串first指定的路径对象,可选参数more用来指定后续路径。
abstract String getSeparator():返回路径分隔符。在Wingdows系统中,它是“\”,在UNIX/Linux系统中,它是“/”。
abstract Iterable<Path>getRootDirectores():返回一个Iterable对象,可以用来遍历根目录。
abstract boolean isOpen():返回该文件系统是否打开。
abstract boolean isReadOnly():返回该文件系统是否只读。
Path类

Path实例包含确定文件或目录位置的信息。在文件系统中表示文件或目录。用来检查,定位和操作文件。

创建Path实例

Path p1 = Paths.get("D:\\study\\com\\Hello.java");
Path p2 = Paths.get(args[0]);
Path p3 = Paths.gat(URI.create("file:///users/joe/FileTest.java"));

检索路径信息

Path path = Paths.get("D:\\study\\user\\report.txt");
System.out.println(path.toString());//D:\study\user\report.txt
System.out.println(path.getFileName());//report.txt
System.out.println(path.getName(0));//study
System.out.println(path.getNameCount());//3
System.out.println(path.subpath(0,2));//study\user
System.out.println(path.getParent());//D:\study\user
System.out.println(path.getRoot());//D:\

  • 30
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 自定义异常可以用来在特定的业务场景中抛出异常。在判断用户名的场景中,可以自定义一个异常类来表示用户名不合法。例如: ```java class InvalidUsernameException extends Exception { public InvalidUsernameException(String message) { super(message); } } ``` 在业务逻辑中,当用户名不合法时,可以抛出该异常。例如: ```java if (!isValidUsername(username)) { throw new InvalidUsernameException("Invalid username: " + username); } ``` 在调用的地方可以使用 try-catch 语句来捕获该异常。 ```java try { register(username); } catch (InvalidUsernameException e) { System.out.println(e.getMessage()); } ``` 这样, 当用户输入不合法的用户名时,就可以在 catch 中输出错误信息了。 ### 回答2: 在Java编程中,当程序出现异常时,我们可以使用异常处理机制来处理这些异常异常处理机制允许我们捕获、处理和报告程序执行过程中的异常情况。在Java中有很多内置的异常类型,例如:数组越界异常、空指针异常、类型转换异常等。除此之外,Java还支持自定义异常,可以根据个人需求来定义异常类型。 在本文中,我们将讨论如何使用自定义异常来判断用户名的合法性。通常情况下,我们需要根据一些规则来判断用户名是否合法,例如:是否包含非法字符、是否太短或太长等。 首先,我们需要创建一个自定义异常类,用来处理用户名不合法的情况。该异常类可以继承于Java内置的异常类,例如:Exception、RuntimeException等。在自定义异常类中,我们可以定义一些成员变量和构造方法,用来保存异常信息和创建异常对象。 然后,我们可以在判断用户名的方法中抛出自定义异常,例如: ```java public void checkUsername(String username) throws IllegalUsernameException { if (username.length() < 6 || username.length() > 18) { throw new IllegalUsernameException("用户名长度必须在6到18个字符之间!"); } if (!username.matches("^[a-zA-Z]\\w{5,17}$")) { throw new IllegalUsernameException("用户名只能包含字母、数字、下划线,且以字母开头!"); } } ``` 以上代码中,我们使用了两个条件语句来判断用户名的合法性。如果用户名不符合规则,则会抛出自定义异常对象IllegalUsernameException,并将异常信息传递给构造方法。 最后,我们需要在调用判断用户名的方法时,使用try-catch代码块来捕获异常。例如: ```java try { checkUsername(username); System.out.println("用户名合法!"); } catch (IllegalUsernameException e) { System.out.println("用户名不合法:" + e.getMessage()); } ``` 如果用户名合法,则会输出“用户名合法!”,否则会输出“用户名不合法:异常信息”。 总之,使用自定义异常可以更加灵活地处理程序中的异常情况,并能够根据个人需求来定义异常类型。在判断用户名的场景中,使用自定义异常也可以提高代码的可读性和健壮性。 ### 回答3: Java是一种很流行的编程语言,而异常处理是Java编程中必不可少的部分。Java异常处理提供了一种在程序执行期间处理错误的方法,这种错误可能导致程序的崩溃。Java中的异常分为两种:已检查异常(Checked Exception)和未检查异常(Unchecked Exception)。在开发Java应用时,有时需要自定义异常来满足特定的需求,比如在判断用户名时需要自定义一个异常。 判断用户名是Web开发和客户端开发中必不可少的部分。在Java中,可以使用正则表达式、字符过滤、长度限制等方式来验证用户名,但是当这些方式无法满足时,我们可以自定义异常来实现对用户名的验证。 首先,需要定义一个自定义异常类来处理用户名验证时可能出现的异常。我们可以创建一个继承于Exception的类,并在该类中实现构造函数,用来接收异常信息。例如: ``` public class UsernameException extends Exception { public UsernameException(String message) { super(message); } } ``` 然后,在判断用户名的方法中,如果出现了用户名不合格的情况,就可以抛出自定义异常。例如: ``` public void checkUsername(String username) throws UsernameException { if (username.length() < 6 || username.length() > 12) { throw new UsernameException("用户名长度应在6-12之间"); } if (!username.matches("[a-zA-Z0-9]+")) { throw new UsernameException("用户名只能由字母和数字组成"); } } ``` 在上述代码中,我们通过判断用户名长度和用户名是否由字母和数字组成来验证用户名,并可以通过抛出自定义异常来提示用户错误信息。 最后,在调用判断用户名方法的地方,需要使用try-catch语句来捕捉可能出现的异常。例如: ``` try { checkUsername(username); } catch (UsernameException e) { e.printStackTrace(); } ``` 通过以上方式,我们可以自定义一个异常来判断用户名,使得判断过程更方便、更灵活,也能给用户更友好的提示信息。除此之外,在其他处同样需要判断用户名时,只需要调用此方法即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值