Non sono necessarie più istruzioni di chiusura per nessuno degli stream e dei lettori nidificati in java.io. È molto raro che alla fine sia necessario chiudere più di una cosa in una sola: la maggior parte dei costruttori può generare un'eccezione, quindi si cercherebbe di chiudere le cose che non sono ancora state create.
Se si desidera chiudere lo stream indipendentemente dal fatto che la lettura abbia esito positivo, è necessario inserirla definitivamente.
Non assegnare nulla alle variabili e quindi confrontarle per vedere se qualcosa è accaduto prima; invece strutturare il programma in modo che il percorso in cui si chiude lo stream possa essere raggiunto solo se l'eccezione non viene generata. A parte le variabili utilizzate per iterare per cicli, le variabili non dovrebbero avere bisogno di modificare il valore - tendo a contrassegnare tutto finale a meno che non ci sia l'obbligo di fare altrimenti. Avere dei flag attorno al tuo programma per dirti come sei arrivato al codice attualmente in esecuzione, e quindi cambiare comportamento in base a quei flag, è uno stile procedurale molto (non ancora strutturato) di programmazione.
Come nidificare i blocchi try/catch/finally dipende se si desidera gestire le eccezioni generate dalle diverse fasi in modo diverso.
private static final String questionUrl = "http://stackoverflow.com/questions/3044510/";
public static void main (String...args)
{
try {
final URLConnection connection = new URL (args.length > 0 ? args[0] : questionUrl).openConnection();
final BufferedReader br = new BufferedReader (new InputStreamReader (
connection.getInputStream(), getEncoding (connection)));
try {
final String response = br.readLine();
System.out.println (response);
} catch (IOException e) {
// exception handling for reading from reader
} finally {
// br is final and cannot be null. no need to check
br.close();
}
} catch (UnsupportedEncodingException uee) {
// exception handling for unsupported character encoding
} catch (IOException e) {
// exception handling for connecting and opening reader
// or for closing reader
}
}
getEncoding
esigenze per controllare i risultati della connessione del getContentEncoding()
e getContentType()
di determinare la codifica della pagina web; il tuo codice utilizza solo la codifica predefinita della piattaforma, che potrebbe essere errata.
Il tuo esempio però è insolito in termini strutturati, poiché è molto procedurale; Normalmente si dovrebbe separare la stampa ed il recupero in un sistema più ampio, e consentire il codice del client per gestire qualsiasi eccezione (o, talvolta, di cattura e creare un'eccezione personalizzata):
public static void main (String...args)
{
final GetOneLine getOneLine = new GetOneLine();
try {
final String value = getOneLine.retrieve (new URL (args.length > 0 ? args[0] : questionUrl));
System.out.println (value);
} catch (IOException e) {
// exception handling for retrieving one line of text
}
}
public String retrieve (URL url) throws IOException
{
final URLConnection connection = url.openConnection();
final InputStream in = connection.getInputStream();
try {
final BufferedReader br = new BufferedReader (new InputStreamReader (
in, getEncoding (connection)));
try {
return br.readLine();
} finally {
br.close();
}
} finally {
in.close();
}
}
Come McDowell ha sottolineato, potrebbe essere necessario chiudere il flusso di input se new InputStreamReader
genera.
Il codice è in realtà ha un piccolo problema nella clausola finally. È possibile che 'isr' e' br' siano ancora 'null' nella clausola finally come' InputStreamReader' e che i costruttori 'BufferedReader' generino eccezioni. Dovresti cambiare la clausola finally in: 'finally {if (br! = Null) br.close(); if (isr! = null) isr.close(); } '. Questo non è ancora corretto perché 'br.close() 'potrebbe lanciare un'eccezione e quindi 'isr' non verrà chiuso in quel caso. La risposta di Andreas sembra essere il modo di seguire IMHO. – Behrang
Non catturare mai "Eccezione" a meno che non si sappia perché –