PDA

View Full Version : Java domanda semplice


vittorio130881
27-11-2014, 18:10
Ragazzi ciao oltre all implementazione di un singleton, che ho letto su un libro, a cosa serve dichiarare una variabe di tipo libro (esempio sciocco) all interno della definizione stessa della classe libro? Nel singleton piu o meno lho capito.... ma per il resto a cosa potrebbe servire?

wingman87
27-11-2014, 22:31
Può essere utile quando devi linkare tra loro gli oggetti. Per seguire il tuo esempio, se il libro fa parte di una collana potresti avere un riferimento al libro precedente e al successivo (otterresti una sorta di lista doppiamente concatenata).

vittorio130881
28-11-2014, 10:34
ok come esempio mi piace :)
grazie

vittorio130881
28-11-2014, 11:26
Pero non cè rischio di creare un loop infinito ovvero cre un libro dentro istanzio il precedente e il successivo ma cosi facendo il precedente istanzia altri due e cosi via.... cone potrei limitare il numero di istanze? Lo trovo pericoloso boh

wingman87
28-11-2014, 13:06
Se il libro è il primo della collana non ha un precedente, e se è l'ultimo non ha un successivo. Se il libro non fa parte di una collana non ha né il precedente né il successivo. Quindi non c'è un "loop" infinito.
Ovviamente devi programmarlo nel modo giusto. Da quello che dici penso tu abbia immaginato di creare le istanze di libro precedente e successivo nel costruttore di default del libro ma questo è sbagliato proprio perché vai a creare un "loop" infinito.
Un modo corretto è far creare i vari libri ad un modulo (resto sul vago di proposito) esterno al costruttore che si occuperà anche di concatenarli.

vittorio130881
28-11-2014, 15:41
Grazie!

vittorio130881
01-12-2014, 15:11
domanda ulteriore!!!!

se io ho una classe B che estende una classe A facendo ovverride di un metodo accelera() public.

nell'override di accelera ho fatto uso del metodo accelera della classe A mediante la parola chiave super.
tipo quando si fa il tostring e si prende il super.tostring + 'altro testo sottoclasse'.

fin qui tutto chiaro. quando però istanzio una classe B tipo
B pippo=new B();
quando faccio pippo.accelera chiamo il metodo di cui ho fatto l'override....ma dico una cavolata.....posso scrivere pippo.super.accelera ???
o avendo fatto l'override il metodo oramai da chiamare con una istanza pippo è per forza quello della classe B?
avrei tanto per capirci dovuto istanziare una classe A e usare pluto.accelera...... o al limite non fare l'override di quel metodo ma crearne uno nuovo in b cosi da ereditarlo senza modifiche.....scusate in anticipo se bestemmio :)

wingman87
01-12-2014, 20:33
La seconda che hai detto. Nel momento in cui nascondi un metodo della superclasse facendone l'override, questo non è più visible dall'esterno.

La parola chiave super può essere utilizzata solo dove è possibile utilizzare la parola chiave this, in particolare: nei metodi di istanza, negli inizializzatori d'istanza, nei costruttori e negli inizializzatori di variabili d'istanza. Fonte: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.11.2

vittorio130881
02-12-2014, 08:43
gazie wingman!

vittorio130881
02-12-2014, 09:01
La seconda che hai detto. Nel momento in cui nascondi un metodo della superclasse facendone l'override, questo non è più visible dall'esterno.

La parola chiave super può essere utilizzata solo dove è possibile utilizzare la parola chiave this, in particolare: nei metodi di istanza, negli inizializzatori d'istanza, nei costruttori e negli inizializzatori di variabili d'istanza. Fonte: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.11.2

dici non visibile all'esterno per le istanze della classe B ma per le istanze della classe A rimane accessbile spero!?

wingman87
02-12-2014, 09:25
Sì sì l'avevo dato per scontato

vittorio130881
02-12-2014, 09:32
ok :)

scusa wing dato che ci sto continuo a fare domandine.........

sto leggendo di SUPPRESSED del try with resources
ovvero le eccezioni lanciate durante la chiusura automatica degli oggetti (tipo connection) vengono soppresse a scapito di una eccezione avvenuta per esempio causa problemi di connessione........

