Category: magico mondo de Java

NFC: qualcosa si muove (part-two)

NFC2Seconda parte dell’articolo su come scrivere programma che legge da un tag RFC e scrive su un tag RFC. Qui potete trovare quanto scritto sulla lettura da un tag NFC.
La parte che andremo ad analizzare prevede la scrittura di alcune informazioni su un tag NFC, attraverso l’interfaccia della nostra applicazione. Nello specifico andremo a scrivere i dati di un nuovo contatto della rubrica sul tag e successivamente potremo leggere quanto scritto con la funzionalità vista nell’articolo precedente.

Anche in questo caso la logica che sta dietro alla funzionalità è basata sugli eventi, in particolare, per la classe NFCWriter viene registrato un evento, il Tag Detection, che quanto catturato, esegue il codice contenuto al suo interno. Dall’interfaccia viene richiesto di inserire il testo da scrivere sul tag, si preme su OK e si avvicina il cellulare in prossimità del tag. A quel punto viene gestito l’evento che si preoccupa di stabilire una connessione con il tag NFC ed inviare.

 

write-on-nfc-1     write-on-nfc-3

 

Vediamo il codice che realizza quanto detto:

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
35
36
37
38
39
40
41
42
43
44
45
public class NDEFWriter extends NDEFHandler {
    Form previousScreen = null;
    String fName = "No name";
 
    public NDEFWriter(Form form) {
	previousScreen = form;
    }	
 
    public void targetDetectionMade(TargetProperties[] tProp) {
	previousScreen.append("Target detected.\n");
	if(tProp == null || tProp.length == 0) {
	    previousScreen.append("No TargetProperties found!\n");
	}
	NDEFTagConnection ndefTagConnection = null;
	try {				
	    previousScreen.append("Target mapping:"+tProp[0].getMapping()+"\n");				
	    ndefTagConnection =NDEFUtil.getNDEFTAGConnection(tProp,previousScreen);
	    if(ndefTagConnection == null) {
		previousScreen.append("Could not establish connection to card.\n");
		return;
	    }
	    NDEFUtil.writeNDEFMessage(ndefTagConnection,previousScreen);
	    ndefTagConnection.close();
	} catch (Exception e) {
	    if(ndefTagConnection != null) {
		try {
		    ndefTagConnection.close();
		} catch (IOException e1) {
		    previousScreen.append("Exception in closing connection:"+e1.toString());
		}
	    }
	    previousScreen.append("Exception:\n"+e.toString()+"\n");
	    e.printStackTrace();
	}
 
    }
 
    public String getFormattedName() {
	return fName;
    }
 
    public void setFormattedName(String fName) {
	this.fName = fName;	
    }
}

Verifica dei dati scritti sul tag

Come potete vedere non è molto difficile realizzare un programma Java che sfrutti le potenzialità fornite dalla tecnologia NFC, tutta sta a conoscere un pò le API messe a disposizione dalla Nokia. Tutto il resto è Java, gestione degli eventi, ereditarietà, interfacce, etc etc. Un vero (buon) programmatore Java non troverà alcuna difficoltà a realizzare la maggior parte delle funzionalità.
Questo è tutto.
Il codice completo per far girare l’esempio lo trovato nelle SDK del Nokia 6131 NFC è necessario la registrazione sul sito per poter effettuare il download. Dopo di che cercate nella cartella examples.
Stay tuned. yo.
 

NFC: qualcosa si muove (part-one)

