1

1 つのスキャナー オブジェクトを閉じて新しいオブジェクトを作成し、さらに入力を読み取ろうとすると、NoSuchElementException例外が発生します。

コードは正常に動作しますが、スキャナーを閉じないと警告が表示されます。ただし、警告を取り除くために閉じると、閉じてしまいSystem.inます...どうすればこれを回避できますか?

また、スキャナーを閉じないことによる影響はありますか?

編集:これが私のコードです:

これは NameAddressExists() メソッドです。

public void NameAddressExists() {
    System.out.println("Enter name");
    Scanner sc = new Scanner(System.in);
    String n = sc.next();
    System.out.println("Enter address");
    String a = sc.next();
    int flag = 0;
    for(int i = 0; i < count; i++) {
        if(array[i].name .equals(n) && array[i].address .equals(a)) {
            System.out.println("True");
            flag = 1;
        }
    }
    if(flag != 1) {
        new Agency(n, a);
    }
    sc.close();
}

これは PanNumberExists() メソッドです。

public boolean PanNumberExists() {
    Scanner s = new Scanner(System.in);
    String n = "";
    System.out.println("Enter the 5 digits");
    try {
        n = s.nextLine();
    }catch(Exception e) {
        System.out.println(e);
    }finally {
        s.close();
    }
    if(n  .equals(this.PAN.subSequence(4,9))) {
        return true;
    }
    else {
        return false;
    }
}

これらのメソッドは、次の main() メソッドから呼び出されます。

public static void main(String args[]) {
    Agency obj1 = new Agency("XYZ", "ABCD");
    Agency obj2 = new Agency("XYZ", "ABCDEFG", "+91083226852521", "ab 1234567", "abcd12345ab");
    // Agency obj3 = new Agency("XYZ", "TSRK", "36", "ab 1234567", "abcd12345ab");
    obj1.NameAddressExists();
    System.out.println(obj2.PanNumberExists());
}

ご覧のとおり、最初に NameAddressExists() メソッドを呼び出します。このメソッドで、Scanner名前付きの「sc」を開き、使用し、閉じます。これは正常に機能し、正しい出力が得られます。次に、PanNumberExists() メソッドを呼び出します。このメソッドでは、Scanner's' という名前の別のオブジェクトを開き、それを使用してユーザーからの入力を取得しようとします。ここで例外を受け取りNoSuchElementExceptionます。NameAddressExists() メソッドで「sc」を開いたままScannerにしておくと、このエラーは発生しません。

4

2 に答える 2

3
Scanner scan = new Scanner(new FilterInputStream(System.in) {
    @Override
    public void close() throws IOException {
        // do nothing here ! 
    }
});

close()または、カスタムデコレータを実装して無視してください。

public class UnClosableDecorator extends InputStream {

    private final InputStream inputStream;

    public UnClosableDecorator(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public int read() throws IOException {
        return inputStream.read();
    }

    @Override
    public int read(byte[] b) throws IOException {
        return inputStream.read(b);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        return inputStream.read(b, off, len);
    }

    @Override
    public long skip(long n) throws IOException {
        return inputStream.skip(n);
    }

    @Override
    public int available() throws IOException {
        return inputStream.available();
    }

    @Override
    public synchronized void mark(int readlimit) {
        inputStream.mark(readlimit);
    }

    @Override
    public synchronized void reset() throws IOException {
        inputStream.reset();
    }

    @Override
    public boolean markSupported() {
        return inputStream.markSupported();
    }

    @Override
    public void close() throws IOException {
        //do nothing
    }
}

で使用している間main()

public static void main(String[] args) throws Exception {
        System.setIn(new UnClosableDecorator(System.in));
}
于 2014-08-26T12:55:22.997 に答える
0

Decorator パターンを使用して、InputStream閉じることができないカスタムを作成し、それをScanner

import java.io.IOException;
import java.io.InputStream;

public class PreventClosingInputStream extends InputStream {

    private InputStream inputStream;

    public PreventClosingInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public int read() throws IOException {
        return inputStream.read();
    }

    @Override
    public void close() throws IOException {
        // Don't call super.close();
    }

}

次に、コードで:

PreventClosingInputStream in = new PreventClosingInputStream(System.in);
Scanner s = new Scanner(in);
// ...
s.close(); // This will never close System.in as there is underlying PreventClosingInputStream with empty close() method

try-with-resources の使用:

try (PreventClosingInputStream in = new PreventClosingInputStream(System.in);
        Scanner s = new Scanner(in);) {
    // ...
    // resources will be automatically closed except of System.in
}
于 2014-08-26T12:58:10.480 に答える