ma vengono soppresse e quindi? chiuse lo stesso? e poi getsuppressed che roba è? dice il libro "lutilizzo di getsuppressed è permesso utilizznado le classi che implementano le interfacce closable........" arabo :D :D

wingman se sto parlando di cose che possono aspettare (magari si studiano dopo con jdbc) e non sono utili dimmelo che vado avanti.......sto alle eccezioni che per ora mi risultano chiare tranne questo :)

wingman87
02-12-2014, 11:10
Allora, premetto che non sono espertissimo dell'argomento perché in java non ho mai usato questa istruzione però leggendo la documentazione mi sembra abbastanza chiaro.
Da qui: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Dentro al blocco try potrebbe verificarsi un'eccezione, nel caso ciò avvenga (anche nel caso ciò non avvenga, ma poniamoci in questo caso speciale), verrà chiamato il metodo close dell'oggetto specificato nel try-with. Nel caso in cui il metodo close lanci un'eccezione, ti troverai nella situazione in cui sono state lanciate in sequenza due eccezioni e nel catch la jvm deve fare una scelta, cioè deve decidere quale eccezione viene "catchata". Per specifica, è stato deciso che l'eccezione "catchata" è la prima, quella che è stata lanciata nel blocco, l'altra però è sempre accessibile tramite il metodo getSuppressed dell'eccezione catchata.
In realtà getSuppressed ti restituirà una lista di eccezioni soppresse perché potresti trovarti in una serie di blocchi try-with annidati e per ognuno degli oggetti su cui viene chiamato close potrebbe venire lanciata un'eccezione.

Riguardo al fatto se la risorsa viene chiusa o meno... dipende da dove è andato in eccezione il metodo close perché è lui il responsabile di quell'operazione, ma direi che una volta che l'hai chiamato il tuo lavoro di programmatore dovrebbe essere finito a meno che non hai scritto tu il metodo close o se hai utilizzato male il framework che stai utilizzando...

vittorio130881
02-12-2014, 11:34
grazie

vittorio130881
04-12-2014, 17:21
altra domandina

sulle asserzioni
dato questo codice



“static {
boolean assertsEnabled = false;
assert assertsEnabled = true;
if (!assertsEnabled)
throw new RuntimeException("Asserts must be enabled!"); }”




il testo dice:
il blocco prima inizializza la variabile assertEnabled a false per poi cambiare il suo valore a true se le asserzioni sono abilitate. se non lo sono lancia un runtime exception


mah io sinceramente non vedo quello....vedo una verifica tramite assert della variabile che essendo falsa (dichiarata tale all0inizio) lancia un avvertimento....sbaglio?
anzi la parte
if (!asser......
mi sembra che non verrà mai eseguita visto che è false di partenza e già l'asserzione lo individua....mi aiutate? grazie!

wingman87
04-12-2014, 17:50
Se guardi bene l'espressione dopo l'assert puoi notare che non è un confronto ma un'assegnazione. Dopo l'assegnazione il valore dell'espressione è quello assegnato alla variabile e quindi true. Quindi se l'assert è abilitato effettuerà l'assegnazione, se invece non è abilitato l'assegnazione non avrà luogo e andrà in eccezione per via dell'if.

Sono interessanti le tue domande :)

vittorio130881
05-12-2014, 10:04
Hahaha grazie. Spero che le mie domande possano servire ad altri e che siano stimolanti per chi è già esperto.

Wingman sei grandissimo! Non avevo notato uguale come assegnazione....

Continuerò allora tanto qualcosa mi sfuggirà sicuramente. :)

vittorio130881
11-12-2014, 16:02
altra domanda come previsto


public void print(ArrayList<?> al) {
Iterator<?> i = al.iterator();
while (i.hasNext()) {
Object o = i.next();
System.out.println(o);
}
}


ho chiaro il concetto di wildcard in ottica di raw type. mi piace e la trovo utile. però mi è venuto un quesito in mente che non c'entra con i generics.....usando println su o dove o è un object in pratica si sta utilizzando il tostring che arraylist ha fatto come ovverride su object? quindi un metodo virtuale?