NFC2Oggi ho visto in tv un servizio che parlava su come usare il proprio cellulare per effettuare piccoli pagamenti, il cosidetto telefonino/bancomat. Il funzionamento si basa sulla tecnologia Near Field Communication, ovvero un’evoluzione dell’ RFID la tecnologia che permette di far comunicare due dispositivi portanto in prossimità l’uno dell’altro. In questo articolo pubblicato sulle pagine di devme poco tempo fa, reperibile qui si parla di questa tecnologia, in particolare è possibile utilizzare il telefonino come fosse bancomato, nella modalità touch-to-pay: "avvicinando il cellulare sarà possibile utilizzarlo come una carta di credito. Le informazioni sensibili della carta sono memorizzate al suo interno in un elemento chiamato secure element. In sostanza funziona come una carta di credito senza contatto.E’ possibile visualizzare le informazioni informative classiche delle proprie transazioni".
Nello specifico in linea di principio basta scrivere i dati del proprio bancomat all’interno del cosidetto secure element e a quel punto sarà possibile, avvicinando il cellulare in prossimità di un dispositivo capace di leggere tag NFC, effettuare un’addebito sul proprio conto corrente. Pensateci, quale migliore comodità !!
Bene, analizziamo ora più da vicino, in un esempio molto semplice, come scrivere un programma che legge da un tag NFC e scrive su un tag NFC. Il programma è scritto in Java, l’IDE che utilizziamo per fare il test è Eclipse sul quale installeremo il plugin eclipseme che permette di sviluppare applicazione utilizzando le librerie J2ME.

Partiamo quindi lo scrivere la nostra midlet, DevMeNFCMidlet:

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
public class DevMeNFCMidlet extends MIDlet {
    Display display;
    MainList list;
    String[] actions = new String[]{"Read","Write","Show contacts"};
    Image[] images = null;
 
    protected void startApp() throws MIDletStateChangeException {
	display = Display.getDisplay(this);
	list = new MainList("Select action to do:", List.EXCLUSIVE,actions,images,this,null);
	display.setCurrent(list);
    }
 
    protected void pauseApp() {}
 
    public void destroyApp(boolean arg0) throws MIDletStateChangeException {
	notifyDestroyed();
    }
 
    /**
     * Helper method to change the current displayable
     * 
    */
    public void setToDisplay(Displayable dspl) {
	display.setCurrent(dspl);
    }
}

Nel caso vi foste persi qualcosa sulle Midlet Java, in breve, è un’applicazione che gira su sistemi su cui è presente la J2ME Virtual Machine. Per creare una Midlet è sufficente estendere la propria classe con la classe Midlet, messa a disposizione dal Wireless Toolkit. L’estensione impone l’implementazione di alcuni metodi dal momento che la classe Midlet è una classe astratta. Il metodo StartApp() viene richiamato al momento del lancio dell’applicazione e nel nostro caso crea una lista con 3 opzioni: Read, Write e Show Contacts. La nostra applicazione legge da un tag NFC virtuale, emulato per intenderci e scrive sullo stesso tag. L’emulazione viene messa a disposizione dalle librerie opzionali, Contactless Communication API scaricabili dal sito della nokia, che sarà dunque necessario rendere disponibili all’interno del progetto in eclipse. Lanciando l’applicazione avremo:

midlet-on-nfc

Ciò che si vede è l’interfaccia dell’emulatore con la midlet caricata e pronta per essere eseguita. L’emulatore sostanzialmente è un cellulare, nello specifico il nokia 6131 che possiede al suo interno un tag NFC con le relative librerie. Per avviare l’applicazione è sufficente cliccare il bottone (sul cellulare) in corrispondenza della voce Select.

midlet3-on-nfcL’applicazione come detto mostra il menù con 3 voce selezionabili, in particolare se selezioniamo l’opzione Read saremo in grado di leggere da un tag NFC un certo contenuto. Nella nostra simulazione, i tag NFC sono virtuali e vengono mostrati sulla destra nell’interfaccia dell’emulatore. Alcuni di questi sono attivi, connessi altri disconnessi. Per effettuare una simulazione di lettura trasciniamo il tag NFC attivo all’interno del cellulare come mostrato in figura. A quel punto il contenuto del tag viene mostrato all’interno del telefono.

Ma diamo un occhiata al codice che realizza la funzionalità. L’idea che sta dietro alla logica è molto semplice. Si registra la classe del Reader per un determinato evento, ovvero per l’evento Tag Detection. Rilevato il tag viene richiamato un metodo della classe che stabilisce una connessione con il tag e legge il messaggio inviato dal tag. Il contenuto del messagio viene visualizzato sul display del cellulare. Di seguito incollo il codice della classe Reader.

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
35
36
37
38
39
40
41
42
public class NDEFReader extends NDEFHandler {
    Form previousScreen = null;
    public NDEFReader(Form form) {
        super();
        previousScreen = form;
    }
 
