Choose your language
feb 02

Che confusione!
Sui tipi annidati (nested type) e la classi interne (inner classes) in giro per la rete ci sono scritte un sacco di fregnacce! Probabilmente perché la SUN, a partire dalla versione 1.4 di java, ha fatto un po’ di casini con la nomenclatura, modificando il significato di alcuni termini. Comunque sia, ora proviamo a fare chiarezza.
Per prima cosa mettiamo in chiaro un concetto: le definizioni in informatica si danno e si usano in inglese. Ci si può riferire al corrispondente termine italiano per meglio comprendere di cosa si parla, ma è l’inglese che rende univoco un concetto o una definizione.
Torniamo quindi all’Università e alle definizioni :-)

Definizione:
Con il termine nested type (tipi annidati) si intende indicare:

  • nested classes
  • nested enums
  • nested interfaces

Definizione:
Con il termine nested class (classe annidata) si intende una classe dichiarata all’interno di un’altra classe.
Allo stesso modo si definisono le nested enum e le nested interface.
Ci sono 4 tipi di nested classes:

  1. static member classes, enums e interfaces
  2. non-static member classes
  3. local classes
  4. anonymous classes

Definizione:
Con il termine inner class (classe interna) si indica una qualsiasi nested class purché NON di tipo 1 (vedi definizione precedente).

Facciamo un esempio commentato a dovere:

class Alessandro {              // (1) Top level class
    static class SMC {/*...*/}  // (2) Static member class
    interface SMI {/*...*/}     // (3) Static member interface
    class NSMC {/*...*/}        // (4) Non-static member (inner) class
    void nsm() {
        class NSLC {/*...*/}    // (5) Local (inner) class in non-static context
    }
    static void sm() {
        class SLC {/*...*/}     // (6) Local (inner) class in static context
    }
    SMC nsf = new SMC() {       // (7) Anonymous (inner) class in non-static context
        /*...*/
    };
    static SMI sf = new SMI() { // (8) Anonymous (inner) class in static context
        /*...*/
    };
    enum SME {/*...*/}          // (9) Static member enum
}
  • Share/Bookmark
Tagged with:
dic 02

Ma abbiamo davvero capito come vengono gestiti i reference in java?
Piccolo snippet per metterci alla prova.
Ammettiamo di avere 2 classi

  • ClasseA
  • ClasseB

e che ClasseB sia una sottoclasse di ClasseA ossia “ClasseB extends ClasseA”.
ClassB extends ClassA
Ora, supponendo che le classi si trovino tutte nello stesso package, scriviamo questo codice nel nostro main method:

ClasseA a;
ClasseB b;

a = new ClasseA();
b = new ClasseB();

a = b; //(1)
b = a; //(2)

Problemi?
Il codice scritto funziona? Anzi, compila?
La risposta è, ovviamente, no :-) e il problema è nell’ultima riga (2): b = a;
Perché?
Eppure sembra tutto ok!
In (1) abbiamo assegnato b ad a, quindi a = b. Come è mai possibile che scrivendo poi b = a la cosa non sia corretta?
La spiegazione è nel tipo di dichiarazione iniziale dei reference a e b.
ClasseA è una superclasse di ClasseB, quindi scrivere a = b è possibile per automatico widening (a è “più grande” di b). La cosa invece non è possibile in senso inverso perché b è “più piccolo” di a e non può quindi “contenerlo”.
L’osservazione più comune a questo punto è:
ma se in (1) abbiamo scritto a = b significa che a e b sono diventati uguali! Quindi come è mai possibile che b = a dia problemi? :-)
Già, come è mai possibile?
Leggete il post su java i reference e la RAM e forse ne capirete di più… :-)

  • Share/Bookmark
Tagged with:
nov 19

Molti le nominano, pochi le usano, meno le conoscono.
Eppure sono moderatamente utili e molto semplici da usare…
In java una

assert

è un’affermazione che il programmatore fa in un certo punto del codice da lui scritto.. Il compilatore si occupa di verificare che tale affermazione sia corretta, in caso contrario lancia un’eccezione di tipo unchecked. E’ decisamente opportuno disabilitarle in fase di produzione del sistema, mentre possono essere utili in fase di sviluppo e test.

Come si dichiarano?
In 2 modi diversi:

assert <boolean expression>;
assert <boolean expression>: <message expression>;

Se ad esempio, in una nostra classe stiamo calcolando la velocità come spazio/tempo, potremmo scrivere:

assert spazio > 0;
assert tempo > 0: "Il tempo non è un numero positivo!" + tempo;

Come si abilitano?
Per default le asserzioni sono disabilitate.
Bisogna quindi esplicitamente abilitarle. Ecco come fare:

>java -ea <classe da eseguire></classe>

In questo modo abilitiamo l’uso delle asserzioni nella nostra classe e in tutte le sue dipendenze, ma non nelle classi di sistema (quelle caricate direttamente dalla JVM). Per abilitare anche quelle ci tocca scrivere:

