String method(int x) { switch (x) { case 0: String s = "Ok"; return s; case 1: String s = "No"; return s; default: String s = "Problem"; return s; } }Perché il compilatore di Java non accetta di compilare questo codice dicendo che la variabile s è stata ridichiarata?
Il problema deriva dal fatto che i casi dentro uno switch non sono esclusivi. Quando un caso si applica, si esegue non solamente il codice di questo caso ma anche i casi successivi. Per esempio il codice da eseguire per il primo caso è:
String s = "Ok"; return s; String s = "No"; return s; String s = "Problem"; return s;Su questo codice è chiaro che la variabile s è ridichiarata. Una soluzione per risolvere questa situazione è usare sempre un blocco per delimitare il corpo di un caso:
String method(int x) { switch (x) { case 0: { String s = "Ok"; return s; } case 1: { String s = "No"; return s; } default: { String s = "Problem"; return s; } } }Adesso poiché una variabile non è visibile al di fuori di un blocco, tutto va bene.
class A { int i; A(int i) { this.i = i; } } class B extends A { int j; B(int i, int j) { this.i = i; this.j = j; } }Perché il compilatore di Java non accetta di compilare questo codice e dice che non può applicare A()?
Il problema deriva dal fatto che per creare un oggetto di tipo B, Java prima crea un oggetto di tipo A. Quando non c'è nessuna indicazione, Java prova a chiamare il costruttore senza parametro. Dunque il codice precedente è equivalente a
class A { int i; A(int i) { this.i = i; } } class B extends A { int j; B(int i, int j) { super(); this.i = i; this.j = j; } }L'errore deriva dal fatto che il costruttore senza parametro non è stato definito. Per risolvere il problema è sufficiente dichiarare tale costruttore:
class A { int i; A() {} A(int i) { this.i = i; } } class B extends A { int j; B(int i, int j) { this.i = i; this.j = j; } }Ovviamente è più naturale scrivere il codice seguente:
class A { int i; A(int i) { this.i = i; } } class B extends A { int j; B(int i, int j) { super(i); this.j = j; } }
Al tipo primitivo int è associato una class Integer. Dentro questa class c´è un metodo statico parseInt che permette di fare la conversione. Nel caso in cui la stringa non rappresenti un intero, parseInt solleva l'eccezione runtime NumberFormatException. Dunque per tradurre la stringa "12" in un intero è sufficiente fare:
int i = Integer.parseInt("12");Invece per convertire un intero in una stringa si può usare il metodo valueOf. Per esempio
String s = String.valueOf(12);Si può anche usare l'overloading dell'operatore +
String s = "" + 12;
Nella class System ci sono due campi statici in e out che rappresentano rispettivamente il canale di ingresso ed il canale di uscita del programma. Per esempio, per leggere dalla tastiera si può usare il metodo read. Invece per scrivere si può usare il metodo write o print.
Comunque per interagire con un programma in Java è meglio usare l'interfaccia grafica. Nella class javax.swing.JOptionPane ci sono due metodi statici showInputDialog e showMessageDialog che permettono rispettivamente di inserire e di mostrare una stringa.
Per esempio, il codice seguente permette di calcolare la somma di due valori che sono richiesti all'utente.
import javax.swing.JOptionPane; public class Test { public static void main(String[] args) { String s; int x, y, res; s = JOptionPane.showInputDialog("Inserire X"); x = Integer.parseInt(s); s = JOptionPane.showInputDialog("Inserire Y"); y = Integer.parseInt(s); res = x + y; JOptionPane.showMessageDialog(null, "Risultato " + res); } }