apr 17

Java, anonymous classes (classi anonime)

Stampa questo articolo

Un’anonymous class (classe anonima) è una inner class che viene contemporaneamente definita e istanziata e non ha un nome.
Un’anonymous class (classe anonima) esiste se e soltanto se esiste una super classe da estendere o un’interfaccia da implementare!
Quando estende una classe, la sintassi dichiarativa assume la seguente forma:
new <nome superclasse> (<lista opzionale di argomenti>) {…}
Quando invece implementa un’interfaccia, assume la seguente forma:
new <nome interfaccia> () {…}
Bisogna osservare che sebbene una classe anonima estenda una classe o implementi un’interfaccia, essa non usa né la clausola extends né la clausola implements.
Inoltre, come per le local classes, anche le anomymous classes non possono usare la parola chiave static in fase di dichiarazione.
[to be continued...]

Tagged with:
apr 12

Java, local classes

Stampa questo articolo

Per local class (classe locale) si intende una inner class che è definita in un blocco di codice. Un blocco di codice potrebbe essere il corpo di un metodo, di un costruttore, un blocco locale, un inizializzatore statico o un inizializzatore di istanza.
Alcune caratteristiche di una local class:

  • una local class non può avere memebri statici (questo però non esclude la possibilità di avere un membro final static, essendo esso una costante)
  • una local class non può avere modificatori di accessibilità (public, private, ecc.). Sarà quindi dichiarata scrivendo semplicemente class nomeClasse {…}
  • una local class può estendere un’altra classe
  • all’interno del blocco in cui è definita, una local class può accedere solo ai membri dichiarati final
  • una non-static local class può accedere sia ai membri statici sia ai membri non statici della classe contenitore (da non confondere con il blocco contenitore)
  • una static local class può accedere solo ai membri statici della classe che la contiene
  • una local class (essendo locale) può essere istanziata solo nel blocco nel quale è definita e deve essere dichiarata prima di essere utilizzata

Prima accortezza: se il blocco contenente la dichiarazione della local class è definito in un contesto statico (ad esempio un metodo statico o un inizializzatore statico) allora la local class è implicitamente statica e quindi non richiede alcun oggetto contenitore per essere istanziata.
Facciamo però attenzione al fatto che, sebbene in certi contesti (appena visti) la local class è intesa implicitamente statica, essa non consente di utilizzare nella propria dichiarazione la parola chiave static. Mai.
Facciamo anche attenzione al fatto che se una local class si trova dichiarata in un contesto statico, ciò influenzerà quello che la local class può “vedere” nel contesto contenitore. Prosegui nella lettura di “Java, local classes” »

Tagged with:
apr 04

Java, non-static member class

Stampa questo articolo

Una non-static member class è una inner class definita senza la keyword static (vedere il punto (2) dell’esempio sotto).
Bisogna osservare che:

  • Un’istanza di una non-static member class può esistere solo e soltanto insieme all’istanza della classe che la contiene
  • Una non-static member class non può avere static members (a meno che non siano anche final)
  • Il codice scritto in una non-static member class può avere accesso diretto a ogni membro (inclusi i nested) anche se dichiarato private

Vediamo un esempio con un po’ di casi particolari.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class MyLinkedList {
    private String message = "Shine the light"; // (1)
   
    public Node makeInstance (String info, Node next) {
        return new Node(info, next);
    }
   
    public class Node { // (2) non-static member class (NSMC)
        final static int maxNumOfNodes = 100;
        private String nodeInfo;
        private Node next;
        private String message ="Messaggio dal Nodo "; // (3)
       
        public Node(String nodeInfo, Node next) {
            this.nodeInfo = nodeInfo;
            this.next = next;
        }
       
        @Override
        public String toString(){
            message = "Modifica del message di Node"; // (4)
            return MyLinkedList.this.message + " in " + nodeInfo + " (" + maxNumOfNodes + ")"; // (5)
        }
    }
}

public class ListClient {
    public static void main(String[] args) {
        MyLinkedList list = new MyLinkedList();
        MyLinkedList.Node node1 = list.makeInstance("node1", null);
        MyLinkedList.Node node2 = list.makeInstance("node2", node1);
        System.out.println(node2.toString());
    }
}

Osserviamo il punto (4).
Viene modificato il valore asseganto all’attributo di tipo stringa message. Ma esistono 2 attributi di tipo stringa denominati message! Li vediamo dichiarati al punto (1) e al punto (3), entrambi private. Il message al punto (1) appartiene alla classe contenitore (MyLinkedList), mentre quello dichiarato al punto (4) appartiene alla non-static inner class (Node). Abbiamo detto che in una non-static member class possiamo riferirci a qualunque membro, anche dichiarato private, anche appartenente alla classe contenitore. Ma come possiamo riferisci all’attributo message del contenitore? Lo si può fare con un uso particolare della parole chiave this. Osserviamo a tal riguardo il punto (5).

ATTENZIONE.
Se non fosse stato dichiarato l’attributo al punto (4), allora scrivendo

1
return message + " in " + nodeInfo + " (" + maxNumOfNodes + ")"; // (5a)

non si avrebbe alcun errore (come invece ci si potrebbe aspettare), poiché ci riferiremmo, in modo implicito, all’attributo message della classe contenitore!!!
Facciamo attenzione a questo caso particolare!

Tagged with:
feb 02

Java 1.6, nested type e inner classes

Stampa questo articolo

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
}
Tagged with:
nascondi colonna destranascondi colonna destra
preload preload preload

Optimized by SEO Ultimate