最近在系统运用java做一些项目的时候,总是可以遇到很多异想之外的报错,渐渐的也就自己学会给代码找错的原因了。
写一篇文章记录我学习时遇到的不容易解决的bug给新入手的朋友一点小小启示。
1.java中try-with-resourse语句引发的Scanner类关闭之后无法继续input的情况
java中有很多种类,一旦声明十分占用资源,需要程序员自己关闭,但是每次重复的关闭,难道这是程序员的一贯作风吗?nonono,程序员可是最会偷懒的,于是在java中也就诞生了try-with-resourse语句,其作用是在这个语句块中声明的对象会在语句块结束的时候自动关闭声明的该对象,从而减少程序员的开发代码和尽量避免忘记关闭这类事情。
下面一串代码请大家寻找一下错误
package Library; import java.util.Scanner; public class Test { public static void main(String args[]){ Test1() ; } public static void Test1(){ try( Scanner scanner = new Scanner(System.in) ){ System.out.print("请输入书本名称:") ; String name = scanner.next() ; System.out.println() ; System.out.print("请输入书本作者:") ; String writer = scanner.next() ; System.out.println() ; } Login() ; } public static void Login(){ System.out.println("请输入你的身份: 1->管理员 2->用户") ; Scanner scanner = new Scanner(System.in) ; String user = scanner.next() ; } }
讲解一下:其中在Test类中声明了两个方法,两个都是静态,Test1()和Login() 其中Test1方法中运用了try-with-resourse语句块,在使用完之后自动关闭了scanner对象,下面是报错信息
系统报NoSuchElementException错误,报错在代码24行,也就是Login方法体内。
具体这个错误,刚开始我也非常没有头绪,我并不知道错在哪里。想必没有深入了解Scanner类的小伙伴都没看到问题出在何处了吧
查询了csdn大佬上们的解释,发现这类问题并不是很多,或者对于小白来说并没有太多文章解释这个错误
解释:try-with-resourse自动关闭了scanner对象,而我们去看Scanner创建对象时输入了一个System.in,而我们去看System类源代码,in是System类的静态最终输入流对象,静态不依赖于对象而是和类共生,也就是说Scanner类一旦关闭,其传入的参数System,in也将关闭,而后再声明Scanner类对象就会报NoSuchElementException错误,所以就是避免
2.equals引用互换导致错误,至今不明原因!希望有小伙伴可以指正
我来描述问题吧。
package Library.BookSrc; public class Book { private String name; private String writer; private double price; private String type; private boolean isBorrowed; public void setName(String name) { this.name = name; } public String getName() { return name; } public void setWriter(String writer) { this.writer = writer; } public String getWriter() { return writer; } public void setPrice(Double price) { this.price = price; } public double getPrice() { return price; } public void setType(String type) { this.type = type; } public String getType() { return type; } public void setIsBorrowed(boolean isBorrowed) { this.isBorrowed = isBorrowed; } public boolean getIsBorrowed() { return isBorrowed; } @Override public String toString() { String result; if(isBorrowed) result = "已经被借出!"; else result = "未被借出!" ; return name + "-" + writer + "-"+price+"-"+type+"-"+result ; } public boolean equals(Object object) { if (object == null) { return false; } else { if (!(object instanceof Book)) { return false; } else { Book temp = (Book) object; if (temp.getName().equals(this.getName()) && temp.getWriter().equals(this.getWriter())) { return true; } else { return false; } } } } public Book(String name, String writer, double price, String type) { this.name = name; this.writer = writer; this.price = price; this.type = type; } }
主要看equals方法,我给Book类写了equals方法
主要目的是往图书管理系统中看添加的书是否已经存在,下面看addOperation类代码
package Library.IoOperationSrc; import Library.BookSrc.Book; import Library.BookSrc.BookList; public class AddOperation implements IoOperation{ public void work(BookList bookList){ System.out.println("增加图书!") ; System.out.print("请输入你增加书名:") ; String name = scanner.next() ; System.out.println(); System.out.print("请输入你增加书的作者:") ; String writer = scanner.next() ; System.out.println() ; System.out.print("请输入价格:") ; double price = scanner.nextDouble() ; System.out.println() ; System.out.print("请输入类型:") ; String type = scanner.next() ; System.out.println() ; Book book = new Book(name, writer, price, type) ; for(Book temp : bookList.getBooks()){ if(temp.equals(book)){ System.out.println("已有此书,加入失败") ; return ; } } bookList.addBook(book); } }
主要看
运行下来会报错,报错如下
我检查下来就是if(temp : equals(book)) 出错了
于是,我简单换了一下位置,代码就不会报错
代码如下
所以到底出错在哪了?
还是那句话哪怕是屎山也不要改可以运行的代码