    public void targetDetectionMade(TargetProperties[] tProp) {
	previousScreen.append("Target detected.\n");
	if(tProp == null || tProp.length == 0) {
	    previousScreen.append("No TargetProperties found!\n");
	}
	NDEFTagConnection ndefConnection = null;
	try {			
	    previousScreen.append("Target mapping:"+tProp[0].getMapping()+"\n");				
	    ndefConnection =NDEFUtil.getNDEFTAGConnection(tProp,previousScreen);
	    if(ndefConnection == null) {
		previousScreen.append("Could not establish connection to card.\n");
		return;
	    }
	    NDEFUtil.readNDEFMessage(ndefConnection,previousScreen);
	    ndefConnection.close();
	} catch (Exception e) {
	    if(ndefConnection != null) {
	        try {
		    ndefConnection.close();
	        } catch (IOException e1) {
		    previousScreen.append("Exception in closing connection:"+e1.toString());
	        }
	    }
	    previousScreen.append("Exception:\n"+e.toString()+"\n");
	    e.printStackTrace();
        }
    }
 
    public String getFormattedName() {
        return null;
    }
 
    public void setFormattedName(String fName) {}
 
}

Il metodo targetDetectionMade realizza tutto quello che è stato detto nel paragrafo precedente. Per quanto riguarda il resto del codice rimando ai prossimi articoli. Stay tuned! yo

Crittare l’url di un immagine in jsp con Spring

DataObfuscationIn questo articolo voglio far vedere come nascondere l’href di un immagine in una pagine JSP, pur visualizzando l’immagine come elemento HTML in modo standard.
Supponiamo di dover sviluppare un’applicazione web in cui ciascun utente mantiene una libreria multimediale, costituita per semplicità da soli elementi immagine. Ogni immagine viene memorizzata all’interno di un database assieme alla relative informazioni dell’utente a cui appartiene.
Affinché l’immagine non sia accessibile semplicemente attraverso l’indirizzo indicato nell’HREF, è necessario offuscare il suo contenuto attraverso una codifica il cui funzionamento è noto al sistema. Lo stesso sistema sarà in grado così di decodificare l’HREF in modo da poter restituire la risorsa e quindi visulalizzarla all’interno della pagina.
Vediamo il seguente esempio:

1
2
3
4
5
   <!-- Immagine in chiaro -->
   <img src="http://host/images/img.jpg" title="Immgine in chiaro" alt="" />
 
   <!-- Immagine offuscata -->
   <img src="http://host/image.htm?a=QVMyJCU0c2Rm%3D&b=QVMyJCU0c2RmMzI0M3NkdzI%3D" title="Immgine in chiaro" alt="" />

Nell’esempio di sopra viene mostrata un’immagine in cui l’href è crittata secondo un algoritmo che ora vedremo. E’ chiaro che nel secondo caso, affinché l’immagine possa essere visualizzata è necessaria la presenza di un elemento capace di interpretarne il contenuto, ottenere e restituire la risorsa.
Nell’ambito di Spring tutto questo può essere tradotto nel modo seguente: è necessario un Controller che venga richiamato ogni volta in cui nella pagina è presente un’immagine.
Il Controller dovrà prelevare il contenuto dell’HREF decodificarlo e restituire l’immagine, se corretto. Procediamo quindi per step.
Primo Step configuriamo il Controller (Servlet) all’interno di Spring…quindi editiamo il file di configurazione di spring ed aggiungiamo le seguenti righe di codice:

1
2
3
4
5
6
7
8
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" id="urlMapping"> 
        <property name="mappings">
	<value>/image.htm=mediaResolver</value>
        <property value="true" name="alwaysUseFullPath"></property>
    </bean> 
    <bean class="it.devme.obfuscator.media.MediaResolver" id="mediaResolver">
        <property name="dbManager"><ref bean="dbManager"></ref></property>     
    </bean>

L’invocazione della risorsa virtuale index.htm provoca l’invocazione del Controller MediaResolver. Vediamo la sua struttura di seguito:

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
35
36
37
public class MediaResolver extends BaseCommandController {
 
    private DBManager dbManager;
    public void setDbManager (DBManager dbManager) {
	this.dbManager = dbManager;
    }
 
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	Object mediaid = req.getParameter("a");
	Object uid = req.getParameter("b");
 