>java -esa

L’errore più clamoroso che si possa commettere nell’uso di una

assert

è quello di confonderla con la gestione delle eccezzioni!

  • Share/Bookmark
Tagged with:
nov 17

Il sistema utilizzato da java per passare parametri ai metodi è molto semplice, eppure nella mia breve storia di programmatore java in molti mi hanno chiesto delucidazioni su questo argomento. In base alla mia esperienza posso dire che avere problemi nel capire come funziona il passaggio dei parametri in java significa avere problemi con reference e dati primitivi.
Quindi, per prima cosa, vi rimando alla lettura di tali post!

Se avete chiara la differenza tra un reference e un dato primitivo, diventa tutto facile.
In java i parametri vengono sempre passati per valore e sempre duplicati con copie locali al metodo.
Dovrebbe però essere chiaro che duplicare una variabile di tipo primitivo è diverso dal duplicare una varibile di tipo reference! Duplicare un reference significa avere 2 reference che puntano allo stesso oggetto! Ecco perché quando in un metodo modifico il valore di un parametro di tipo primitivo esso non modifica il valore del parametro fuori dal metodo, mentre quando uso un parametro di tipo reference ogni modifica apportata all’oggetto puntato da tale reference viene riflessa sull’oggetto puntato dal parametro esterno: entrambi i reference (essendo uno la copia dell’altro) puntano lo stesso oggetto!

  • Share/Bookmark
Tagged with:
nov 01

Non molto tempo fa abbiamo cercato di dipanare la matassa intorno alla gestione dei reference.
In questo post invece cerchiamo di capire come funzionano i dati primitivi nella memoria del PC.
Innanzitutto un dato primitvo NON è un oggetto!
Tuttavia, ogni dato primitivo ha una corrispondente wrapper class che può essere usata per rappresnetarlo come un oggetto. Ma in questo post non parleremo di questo.
Ci occuperemo invece di quali sono i dati primitivi in java e come vengono rappresentati nella RAM del PC.
Possiamo dividere i dati primitivi in 3 categorie:

  • integral types (byte, short, int, long e char)
  • floating-point types (float, double)
  • boolean type (boolean)

E’ lecito scrivere:

int intVar = 10;

Cosa succede nella RAM del PC quando noi scriviamo una tale istruzione?
La figura di seguito dovrebbe spiegarlo.
Il dato primitivo nella RAM
Nella cella di memoria con sfondo verde è stato inserito il valore del nostro tipo primitivo; in questo caso il valore 10. Da adesso in poi ogni istruzione di modifica della variabile intVar modificherà direttamente il valore contenuto in quella cella di memoria. Quindi scrivendo:

intVar = 163;

java modificherà per noi il contenuto della cella in figura.
E’ molto importante notare e capire che java gestisce in modo differente gli oggetti e i dati primitivi.

  • Share/Bookmark
Tagged with:
ott 26

Questo è un argomento ostile, nel quale è facile perdersi, ma nello stesso tempo è la prima porta da aprire se si vuole entrare a pieno titolo nel mondo della programmazione java…

Innanzitutto distinguiamo tra reference value e object reference.
Un reference value rappresenta un valore (value) e precisamente il valore che viene restituto quando viene creato un particolare oggetto.
Un object reference (o semplicemnte reference) rappresenta invece una variabile che può memorizzare un reference value.
Questa differenza deve essere chiara perché altrimenti niente sarà mai chiaro con i reference in java!
Ora traduciamo questi concetti in codice.
Creiamo 2 object reference di tipo MiaClasse:

MiaClasse refOggetto1, refOggetto2;

Scrivendo questa riga di codice abbiamo comunicato a java di creare due variabili (nella RAM del calcolatore) di tipo MiaClasse e gli abbiamo anche detto che in queste 2 variabili DOVRANNO essere inseriti dei valori che si riferiranno (reference) a 2 oggetti di tipo MiaClasse. Stiamo parlando di “reference”! Questo significa che in queste 2 variabili java NON inserirà MAI gli oggetti veri e propri, ma il rifeimento a tali oggetti!!!
Rileggete bene l’ultimo paragrafo: è molto importante!

Bene. Inseriamo allora tali riferimenti ai 2 oggetti:

refOggetto1 = new MiaClasse(1);
refOggetto2 = new MiaClasse(2);

A questo punto java assegna un valore a refOggetto1 e un altro valore a refOggetto2. Ribadisco ancora che tale valore NON indica l’oggetto vero e proprio, ma indica la posizione (in RAM) dell’oggetto; il suo “riferimento”.
Si può rappresentare graficamente quanto detto con la seguente figura (scusate la poca eleganza).

Oggetti in RAM

In questa figura c’è rappresentato tutto quello che bisogna sapere sui reference!
Continue reading “Java, i reference e la RAM” »

  • Share/Bookmark
Tagged with:
preload preload preload

Search engine optimization by SEO Design Solutions