Cercando di leggere dalla console in Java

Ho appena iniziato a imparare Java con IntelliJ IDE. Conosco un po ‘C #, quindi la logica ha un senso, tuttavia c’è una cosa che finora non ho potuto superare.

Come leggo dalla console? In C #, si può facilmente leggere ciò che l’umano ha digitato in esso, utilizzando Console.ReadLine() . In Java, System.console().readLine(); non funziona per me e lancia una NullPointerException .

Cosa mi manca qui?

Problema

La maggior parte degli IDE utilizza javaw.exe invece di java.exe per eseguire il codice Java (vedi immagine sotto).

La differenza tra questi due programmi è che javaw esegue il codice Java senza associazione con il terminale / console corrente (che è utile per le applicazioni GUI) e poiché non esiste una finestra console associata, System.console() restituisce null . A causa di questo System.console().readLine() finisce come null.readLine() che lancia NullPointerException poiché null non ha il metodo readLine() (né alcun metodo / campo).

Ma solo perché non esiste una console associata, ciò non significa che non possiamo comunicare con il processo javaw . Questo processo supporta ancora flussi di input / output / errori standard, quindi gli IDE elaborano (e tramite esso anche noi) possono utilizzarli tramite System.in , System.out e System.err .

In questo modo gli IDE possono avere qualche tab / finestra e lasciar simulare la console.

Ad esempio, quando eseguiamo codice come in Eclipse:

 package com.stackoverflow; public class Demo { public static void main(String[] args) throws Exception { System.out.println("hello world"); System.out.println(System.console()); } } 

vedremo come risultato

inserisci la descrizione dell'immagine qui

che mostra che nonostante javaw.exe non abbia console associata ( null alla fine) IDE è stato in grado di gestire i dati dallo standard output del processo javaw System.out.println("hello world"); e mostra hello world .

Soluzione generale

Per consentire all’utente di passare le informazioni da elaborare, utilizzare lo stream di input standard ( System.in ). Ma dato che è semplice InputStream e Stream s sono pensati per gestire i dati binari , non ha metodi che permettano di leggere e leggere i dati come testo (specialmente se la codifica può essere coinvolta). Questo è il motivo per cui Readers and Writers ware è stato aggiunto a Java.

Quindi, per semplificare la vita e consentire all’applicazione di leggere i dati dall’utente come testo, è ansible avvolgere questo stream in uno dei Reader come BufferedReader che consente di leggere l’intera riga con il metodo readLine() . Sfortunatamente questa class non accetta Streams ma Reader s, quindi abbiamo bisogno di una sorta di adattatore che simulerà Reader e sarà in grado di tradurre byte in testo. Ma ecco perché esiste InputStreamReader .

Quindi il codice che permetterebbe all’applicazione di leggere i dati dal stream di input potrebbe essere simile

 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Hello. Please write your name: "); String name = br.readLine(); System.out.println("Your name is: "+name); 

Soluzione preferita / più semplice – Scanner

Per evitare questa magia che comporta la conversione di Stream in Reader, è ansible utilizzare la class Scanner , che ha lo scopo di leggere i dati come testo da flussi e lettori.

Questo significa che puoi semplicemente usare

 Scanner scanner = new Scanner(System.in); //... String name = scanner.nextLine(); 

per leggere i dati dell’utente (che verrà inviato dalla console simulato dall’IDE utilizzando il stream di input standard).

java.util.Scanner API java.util.Scanner è ciò che stai cercando.

Se hai davvero bisogno di un object Console, puoi compilare la tua class dalla riga di comando. Innanzitutto nel mio file java la prima istruzione è il package com.inputOutput;

Vai nella cartella ” src ” del progetto e compila come: ” javac com/inputOutput/Password.java ” ‘ com ‘ e ‘ inputOutput ‘ sono cartelle (pacchetto). Esegui il tuo file di class nella cartella src
java com.inputOutput.Password “. Aveva funzionato per me.