	if (mediaid==null || uid==null) 
	    return new ModelAndView(new MediaView("image/jpeg", "no-image.jpg", rs.getString("basePath"), MediaView.USE_DEFAULT_IMAGE));
 
	Encrypter dec = Encrypter.getInstance();
	int idaccount = Integer.parseInt(URLDecoder.decode(dec.decrypt(uid.toString()), "UTF-8"));
	int idelement = Integer.parseInt(URLDecoder.decode(dec.decrypt(mediaid.toString()), "UTF-8"));
 
	MediaBean media = null;
	File f = null;
	String mediaPath = null;
 
	/* Check if media item exists */
	media = dbManager.getImage(idelement, idaccount);
	if (media==null) return new ModelAndView();
	mediaPath = media.getPath();
	f = new File(UPLOAD_PATH + File.separator + mediaPath);
 
	MimetypesFileTypeMap mime = new MimetypesFileTypeMap();
 
	resp.setHeader("Cache-Control", "private,no-cache,no-store");
	resp.setContentType(mime.getContentType(f));
	return new ModelAndView(new MediaView(mime.getContentType(f), mediaPath, rs.getString("basePath"), !MediaView.USE_DEFAULT_IMAGE));
    }
 
}

La classe di sopra estende BaseCommandController e quando invocata viene richiamato l’unico metodo di cui è stato fatto l’override che si occupa di decodificare e restituire la risorsa. Vediamo come.
Sostanzialmente recupera i parametri dalla GET (nel nostro caso sono a e b). Li decodifica utilizzando un algoritmo di crittografia a noi noto (si può usare qualunque algoritmo a nostro piacimento basato su una chiave provata) e quindi ottiene per il parametro a, l’id dell’utente a cui appartiene la risorsa e per il parametro b, l’id della risorsa a cui si vuole accedere. Questi dati vengono passati in input ad un metodo che effettua una query su db (getImage(idelement, idaccount)) e verifica se effettivamente la risorsa richiesta appartiene all’utente corrente.
In caso contrario viene restituita una View vuota, altrimenti si determina il mime-type della risorsa e si restituisce una view creata a partire dalla classe MediaView.

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
35
public class MediaView extends AbstractView {
 
    private String media;
    private String basePath;
    private boolean noImage;
 
    public MediaView(String mime, String media, String basePath, boolean noImage) {
	this.media = media; 
	setContentType(mime);
	this.basePath = basePath;
    }
 
    @Override
    protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
	String rpath = 	null;
 
	rpath = this.basePath + request.getContextPath().substring(1) +
		MediaResolver.UPLOAD_PATH + File.separator + this.media;
 
 
	File f = new File(rpath);
	byte[] bytes = FileUtils.readFileToByteArray(f);
 
 
        // Write content type and also length (determined via byte array).
        response.setContentType(getContentType());
        response.setContentLength(bytes.length);
 
        // Flush byte array to servlet output stream.
        ServletOutputStream out = response.getOutputStream();
        out.write(bytes);
        out.flush();
    }
 
}

La classe MediaView non fa altro che leggere fisicamente i byte dell’immagine e restituirla nella response utilizzando un OutputStream. Il risultato è che l’immagine scritta nella response verrà visualizzata in pagina come un elemento HTML standard, mantenendo perà l’HREF dell’immagine crittato.
Alla prossima.

X-stream: xml è facile !