vittorio130881
11-12-2014, 16:15
no... credo di aver capito....chiama il tostring degli elementi di arraylist ...

tagan
11-12-2014, 16:24
altra domanda come previsto


public void print(ArrayList<?> al) {
Iterator<?> i = al.iterator();
while (i.hasNext()) {
Object o = i.next();
System.out.println(o);
}
}


ho chiaro il concetto di wildcard in ottica di raw type. mi piace e la trovo utile. però mi è venuto un quesito in mente che non c'entra con i generics.....usando println su o dove o è un object in pratica si sta utilizzando il tostring che arraylist ha fatto come ovverride su object? quindi un metodo virtuale?


non ho capito.....
comunque.
se hai una classe

public class MiaClasse {
public String stringa1;
public String stringa2;

public String toString(){
return "Override di toString : "+stringa1+"-"+stringa2;
}
}

....
ArrayList<MiaClasse> arrl = new ArrayList<>();
MiaClasse m1 = new MiaClasse();
m1.stringa1="valoreDiStringa1";
m1.stringa2="valoreDiStringa2";
arrl.add(m1);
MiaClasse m2 = new MiaClasse();
m2.stringa1="valoreDiStringa3";
m2.stringa2="valoreDiStringa4";
arrl.add(m2);

print(arrl);




il tuo esempio ti scrive:

Override di toString : valoreDiStringa1-valoreDiStringa2
Override di toString : valoreDiStringa3-valoreDiStringa4


cioè usi il toString della classe/oggetto contenuto nell'ArrayList.

vittorio130881
11-12-2014, 16:40
ecco questo....grazie!

vittorio130881
11-12-2014, 17:55
Errore scusate

vittorio130881
11-12-2014, 19:49
Scusate non riesco a scrivere da ipad

vittorio130881
11-12-2014, 19:55
errore di scrittura

vittorio130881
11-12-2014, 19:55
errore di scrittura

