我正在使用while循环从控制台获取输入,并调用我的input()方法。 但是,当我尝试关闭扫描仪对象时,它会给出运行时错误。 当未关闭对象时,程序会正确运行,但日食会警告资源泄漏:'s'永远不会关闭。 如何解决? 我的输入代码是
String input()
{
try
{
Scanner s = new Scanner(System.in);
String str=s.nextLine();
s.close(); // error because of this
return str;
}
public class validation {
public static void main(String args[])
{
try
{
String name;
String email_id;
String number;
validation v= new validation();
do{
System.out.println("Enter the name");
name=v.input();
}
while (!(v.validate_name(name)) );
do{
System.out.println("Enter valid Mobile Number");
number=v.input();
}
while(!(v.validate_number(Long.parseLong(number))) || !(v.filevalidate(number)));
do{
System.out.println("Enter valid Email_id");
email_id=v.input();
}
while(!(v.validate_email(email_id)) || !(v.filevalidate(email_id)));
v.writeToFile(name,number,email_id);
}
catch(Exception e){System.out.println(e);}
错误输出为
输入名称 贾斯汀 请输入有效的手机号码 java.util.NoSuchElementException:找不到行 java.lang.NumberFormatException:空
答案 0 :(得分:0)
String input(){
Scanner s = null;
try {
s = new Scanner(System.in);
//your code
}
finally {
if(s!=null)
s.close();
}
}
尝试这样并评论您的回复!希望它能正常工作。 我可以看到您的filevalidate和validate_number方法吗?
答案 1 :(得分:0)
关闭Scanner对象会导致它也关闭其关联的InputStream或文件。如果要在Scanner
方法中使用input()
来从文件而不是从键盘读取数据,则可以这样使用它:
String input() {
InputStream is = new FileInputStream(INPUT_FILE_NAME);
Scanner s = new Scanner(is);
String str = s.nextLine();
s.close();
return str;
}
如您所见,扫描仪已关闭,因此没有资源泄漏。如果不关闭它,则在文件上打开的InputStream将保持打开状态。只需关闭扫描仪,也将关闭构造扫描仪的InputStream。因此也无需关闭InputStream。
上面的代码等同于下面的代码,但是下面的代码更安全,因为它可以正确处理异常:
String input() {
try (
InputStream is = new FileInputStream(INPUT_FILE_NAME);
Scanner s = new Scanner(is)
) {
String str = s.nextLine();
return str;
}
}
这是try-with-resources语句,您可以在Oracle网站或一本好的教科书上阅读该语句。这样可以确保无论发生什么情况,在方法返回之前,始终关闭InputStream和Scanner。
那我们为什么不对在System.in
上打开的扫描仪做同样的事情?这是因为System.in
是一个InputStream,我们希望在程序的整个过程中保持打开状态。如果关闭扫描仪,那也将关闭System.in
,而我们不希望这样做。但是,既然我们不关闭扫描仪,我们不想每次输入input()
方法时都创建一个新的扫描仪。我们只想创建一个可以持续执行程序的扫描程序。一种方法是将其作为字段:
public class Validation {
private static Scanner in = new Scanner(System.in);
String input() {
return in.nextLine();
}
...
}
现在,在JVM加载您的类后立即创建扫描程序,并在您的程序退出之前一直可用。
如果将Scanner对象构造为静态字段,我不确定Eclipse是否仍会抱怨资源泄漏(我不使用Eclipse)。也许您可以告诉我是否这样做。