xml_at_workSalve a tutti…ebbene sì…si ricomincia. Siccome è passato un pò di tempo dall’ultimo post, inizierò a scrivere così come se niente fosse…così nessuno se né accorgerà :P  ! Sono alle prese con lo sviluppo di un’applicazione web, che fa uso di XML per la serializzazione dei dati. L’applicazione è scritta in Java, usa Spring come framework di appoggio. La parte fondamentale come dicevo, consiste nella serializzazione dei dati in XML. La struttura XML che deve essere serializzata non è molto complessa, ma neanche troppo semplice…per cui al primo impatto, ho deciso di non appoggiarmi sulle classiche librerie messe a disposizione da Java (xerces) o quelle presenti di default nelle API (javax.xml.parser).
Sono andato così alla ricerca in rete di qualcosa che potesse essermi utile, cercavo qualcosa che fosse facile da usare e al tempo stesso leggero, in modo tale da non appesantire l’applicazione. Ho trovato così XStream, una libreria che permette di serializzare oggetti in XML e viceversa. Il viceversa nel mio caso è fondamentale, dal momento che se possibile inizializzare una struttura dati di oggetti senza dover, materialmente, navigare l’XML mi ha aiutato molto.
Non mi soffermerò molto nel descrivere le caratteristiche della libreria, sopra come avrete notato ho linkato l’URL quindi potete fare da voi…mi concentrerò su qualche feature che mi è sembrata interessante e descriverò qualche esempio pratico.
La creazione di un file XML a partire da un oggetto Java è molto semplice, si parte dalla creazione e inizializzazione dell’oggetto stesso, dopo di ché si procedere richiamando un metodo statico che provvede alla generazione (serializzazione) del file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Blog {
  private String name;
  private String author;
  private Contacts contacts;
  /* getter&setter + constructor */
}
 
public class Contacts {
  private String email;
  private String url;
  /* getter&setter + constructor */
}
 
XStream xstream = new XStream();
XStream xstream = new XStream(new DomDriver());
 
/* GLi alias rendono la serializzazione pi&ugrave; chiara */
xstream.alias("person", Blog.class);
xstream.alias("phonenumber", Contacts.class);
 
Blog blog = new Blog("DevMe", "mulp");
blog.setContacts(new Contacts("mulp@devme.it", "http://www.devme.it"));
String xml = xstream.toXML(blog);
<blog>
    <name>DevMe</name>
    <author>mulp</author>
    <contacts>
    	<email>mulp@devme.it</email>
    	<url>http://www.devme.it</url>
    </contacts>
</blog>

Al contrario, dando in input l’XML prodtto, si ottiene l’oggetto inizializzato:

1
Blog blog = (Blog)xstream.fromXML(xml);

L’esempio di prima dimostra la facilità e la flessibilità d’uso della libreria XStream. Unico particolare degno di nota è il fatto di poter definire degli alias per le classi che permette poi, in fase di serializzazione di poter generare tag coincisi dal nome uguale al nome della variabile membro, a meno che non si chieda di cambiarlo. Per intenderci, se non avessi definito gli alias otterei come tag il nome completo della classe per il tag blog assieme al nome del package, nell’esempio quello di default.

XStream usa il meccanimo delle Annotations per definire gli alias, rendendo così la definizione decisamente più pratica. Vediamo un esempio di codice che non definisce alias:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package it.devme.music;
 
public class Police {
    private String songTitle;
    public Police(String songTitle) {
        this.songTitle = songTitle;
    }
}
 
package it.devme.music;
public class JukeBox {
    public static void main(String[] args) {
        XStream stream = new XStream();
	Police song = new Police("Message in a bottle");
	System.out.println(stream.toXML(msg));
    }
}

L’esecuzione del codice produce il seguente XML:

1
2
3
    <it.devme.music.Police>
        <songTitle>Message in a bottle</songTitle>
    </it.devme.music.Police>

Come si può notare, senza l’utilizzo degli alias la serializzazione in XML non è coincisa, in particolare il nome della classe Persona eredita l’intero percorso del suo package di appartenenza. Definiamo ora gli alias usando le Annotations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package it.devme.music;
 
@XStreamAlias("police-songography")
public class Police {
    @XStreamAlias("song")
    private String songTitle;
    public Police(String songTitle) {
        this.songTitle = songTitle;
    }
}
 
package it.devme.music;
public class JukeBox {
    public static void main(String[] args) {
        XStream stream = new XStream();
	Police song = new Police("Message in a bottle");
	System.out.println(stream.toXML(msg));
    }
}

L’esecuzione del codice produce il seguente XML:

1
2
3
    <police-songography>
        <song>Message in a bottle</song>
    </police-songography>

Notate ora come il file XML è più chiaro e come il nome dei tag non dipende strettamente dai nomi delle classi e/o delle variabili membro, ma dagli alias definiti all’interno della classe stessa.