vittorio130881
11-12-2014, 19:56
public void print(List <? extends Number> list) {
for (Iterator<? extends Number> i = list.iterator(); i.hasNext( ); ) {
System.out.println(i.next());
}

public static void riempiLista(List<? super Integer> list) {
int size = list.size();
for (int i = 1; i <= size; i++) {
list.add(i);
}
System.out.println(list);
}




Inviato dal mio iPad utilizzando Tapatalk

vittorio130881
11-12-2014, 20:05
Domanda il testo dice sul tema generics queste cose

Partendo dal fatto che i parametri di un metodo possono essere di tre tipi:
1.parametro che contiene dati da usare (&ldquo;IN&rdquo; parameter): esempio del metodo print();
2.parametro che deve essere aggiornato (&ldquo;OUT&rdquo; parameter): esempio riempilista

usare upper bounded wildcard per parametri di tipo 1;
usare lower bounded wildcard per parametri di tipo 2;

Perché? sopra troverete l'esempio di upper bound e lower bound. non capisco perchè se devo usare/riempire una list devo usare super invece se devo leggerla/print extends. in particolare avevo letto che i wildcard rendevano di sola lettura i tipi parametrici e quindi come lo si fa a riempire nel riempiLista? grazieee

vittorio130881
11-12-2014, 21:00
Chiedo scusa ai moderatori e a tutti voi dei post duplicati....scusate

tagan
11-12-2014, 23:49
Domanda il testo dice sul tema generics queste cose

Partendo dal fatto che i parametri di un metodo possono essere di tre tipi:
1.parametro che contiene dati da usare (&ldquo;IN&rdquo; parameter): esempio del metodo print();
2.parametro che deve essere aggiornato (&ldquo;OUT&rdquo; parameter): esempio riempilista

usare upper bounded wildcard per parametri di tipo 1;
usare lower bounded wildcard per parametri di tipo 2;

Perché? sopra troverete l'esempio di upper bound e lower bound. non capisco perchè se devo usare una list devo usare super invece se devo leggerla extends. in particolare avevo letto che i wildcard rendevano di lettura il LISTarray e quindi come lo si riempie? grazieee

boooooooooh!!!!!!!!!
provo a risponderti, ma non ho capito molto cosa intendi

l'upper bounded wildcard cioè la wildcard limitata verso l'alto, significa che posso passare un parametro che è sottoclasse della classe dichiarata.
nell'esempio : print(List <? extends Number> list), accetta solo tipi che sono sottoclassi di Number (Float, Integer, Double, Short)
quindi posso usare un solo metodo per diverse Liste, senza necessariamente crearne una per ogni tipo.

il lower bounded wildcard funziona al contrario. accetta le superclassi di quella dichiarata. nell'esempio che hai riportato, riempiLista(List<? super Integer> list) il parametro che passi deve essere una lista di Integer, oppure una superclasse di Integer, quindi Number..... però genera errore se passi una lista di Float.

sinceramente ho sempre usato extends, mai super.

se dovessi inizializzare una lista con un metodo (modifichiamo il tuo), lo farei in questo modo:

public static void riempiLista(List<? super Integer> list) {
int size = 10;
for (int i = 1; i <= size; i++) {
list.add(i);
}
System.out.println(list);
}

//per chiamare il metodo
List<Integer> li = new ArrayList<>();
riempiLista(li);

ho cambiato int size = list.size() perché se passo una lista vuota, size = 0 e non verrebbe mai riempita.
anche questo modo, può essere usato per riempire liste di oggetto che sono superclassi di classi definite da te (non considerare Integer, ma pensa a Dipendente , sottoclasse di Persona)

public class Persona {
public String nome;
public Persona(String nome){
this.nome=nome;
}
}

public class Dipendente extends Persona{
public String ruolo;
public Dipendente(String nome, String ruolo){
super(nome);
this.ruolo=ruolo;
}

public String toString(){
return nome+"-"+ruolo;
}
}

public static void riempiLista(List<? super Dipendente> list) {
int size = 10;
for (int i = 1; i <= size; i++) {
list.add(new Dipendente("pippo",""+i));
}
System.out.println(list);
}



List<Persona> lp = new ArrayList<>();
riempiLista(lp);


altra cosa...... se scrivi :
public static void riempiLista(List<Dipendente> list)
il codice
List<Persona> lp = new ArrayList<>();
riempiLista(lp);

genera errore.


comunque, aspettiamo qualche esperto, perché oltre a dirti la differenza tra upper e lower, non capisco il metodo riempiLista scritto in quel modo!

una cosa però si puo dire. nel metodo riempiLista non ci puoi mettere:
riempiLista(List<? extends Number> list)
cosi scritta, il compilatore non riuscirebbe a capire che tipo verrà aggiunto e l'istruzione list.add(i) restituirà un errore.

PS: ma che libro stai studiando?

vittorio130881
12-12-2014, 11:23
grazie a tagan! e grazie a tutti voi della pazienza

vittorio130881
15-12-2014, 18:02
domanda finale sui generics
mi potete dire se ho capito bene?

i generics permettono di evitare i casting ovvero.....


ArrayList <Number> list = new ArrayList <Number>();
list.add(1); list.add(2.0F); list.add(2.0D); list.add(2L);
Iterator<Number> i = list.iterator(); while(i.hasNext())
{ Number n = i.next(); }

non serve fare il cast perchè il compilatore capisce da solo che è number.
invece quest altro codice



ArrayList list = new ArrayList();
list.add(1);
list.add(false);
list.add(‘c’);
int intero = (Integer) list.elementAt(0); boolean booleano = (Boolean) list.elementAt(1); character c = (Character) list.elementAt(2);


qui devo usare il cast perchè non cè il generics ma row types.

qualora usassi le wildcard cmq sia devo utilizzare uno stratagemma ovvero il metodo helper perchè il compilatore non capisce che sto usando una lista di stringhe :


public class WildCardTest {
void test(List<?> list) {
testHelper(list);
}
//Metodo helper
private <T> void testHelper (List<T> list) { list.set(0, list.get(0)); } }


List<String> param = getArrayListCompleto();
WildCardTest wct = new WildCardTest();
wct.test(param);