流已关闭但未重新打开-Java

流已关闭但未重新打开-Java,java,stream,overriding,try-with-resources,Java,Stream,Overriding,Try With Resources,我有一个简单的“家庭作业”要做,但我发现关闭输入流有一个小问题。 简单地说,我必须用Java制作一个联系人列表应用程序,以便以正确的方式使用多态性。所以我有一个类Contact和一个子类Private(Contact)。在这两个类中都有一个modify方法来更改变量的值 public void modify() throws IOException { System.out.println("Previously name: " + name); System.out.print

我有一个简单的“家庭作业”要做,但我发现关闭输入流有一个小问题。 简单地说,我必须用Java制作一个联系人列表应用程序,以便以正确的方式使用多态性。所以我有一个类Contact和一个子类Private(Contact)。在这两个类中都有一个modify方法来更改变量的值

public void modify() throws IOException {
    System.out.println("Previously name: " + name);
    System.out.println("Insert new name");
    try(InputStreamReader ir = new InputStreamReader(System.in);    
    BufferedReader in = new BufferedReader(ir) ) {  
        name= in.readLine();
        System.out.println("You've changed the name to: "+ name);                       
    System.out.println("Previously surname: " + surname);
    System.out.println("Insert new surname");
        surname= in.readLine();
        System.out.println("You've changed the surname to: "+ surname);                         
    System.out.println("Previously e-mail: " + email);
    System.out.println("Insert new e-mail");
        email = in.readLine();
        System.out.println("You've changed the e-mail to: "+ email);    }                   
}
这是一种不会产生问题的联系方式

@Override 
public void modify() throws IOException {
    super.modifica();
    System.out.println("Numero di cellulare precedente: " + cell);
    System.out.println("Inserire nuovo numero");
    try (InputStreamReader ir = new InputStreamReader(System.in);   
    BufferedReader in = new BufferedReader(ir)) {
        cell = in.readLine();
        System.out.println("Hai cambiato il numero in: "+ cell);                        
    System.out.println("Contatto skype precedente: " + skype);
    System.out.println("Inserire nuovo contatto");
        skype = in.readLine();
        System.out.println("Hai cambiato il contatto in: "+ skype);                         
}   
}
相反,这是私有方法的重写。 主要是创建一个私有对象并调用modify方法。我可以毫无问题地插入姓名、姓氏和电子邮件,然后该方法抛出IO异常,因为流已关闭。
我不明白我为什么会有这样的问题。我认为在第一个代码中,try with resources关闭了流,但在第二个代码中,try with resources打开了流。可能我的想法有点不对劲。

您的问题确实是由于try-with-resource语句关闭了
新的InputStreamReader(System.in)
,它在后台也关闭了底层的输入流,即
System.in
in
系统的
公共静态
字段)这样,在您的
modify
方法中,
System.in已关闭,然后无法再读取,这就是为什么会出现此异常。

您的问题确实是由于try-with-resource语句关闭了
新的InputStreamReader(System.in)
它在幕后也关闭了底层的输入流,即
系统。
中(
中的
系统的
公共静态
字段)因此,在您的
modify
方法中,系统中的
已关闭,然后无法再读取,这就是为什么会出现此异常。

如果使用
系统中的
CloseShieldInputStream
包装
系统,您仍然可以使用
尝试使用资源

我还建议使用
扫描仪
而不是
InputStreamReader
BufferedReader
,因为它很简单:

import java.util.Scanner;
import org.apache.commons.io.input.CloseShieldInputStream;

public class Contact {

    protected String name;
    protected String surname;
    protected String email;

    public void modify() throws IOException {
        System.out.println("Previously name: " + name);
        System.out.println("Insert new name");
        try (Scanner sc = new Scanner(new CloseShieldInputStream(System.in))) {
            name = sc.nextLine();
            System.out.println("You've changed the name to: " + name);
            System.out.println("Previously surname: " + surname);
            System.out.println("Insert new surname");
            surname = sc.nextLine();
            System.out.println("You've changed the surname to: " + surname);
            System.out.println("Previously e-mail: " + email);
            System.out.println("Insert new e-mail");
            email = sc.nextLine();
            System.out.println("You've changed the e-mail to: " + email);
        }
    }
}

public class Private extends Contact {

    private String cell;
    private String skype;

    @Override
    public void modify() throws IOException {
        super.modify();
        System.out.println("Numero di cellulare precedente: " + cell);
        System.out.println("Inserire nuovo numero");
        try (Scanner sc = new Scanner(new CloseShieldInputStream(System.in))) {
            cell = sc.nextLine();
            System.out.println("Hai cambiato il numero in: " + cell);
            System.out.println("Contatto skype precedente: " + skype);
            System.out.println("Inserire nuovo contatto");
            skype = sc.nextLine();
            System.out.println("Hai cambiato il contatto in: " + skype);
        }
    }
}

另请参见:

如果使用
CloseShieldInputStream将
System.in
包装为
的话,您仍然可以使用
try with resources

我还建议使用
扫描仪
而不是
InputStreamReader
BufferedReader
,因为它很简单:

import java.util.Scanner;
import org.apache.commons.io.input.CloseShieldInputStream;

public class Contact {

    protected String name;
    protected String surname;
    protected String email;

    public void modify() throws IOException {
        System.out.println("Previously name: " + name);
        System.out.println("Insert new name");
        try (Scanner sc = new Scanner(new CloseShieldInputStream(System.in))) {
            name = sc.nextLine();
            System.out.println("You've changed the name to: " + name);
            System.out.println("Previously surname: " + surname);
            System.out.println("Insert new surname");
            surname = sc.nextLine();
            System.out.println("You've changed the surname to: " + surname);
            System.out.println("Previously e-mail: " + email);
            System.out.println("Insert new e-mail");
            email = sc.nextLine();
            System.out.println("You've changed the e-mail to: " + email);
        }
    }
}

public class Private extends Contact {

    private String cell;
    private String skype;

    @Override
    public void modify() throws IOException {
        super.modify();
        System.out.println("Numero di cellulare precedente: " + cell);
        System.out.println("Inserire nuovo numero");
        try (Scanner sc = new Scanner(new CloseShieldInputStream(System.in))) {
            cell = sc.nextLine();
            System.out.println("Hai cambiato il numero in: " + cell);
            System.out.println("Contatto skype precedente: " + skype);
            System.out.println("Inserire nuovo contatto");
            skype = sc.nextLine();
            System.out.println("Hai cambiato il contatto in: " + skype);
        }
    }
}

另请参见:

。。。应用程序无法重新打开中的流
系统。是否需要删除?因为我在一本书中读到,尽快关闭流很重要,自动建议使用try with resource来完成。使用try with resources语句确实是一个很好的实践,但在这里不是,因为您真正关闭的唯一资源不能关闭,所以您不能在此处使用它。在这方面我可以做些什么来避免内存浪费情况?让总司令来做它的工作。。。应用程序无法重新打开中的流
系统。是否需要删除?因为我在一本书中读到,尽快关闭流很重要,自动建议使用try with resource来完成。使用try with resources语句确实是一个很好的实践,但在这里不是,因为您真正关闭的唯一资源不能关闭,所以您不能在此处使用它。在这方面我可以做些什么来避免内存浪费情况?让GC完成它的工作也许您应该了解
java.util.Scanner
。你可以从这里开始:谢谢!Scanner和BufferedReader在内存的潜力和管理方面是否存在差异?可能的重复可能您应该了解
java.util.Scanner
。你可以从这里开始:谢谢!扫描仪和BufferedReader在内存潜力和管理方面是否存在差异?可能存在重复的