Come ultima cosa volevo soffermarmi su un’altra caratteristica di questa libreria, i Converter. Questo meccanismo da la possibilità di poter gestire in fase di serializzazione/deserializzazione l’esatta elaborazione che deve essere svolta in modo tale da avere una corretta esecuzione delle procedure. Per poter scrivere il proprio Converter è necessario implementare l’interfaccia Converter ed implementare i metodi proposti:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package it.devme.music;
public class PoliceConverter implements Converter {
    public boolean canConvert(Class clazz) {
        return false;
    }
 
    public void marshal(Object value, HierarchicalStreamWriter writer,
                        MarshallingContext context) {
        }
 
    public Object unmarshal(HierarchicalStreamReader reader,
                        UnmarshallingContext context) {
        return null;
    }
}

Il metodo canConvert verifica l’applicabilità del converter rispetto alla classe che si desidera pre/post elaborare. Il metodo marshal è una pre elaborazione, mentre unmurshal è una post elaborazione. I casi d’uso di un Converter variano dai più semplici, in cui si applica una trasformazione al tipo di dato che dovrà essere serializzato (si pensi ad esempio ad una data in formato millisecondi da trasformare in gg/mm/aaaa), ai più complessi in cui è necessario elaborare un nodo complesso contenente sottoalberi, ovviamente in entrambe le operazioni di serializzazione/deserializzazione. Vi rimando al tutorial sui Converter per gli esempi del caso.

See U on next post, enjoy !

Singleton pattern: quando e come usarlo.

Traendo ispirazione su un post trovato per la rete, ho deciso di scrivere un piccolo, ma proprio piccolo post, sul pattern Singleton, molto usato durante le sessioni di programmazione per risolvere una certa classe di problemi comuni. Definiamo un singleton come:
una classe per cui esiste una sola istanza nell’applicazione, e per la quale viene fornito un’unico punto globale di accesso.
Vediamo un possibile modo di implementare il singleton:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class DevMeSingleton {
    /* class instance */
    private static DevMeSingleton instance;
    /* Costruttore privato della classe */
    private DevMeSingleton() {}
 
    /* Metodo che permette di ottenere l'istanza della classe */
    public static DevMeSingleton getInstance() {
        if (instance==null) {
            instance = new DevMeSingleton();
        }
        return instance;
    }
}

1. Semplice implementazione singleton pattern

L’implementazione di cui sopra, può causare problemi di performance nel contesto di un applicazione multithreading. E’ possibili che 2 thread ottengano in contemporanea 2 istanze della classe singleton, violando così un presupposto fondamentale della definizione. Per far sì che il comportamento non sia critico in un contesto del genere, si consideri l’utilizzo della tecnica: double-checked locking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DevMeSingleton {
        /* class instance */
        private volatile static DevMeSingleton instance;
 
        /* Costruttore privato della classe */
        private DevMeSingleton() {}
 
        /* Metodo che permette di ottenere l'istanza della classe */
        public static DevMeSingleton getInstance() {
            if (instance==null) {
                synchronized(DevMeSingleton.class) {
                    if (instance==null) {
                        instance = new DevMeSingleton();
                    }
                }
            }
        return instance;
    }
}

2. Tecnica double-checked locking

Questa tecnica purtroppo non funziona con la JVM 1.4 a causa della defizione della variabile volatile, la quale non era stata ancora implementata. Per ovviare a questo problema, vediamo l’implementazione successiva. 

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DevMeSingleton {
 
        /* class instance */
        private static DevMeSingleton instance = new DevMeSingleton();
 
        /* Costruttore privato della classe */
        private DevMeSingleton() {}
 
        /* Metodo che permette di ottenere l'istanza della classe */
        public static DevMeSingleton getInstance() {
            return instance;
        }
}

3. Creazione efficiente dell’istanza di una classe Singleton

L’implementazione di cui sopra, garantisce la creazione efficiente dell’istanza della classe singleton, piuttosto di una creazione cosiddetta lazy (pigra). Il singleton viene creato all’atto dell’invocazione della classe, in quel momento vengono istanziate tutte le varibili static, tra cui anche l’istanza del singleton. Spero che possa essere utile. A presto.

 

You need to log in to vote

The blog owner requires users to be logged in to be able to vote for this post.

Alternatively, if you do not have an account yet you can create one here.

Powered by Vote It Up

WordPress Themes