JSON e Java, come si semplifica la vita con Gson

JSON e Java, come si semplifica la
vita con Gson
In questo articolo vedremo come trattare facilmente il formato JSON in Java,
attraverso la libreria Gson.
Per chi non lo sapesse (tratto da Wikipedia) ecco che cos’è Json:
JSON, acronimo di JavaScript Object Notation, è un formato adatto
all’interscambio di dati fra applicazioni client-server.[1]
È basato sul linguaggio JavaScript Standard ECMA-262 3ª edizione dicembre
1999, ma ne è indipendente. Viene usato in AJAX come alternativa aXML/XSLT.[2]
I tipi di dati supportati da questo formato sono:
booleani (true e false);
interi, reali, virgola mobile;
stringhe racchiuse da doppi apici (");
array (sequenze ordinate di valori, separati da virgole e racchiusi in
parentesi quadre []);
array associativi (sequenze coppie chiave-valore separate da virgole
racchiuse in parentesi graffe);
null.
Uno dei motivi principali per cui JSON ha avuto successo negli ultimi anno è
perché permette di trasferire tra diversi dispositivi, che hanno in
esecuzione programmi scritti in diversi linguaggi di programmazione,
oggetti/informazioni/dati.
Grazie all’utilizzo del formato JSON è possibile convertire una variabile
string, del testo, in un “oggetto” in Java.
Ecco un esempio di un file JSON, che descrive una persona:
{
"nome": "Mario",
"cognome": "Rossi",
"nascita": {
"giorno": 1,
"mese": 1,
"anno": 1980
}
}
Come potete vedere, è davvero facile leggere un file JSON, in quanto la
sintassi usata è davvero minimale.
Ora vedremo qualche esempio su come usare la libreria Gson per poter
convertire un oggetto in un variabile string JSON e il viceversa, ovvero come
convertire una string JSON in un oggetto Java.
Per facilità di comprensione, useremo un oggetto davvero semplice, una
Persona che ha come attributi il nome, cognome e la data di nascita.
Ecco la classe Persona.java:
package model;
public class Persona {
private String nome;
private String cognome;
private Data nascita;
public Persona(String nome, String cognome, Data nascita) {
super();
this.nome = nome;
this.cognome = cognome;
this.nascita = nascita;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public Data getNascita() {
return nascita;
}
public void setNascita(Data nascita) {
this.nascita = nascita;
}
@Override
public String toString() {
return "Persona [nome=" + nome + ", cognome=" + cognome + ",
nascita=" + nascita + "]";
}
}
Ecco la classe Data.java:
package model;
public class Data {
private int giorno;
private int mese;
private int anno;
public Data(int giorno, int mese, int anno) {
super();
this.giorno = giorno;
this.mese = mese;
this.anno = anno;
}
public int getGiorno() {
return giorno;
}
public void setGiorno(int giorno) {
this.giorno = giorno;
}
public int getMese() {
return mese;
}
public void setMese(int mese) {
this.mese = mese;
}
public int getAnno() {
return anno;
}
public void setAnno(int anno) {
this.anno = anno;
}
@Override
public String toString() {
return "Data [giorno=" + giorno + ", mese=" + mese + ",
anno=" + anno + "]";
}
}
Ecco il primo test che permette di trasformare un oggetto di tipo Persona in
una variabile string e l’operazione inversa:
package tests;
import com.google.gson.Gson;
import model.Data;
import model.Persona;
public class ObjectToJSON {
public static void main(String[] args) {
Persona persona = new Persona("Mario", "Rossi", new Data(1,
1, 1980));
Gson gson = new Gson();
String jsonString = gson.toJson(persona);
System.out.println(jsonString);
Persona object = gson.fromJson(jsonString, Persona.class);
System.out.println(object);
}
}
Ed ecco l’output:
{"nome":"Mario","cognome":"Rossi","nascita":{"giorno":1,"mese":1,"anno":1980}
}
Persona [nome=Mario, cognome=Rossi, nascita=Data [giorno=1, mese=1,
anno=1980]]
Ecco il secondo esempio/test che utilizza una lista di oggetti di tipo
Persona, con le solite due operazioni, creazione e conversione:
package tests;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import model.Data;
import model.Persona;
public class ObjectsToJSON {
public static void main(String[] args) {
Persona persona1 = new Persona("Mario", "Rossi", new Data(1,
1, 1980));
Persona persona2 = new Persona("Giuseppe", "Verdi", new
Data(10, 10, 1970));
List<Persona> list = new ArrayList<>();
list.add(persona1);
list.add(persona2);
Gson gson = new Gson();
String jsonString = gson.toJson(list);
System.out.println(jsonString);
java.lang.reflect.Type listType = new
TypeToken<ArrayList<Persona>>() {
}.getType();
System.out.println(gson.fromJson(jsonString,
listType).toString());
}
}
Ed ecco l’output:
[{"nome":"Mario","cognome":"Rossi","nascita":{"giorno":1,"mese":1,"anno":1980
}},{"nome":"Giuseppe","cognome":"Verdi","nascita":{"giorno":10,"mese":10,"ann
o":1970}}]
[Persona [nome=Mario, cognome=Rossi, nascita=Data [giorno=1, mese=1,
anno=1980]], Persona [nome=Giuseppe, cognome=Verdi, nascita=Data [giorno=10,
mese=10, anno=1970]]]
Occorre ricordare, che dal momento che viene usato una libreria esterna
dall’ambiante Java, è necessario importarla all’interno del Java Build path.
La libreria Gson è facilmente scaricabile da Internet.
Conclusione
JSON è un formato davvero potente e semplice da usare, perché permette di
inviare dati/oggetti tra diversi componenti di un sistema software, con
diversi linguaggi di programmazione in gioco.
Calcolatrice in Java: esempi di DP
In questo articolo vedremo come realizzare una piccola calcolatrice in Java,
che ci permetterà di mettere in evidenza alcuni design pattern molto utili
quando si programma.
java
L’idea di questa semplice calcolatrice in Java è quella di poter eseguire la
somma delle principali operazioni matematiche, ovvero somma, sottrazione,
moltiplicazione e divisione tra due numeri, interi oppure frazionari.
Una volta che si inseriscono i due numeri basterà selezionare l’operazione e
il button “Calculate” per poter effettuare l’operazione richiesta.
Design pattern presenti
In questa applicazione Java è possibile trovare i seguenti design pattern:
Proxy: serve per poter decidere a run-time il tipo di operazione
MVC: serve per separare il modello, il controllo e la vista
Strategy: serve per creare un algoritmo in grado di essere facilmente
aggiornabile (è possibile aggiungere una nuova operazione e instanziarla
in una sola classe)
Il principale elemento del codice è l’interfaccia IOperation che permette di
facilitare notevolmente la scrittura del codice. Infatti, se una ci pensa
qualche secondo, una qualsiasi operazione matematiche, ha in ingresso dei
numeri (double in questo caso) e restituisce un risultato.
package mathoperation;
public interface IOperation {
/**
* This method allows to calculate the result of the operation
* @param p1
* @param p2
*/
public void calculate(Double p1, Double p2);
/**
* This method let the user to retrive the result calculated
* @return
*/
public String getResut();
}
Ovviamente ogni operazione avrà un algoritmo diverso, ma questo viene tenuto
in considerazione nelle classi concrete che implementano l’interfaccia.
Tornando ai DP, perché è necessario usare un Proxy ? L’utilizzo del Proxy
serve per poter cambiare facilmente a run-time un oggetto che in questo caso
è la nostra operazione matematica. In sostanza, sarebbero richieste troppe
modifiche se l’interfaccia grafica dipendesse dalle singole operazione e non
dal proxy (se si dovessero aggiungere delle operazioni, sarebbe necessario
modificare le classi della grafica). In questo caso, il Proxy viene
“inglobato” nel DP MVC; in questo caso il modello è l’operazione matematica,
che viene sostituta dalla classe concreta Proxy (che sarebbe il delegato,
cioè quel componente a cui viene chiesto qualcosa, un’operazione).
E la strategy ? Un aspetto molto importante del codice è aggiungere
un’operazione matematica è davvero semplice, questo grazie all’utilizzo della
classe OperantionsAvaible:
package mathoperation;
import java.util.ArrayList;
import java.util.HashMap;
public class OperationsAvaible {
private static OperationsAvaible avaible = new OperationsAvaible();
private ArrayList<IOperation> operations = new ArrayList<>();
private HashMap<IOperation, String> symbolOperations = new
HashMap<>();
private OperationsAvaible(){
createList();
setSymbol();
}
public void createList(){
operations.add(new Sum());
operations.add(new Subtraction());
operations.add(new Multiplication());
operations.add(new Division());
}
public void setSymbol(){
String[] value = {"+","-","*","÷"};
for (int i = 0; i < operations.size(); i++) {
symbolOperations.put(operations.get(i), value[i]);
}
}
public ArrayList<IOperation> getOperations() {
return operations;
}
public static OperationsAvaible getAvaible() {
return avaible;
}
public HashMap<IOperation, String> getSymbolOperations() {
return symbolOperations;
}
}
Come si può intuire, per poter aggiungere un’operazione è necessario creare
la classe concreta che implementa l’interfaccia IOperation ed inserirla
nell’ArrayList della classe OperantionsAvaible.
Conclusione
Dal momento che l’idea del progetto è abbastanza semplice (creare una
semplice calcolatrice), è possibile imparare in maniera facile alcuni
importanti design pattern in Java, quali il Proxy e il MVC (Model View
Controller). Ci sono alcuni metodi importanti, che non sono stati analizzati
in profondità. Il più importante tra questi è il metodo public void update()
della classe ProxyOperation, che permette di aggiornare il pannello (View),
quando viene premuto il Button (del Controller). Il codice completo è
possibile scaricarlo da questa repo:
https://github.com/jackbell16/Calculator
Concetti di base di Java: polimorfismo
In questo quinto post, sarà discusso il polimorfismo, uno dei più importanti
concetti di base di Java.
Il polimorfismo è uno dei concetti la cui definizione è di facile
comprensione, ma per capire completamente il concetto e sopratutto per
applicarlo correttamente, è necessario del tempo.
Ecco una definizione tratta da Wikipedia:
In informatica, il termine polimorfismo (dal greco πολυμορφοσ composto dai
termini πολυ molto e μορφή forma quindi “avere molte forme”) viene usato in
senso generico per riferirsi a espressioni che possono rappresentare valori
di diversi tipi (dette espressioni polimorfiche). In un linguaggio non
tipizzato, tutte le espressioni sono intrinsecamente polimorfiche.
Vantaggi
Il polimorfismo per inclusione permette al programma di fare uso di oggetti
che espongono una stessa interfaccia, ma implementazioni diverse. Infatti,
l’interfaccia del tipo base definisce un contratto generale che sottoclassi
diverse possono soddisfare in modi diversi – ma tutti conformi alla specifica
comune stabilita dal tipo base. Di conseguenza, la parte del programma che
fruisce di questa interfaccia – chiamata in gergo client – tratta in modo
omogeneo tutti gli oggetti che forniscono un dato insieme di servizi, a
prescindere dalle loro implementazioni interne (presumibilmente diverse tra
loro) definite dalle rispettive classi. In virtù di questa possibilità, si
può utilizzare lo stesso codice personalizzandone o modificandone anche
radicalmente il comportamento, senza doverlo riscrivere, ma semplicemente
fornendogli in inputuna differente implementazione del tipo base o dei tipi
base.
Se usato bene, il polimorfismo permette di avere una struttura ad oggetti
estensibile, in quanto si può indurre il client ad invocare nuovi metodi
personalizzati includendoli in una classe apposita;
resistente, perché eventuali esigenze future nel programma o nella
scrittura del codice potranno essere implementate fornendo ad
un client già scritto una nuova classe scritta ad hoc.
Da queste righe di introduzione del concetto di polimorfismo è intuibile
quanto detto in precedenza, riguardo alla difficoltà di comprendere
correttamente il suo utilizzo. Si può dire che questo aspetto di Java,
permette di rendere più robusto il codice e sopratutto sarà più semplice
aggiungere funzionalità aggiuntive.
Vediamo un primo esempio:
Fattoria
package utils;
public interface Animale {
public void emetteVerso();
}
Con questa struttura di codice è possibile aggiungere qualsiasi tipo di
animale, basterà che implementi la sua interfaccia e quindi dovrà emettere un
verso !
Disegnabile
package utils;
import java.awt.Graphics;
public interface Disegnabile {
public void disegna(Graphics graphics);
}
/**
* Questa classe ha la responsabilità di disegnare tutti gli elementi
* in un pannello
* @author Giacomo
*/
package utils;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;
public class Pannello extends JPanel {
private static final long serialVersionUID = 1L;
private ArrayList<Disegnabile> disegnabili = new ArrayList<>();
public void aggiungiDisegnabile(Disegnabile disegnabile){
disegnabili.add(disegnabile);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < disegnabili.size(); i++) {
disegnabili.get(i).disegna(g);
}
}
}
Attraverso l’interfaccia disegnabile, sarà possibile aggiungere al pannello
qualsiasi figura geometria, come ad esempio un rombo, quadrato etc…
Conclusione
Far dipendere i componenti del proprio progetto da Interfaccia, permette di
dare robustezza al nostro software e lo rende facilmente gestibile sia per
nuove implementazioni, sia per refactoring.
I codici presenti in questo post, come del resto tutti quelli delle lezioni
precedenti, sono scaricabili dalla repo di Github, all’indirizzo
https://github.com/jackbell16/JavaCode
Concetti di base di Java: Ereditarietà
In questo quarto post dedicato al mondo Java, vedremo il secondo paradigma
della programmazione ad oggetti: l’ereditarietà.
L’ereditarietà un concetto molto famigliare a noi. Vediamo un semplice
esempio a riguardo.
Facciamo l’esempio che dobbiamo realizzare un programmare che permette di
gestire alcuni dati relativi a persone, in particolare a studente. Una
persona può avere i seguenti attributi:
Nome
Cognome
Data di nascita
Città di nascita
Un metodo che può essere usato in alcuni applicazioni, può essere ad esempio:
calcolaEtà()
Uno studente, può avere i seguenti attributi:
Nome
Cognome
Data di nascita
Città di nascita
Matricola
Media dei Voti
Come metodi può avere:
calcolaEtà()
mostraMediaVoti()
Non notate qualcosa che accomuna queste due “classi” ? Sicuramente ci sono
quattro attributi in comune e il metodo in comune è quello che permette di
calcolare l’età. Qualora dovessimo scrivere queste due classi separatamente,
dovremmo scrivere del “codice duplicato” e questo non va bene, perché
eventuali modifiche, richiederebbero di andare alla ricerca del codice in più
punti diversi del programma e quando i progetti diventano sempre più grandi,
diventa complicata questa procedura !
Dal punto di vista “operativo” l’ereditarietà si implementa con la seguente
sintassi:
nomeClasseFiglia extends nomeClassePadre
Occorre notare che in Java non è supportata l’ereditarietà multipla (cosa
possibile in C++). Questa scelta è stata fatta ancora una volta per aumentare
la robustezza del linguaggio di casa Oracle.
Un esempio relativo a questo programma è possibile trovarlo nella seguente
cartella.
L’unico metodo che richiede un ulteriore commento riguarda quello del calcolo
dell’età:
public int getAge(Date date){
if((date.getMonth()>=birth.getMonth() &&
date.getDay()>=birth.getDay()) || date.getMonth()>birth.getMonth()){
return date.getYear()-birth.getYear();
}else{
return date.getYear()-birth.getYear()-1;
}
}
Il metodo accetta come parametro una data, che può essere quella di oggi e
restituisce un intero, che rappresenta l’età della persona. L’if in
particolare non è immediato da capire. Facciamo un esempio:
oggi è il 14 di Dicembre e prendiamo la mia data di nascita 16 Luglio 1992.
Attraverso il primo if, verifico se sia il mese che il giorno sia maggiore
della data di nascita, mentre nella seconda condizione, si verifica che il
mese della data passata come parametro, sia maggiore del mese di nascita. Se
non ci fosse la seconda condizione, io non avrei ancora compiuto gli anni,
perché 14>16 !
Ora introduciamo un nuovo tool importante per la programmazione ad oggetti: i
diagrammi UML
Questi diagrammi permettono di capire subito le relazioni che ci sono tra le
varie classi, i metodi e gli attributi di ciascuna di esse.
Facciamo ancora un altro esempio sull’ereditarietà. Facciamo l’ipotesi che
stiamo lavorando su un programma di geometria, che richiede l’utilizzo della
classi rettangolo e triangolo, per il calcolo delle aree. Potremmo
erroneamente, applicare così l’ereditarietà:
public
public
public
public
public
}
public
public
public
}
class
final
float
float
float
Triangolo {
int NUMERO_LATI = 3;
lunghezzaLatoUno;
lunghezzaLatoDue;
lunghezzaLatoTre;
class Rettangolo extends Triangolo {
final int NUMERO_LATI = 4;
float lunghezzaLatoQuattro; ........
Questo codice è corretto ? Per rispondere alla domanda in generale, cioè
capire se l’ereditarietà di giusto oppure no, occorre porsi la seguente
domanda:
nomeClasseFiglia è un nomeClassePadre ?
In quest’ultimo caso:
un rettangolo è un triangolo ? La risposta è no ovviamente !
Vediamo un po’ come poter ristrutturare il programma. Come primo passo, è
necessario usare un concetto importantissimo in Java che prende in nome di
astrazione e successivamente di generalizzazione.
Con il primo termine, si intende di “l’arte di sapersi concentrare solo sui
dettagli veramente essenziali nella descrizione di un’entità”. Mente come
generalizzazione, intendiamo il meccanismo con cui due classi con alcune
caratteristiche in comuni, possano essere rappresentate da una classe Padre.
Il codice dell’esempio relativo ai rettangolo e ai triangolo non è
sicuramente uno dei migliori, ma serve come esempio per capire quando
l’ereditarietà è utile da usare oppure no. Ecco il diagramma UML del
progetto:
Conclusione
Perché usare l’ereditarietà ? L’ereditarietà serve per rendere il codice più
semplice da leggere, più veloce da modificare e sopratutto per EVITARE CODICE
DUPLICATO !
Concetti base di Java: incapsulamento
Come già anticipato nel primo articolo su Java, i tre principali concetti dei
linguaggi ad oggetti verranno trattati singolarmente. In questo articolo
vedremo il primo, che prende il nome di incapsulamento. Questo strumento, è
uno dei più importanti in Java, perché rende quest’ultimo linguaggio
“robusto”. Il bravo programmatore, deve cercare di “nascondere” parte del
codice che non vuole che sia modificato dall’utente, per esempio, pur
rendendo accessibile a quest’ultimo attraverso altri meccanismi.
Ecco un piccolo esempio che chiarisce questo aspetto.
La maggior parte delle persone che sta leggendo questo articolo, avrà
sicuramente un cellulare. Uno dei principali dispositivi presenti in uno
smartphone è sicuramente la batteria, senza la quale non potrebbe funzionare
il dispositivo. Chi ha progettato il sistema operativo per il cellulare, avrà
sicuramente creato una funzionalità (interfaccia pubblica) con la quale il
singolo utente è in grado di capire la percentuale di batteria disponibile.
La percentuale della batteria sarebbe possibile anche calcolarla, smontando
il dispositivo e utilizzando un tester (facendo la misura della tensione ai
capi della batteria). Ma questo potrebbe causare il danneggiamento del
dispositivo ! Il principio dell’incapsulamento è molto simile all’esempio
precedente. Facciamo ora un esempio software. Facciamo che in un classe di un
programma, ci sia del codice che permette di inserire una data. Tutti sanno
che non tutti i mesi hanno 31 giorni, inoltre c’è un mese che ne ha 28.
Quindi alcune date, come ad esempio 31/9 non sarebbe valido e quindi sono
necessari alcuni controlli. Ecco il codice che mostra come non sia
vantaggioso l’utilizzo dell’incapsulamento:
/**
* Questa classe non sfrutta l'incapusalemtno. Dunque non è possibile
effettuare controlli sull'inserimento di dati.
* @author Giacomo
*/
package utils;
public class DateSenzaIncapsulamento {
public int year;
public int month;
public int day;
public DateSenzaIncapsulamento(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
@Override
public String toString(){
return day+"-"+month+"-"+year;
}
public static void main(String[] args) {
DateSenzaIncapsulamento dateSenzaIncapsulamento = new
DateSenzaIncapsulamento(2013, 9, 31);
System.out.println(dateSenzaIncapsulamento);
}
}
A video viene stampata la data che l’utente ha inserito senza nessun
controllo. Vediamo come dovrebbe essere la classe Date, con l’utilizzo
dell’incapsulamento. Dal punto di vista del codice, questa condizione si
trasforma nel rendere tutti gli attributi private e creare dei particolare
metodi di tipo public, che permette all’utente di accedervi. Occorre notare
che ci possono essere anche dei metodi private e non solo gli attributi.
/**
* Questa classe permette di instanziare date. Viene ancora una volta
mostrato il grande vantaggio che offre
* l'incapsulamento, permettendo di fare controlli sui dati inseriti
dall'utente.
* @author Giacomo
*/
package utils;
public class Date {
private int year;
private int month;
private int day;
public Date(int day, int month, int year){
setDay(day);
setMonth(month);
setYear(year);
}
public int getDay(){
return day;
}
public void setDay(int day){
int maxDay=31;
switch(month){
case 2: maxDay=28;
break;
case 4: case 6: case 9: case 11:
maxDay=30;
break;
default: break;
}
if(day<1){
verificaData();
day=1;
}else if(day>maxDay){
verificaData();
day=maxDay;
}
this.day=day;
}
public int getMonth(){
return month;
}
public void setMonth(int month){
if(month<1){
verificaData();
month=1;
}
else if(month>12){
verificaData();
month=12;
}
this.month=month;
setDay(this.day);
}
public int getYear(){
return year;
}
public void setYear(int year){
this.year=year;
}
public void verificaData(){
System.err.println("Attenzione, vefica il corretto inserimento della
data");
}
@Override
public String toString(){
return getDay()+"-"+getMonth()+"-"+getYear();
}
}
All’interno di questa cartella condivisa, è possibile trovare tutto il codice
che è appena stato descritto.
Vediamo di capire un po’ meglio come funziona il codice appena scritto. Gli
attributi che vengono inizializzati private rappresentano l’anno, il mese e
il giorno di una data. Successivamente viene scritto il costruttore, che non
è quello di default, dal momento che vengono inseriti direttamente i 3 valori
che rappresentano la data. Inoltre all’interno delle parentesi graffe vengono
impostati i 3 valori, attraverso i metodi set.
public Date(int day, int month, int year){
setDay(day);
setMonth(month);
setYear(year);
}
All’interno dei metodi set, vengono fatti i relativi controlli. Questo
permette di aumentare la robustezza del codice appena scritto, evitando che
l’utente possa inserire date sbagliate ! Il metodo toString() serve per
rappresentare con un certo layout la data inserita. La parola @Override verrà
chiarita nella prossima puntata, quando parleremo dell’ereditarietà.
Conclusione
Come già spiegato nelle righe precedenti, l’incapsulamento permette di
aumentare la robustezza del nostro codice, permettendo di accedere in modo
controllato ad attributi o metodi. Il codice scritto in questo metodo, oltre
che ad una migliore leggibilità, permette di essere utilizzato più volte nel
corso del tempo.
Eclipse: un ottimo tool per
programmare in Java
Nella scorsa puntata, abbiamo fatto una breve introduzione al linguaggio di
programmazione in Java. Come è stato indicato nel post precedente, per
iniziare a programmare basta un normale editor di testo. Questo è sempre
vero, ma quando i programmi iniziano a diventare sempre più complessi, con
molte classi, il codice da scrivere diventa sempre più grande. Per questo ci
viene incontro un ottimo tool di programmazione gratuito, che si chiama
Eclipse.
Eclipse è disponibile per le principali piattaforme, quali Mac Os, Windows,
Linux. Addirittura è possibile installarlo su Raspberry Pi, in modo da poter
usare il tool anche su iPad, attraverso un VNC Server. Per procedere
all’installazione del software basta andare nella pagina web dedicata ai
download http://www.eclipse.org/downloads/ e selezionare il pacchetto
dedicato per il proprio sistema operativo. Per quanto riguarda Windows,
l’installazione avviene tramite il solito installer, mentre per Mac Os è
necessario creare un pacchetto .App, per poter installare correttamente il
programma. Per Linux, in particolare per Ubuntu, l’applicazione è disponibile
in Ubuntu Software Center. Per le altre distro, basta digitare da terminale:
sudo apt-get install Eclipse
Per tutti i sistemi operativi, è necessario installare il pacchetto Java dal
sito di Oracle, anch’esso gratuito, che in pratica contiene la JVM.
Quali sono i principali vantaggi di Eclipse ?
Per chi non lo sapesse, Java è considerato un linguaggio semplice, perché se
qualcosa viene dimenticato dallo sviluppatore, il compilatore Java è in grado
di “capire” eventuali errori. Non vi siete accorti che negli esempi
precedenti, non è stato necessario importare alcune libreria ? Questo perché
ci ha pensato il compilatore ! Eclipse permette di automatizzare la scrittura
di parte del codice attraverso il Content Assist. In pratica se dobbiamo
digitato un ciclo for, basterà iniziare a scrivere la lettera f e premere
Ctrl+Space ed al resto ci pensa lui ! Altri vantaggi sono la possibilità di
capire se ci sono stati degli errori di sintassi del codice. Questo
sicuramente facilita la vita del programmatore, che in pratica dovrà “solo”
pensare ad organizzare correttamente il codice !
Ecco un esempio che mostra come usare Eclipse. Il programma che stiamo per
realizzare non fa altro che sommare i primi N numeri naturali. Per facilitare
la creazione di un programma, è conveniente creare dei pacchetti, dove
inserire le varie classi. Per esempio abbiamo creato il pacchetto utils, dove
inserire la classe “utile” , mentre nel pacchetto tests, verranno scritti i
vari tests.
/**
* Questa classe permette di calcolare la somma dei primi N numeri
* @author Giacomo
*/
package utils;
public class SommaPrimiNnumeri {
private static int somma = 0;
private int N;
public SommaPrimiNnumeri() {
super();
}
public int getN() {
return N;
}
public void setN(int n) {
if(n>0){
N = n;
}else{
System.out.println("Il valore di N inserito non e'
valido");
}
}
public int calcolaSomma(){
for (int i = 0; i <= getN(); i++) {
somma = somma +i;
}
return somma;
}
}
Il codice di Test01
/**
* Questo test permette di testare la classe SommaPrimiNnumeri
* @author Giacomo
*/
package tests;
import utils.SommaPrimiNnumeri;
public class Test01 {
public static void main(String[] args) {
SommaPrimiNnumeri nnumeri = new SommaPrimiNnumeri();
nnumeri.setN(10);
System.out.println("La somma dei primi "+nnumeri.getN()+"
numeri vale "+nnumeri.calcolaSomma());
}
}
Ecco il video che mostra come è stato “facile” creare questo programma in
Java:
http://youtu.be/DssaAtV5zFA
Per scaricare il Workspace creato, basta aprire il seguente link
Introduzione al linguaggio di
programmazione Java
Oggi inizia una breve panoramica su Java., che ha lo scopo di far conoscere
questo potente linguaggio di programmazione agli utenti. Dal momento che il
linguaggio presenta tantissime funzionalità, per ora verranno introdotti i
concetti basilari di questo linguaggio orientato agli oggetti, che verrano
introdotti in tre differenti post:
Incapsulamento
Ereditarietà
Polimorfismo
Prima di tutto quando nasce Java ? Esso nasce nei primi anni 90, attraverso
il programmatore James Gosling. In quegli anni il linguaggio di
programmazione più di moda era C++, che stava spopolando dopo il “mitico” C.
Fino a pochi anni fa, Java era gestito dall’azienda Sun, ora essa è stata
assorbita da Oracle. Uno dei principali vantaggi di questo linguaggio di
programmazione è quello di essere considerato “portabile”, cosa molto
richiesta nei giorni d’oggi, a causa della presenza di tantissime piattaforme
sul mercato dei PC. In pratica, quando si compila un programma in Java, si
creare il “bytecode”, che attraverso la Java Virtual Machine, è possibile
eseguirlo su “qualsiasi” piattaforma. Una frase che spiega questo concetto è
questo:
“Write once, debug anywhere” (“Scrivi una volta, correggi ovunque”)
Il termine qualsiasi tra “” è dovuta al fatto che recentemente sono stati
introdotti nuovi sistemi embedded, su cui è necessario un lavoro ulteriore
per migliorare la portabilità. Ecco una definizione, tratta da Wikipedia,
riguardo al termine embedded:
In elettronica e informatica, con il termine sistema embedded (generalmente
tradotto in italiano con sistema immerso o incorporato) si identificano
genericamente tutti quei sistemi elettronici di
elaborazione a microprocessore progettati appositamente per una
determinata applicazione (special purpose) ovvero non riprogrammabili
dall’utente per altri scopi, spesso con una piattaforma hardware ad hoc,
integrati nel sistema che controllano ed in grado di gestirne tutte o parte
delle funzionalità richieste.
Se Java risultata essere un linguaggio che permette di fare tutto, perché si
utilizza ancora il C ? Il C è usato tantissimo, ancora oggi, per la scrittura
dei driver per periferiche, nella domotica e nella robotica. Questo perché il
C è più veloce nell’essere compilato. Una differenza di compilazione era
molto evidenti agli inizi degli anni 90, ma dopo più di 20anni di sviluppo
Java è migliorato sotto questo punto di vista. Ora introduciamo alcuni
concetti basilari:
Classi
Oggetti
Metodi
Una clase può essere spiegata come un componente software, in cui sono
presenti righe di codice. Per esempio, una classe può contenere degli
algoritmi per la risoluzione di un problema, come la somma di Numeri. Inoltre
una classe può istanziare oggetti. Per esempio una classe “Persona”, può
creare nuovi oggetti, come Mario Rossi etc…. In pratica le clasi fanno da
“schema” per costruire oggetti. Per chi conosce già il linguaggio C, le
classi possono essere considerate delle struct, in cui vengono dichiari gli
attributi. Per esempio una possibile classe Persona, gli attributi sono Nome,
Cognome. Gli attributi sono le proprietà che gli oggetti possiedono di una
determinata classe. Gli attributi possono essere dichiarati in due modi (in
realtà esistono altri meccanismi, ma verrano trattati successivamente):
pubblico: visibile anche dall’esterno
privato: visibile solo entro la classe
Questo tipo di protezione è alla base dell’incapsulamento, ma parleremo
un’altra volta di questa importantissima proprietà di Java.
Come ultimo concetti, c’è Metodo. Per una più semplice comprensione, si può
dire che un metodo è una “sorta” di funzione che abbiamo visto in C. In
realtà c’è una certa differenza: in C le funzioni erano scritte per risolvere
problemi in modo procedurale, in Java, che è un linguaggio ad oggetti, il
meccanismo di programmazione è diverso.
Ora che abbiamo introdotto un po’ di concetti su Java, passiamo a
programmare. Per ora basta aver installato l’ambiente Java dal sito ufficiale
e un semplice editor di testa. Nella prossima puntata, vedremo Eclipse, un
potentissimo ambiente di programmazione, che facilità (e non poco) la vita
del programmatore.
Hello World in Java
Come primo programma in Java, useremo il famoso HelloWorld: questo programma
non fa altro che stampare a video un saluto.
class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
Il codice è molto simile a quello del linguaggio C. Dopo aver creato la
classe HelloWorld, che devo avere lo stesso nome del file con estensione
.java che abbiamo creato, viene dichiarato il Main, che indispensabile per
poter eseguire una classe (più avanti capiremo meglio…) successivamente viene
fatta una chiamata alla funzione System.out.println, che sostituisce la
printf del C. Ma in questo programma dove sono gli attributi e gli oggetti ?
Nel codice precedente non ci sono, dal momento che se ne poteva faremo a
meno, ma così facendo non è un programma che contempla la filosofia Java. Nel
prossima programma vedremo un’applicazione di oggetti e metodi.
/**
* Questo programma stampa a video un messaggio, usando i concetti di classe,
oggetto, metodo
* @author Giacomo Bellazzi
*
*/
public class HelloWorld {
private String messaggio;
public HelloWorld(String messaggio) {
super();
this.messaggio = messaggio;
}
public String getMessaggio() {
return messaggio;
}
public void setMessaggio(String messaggio) {
this.messaggio = messaggio;
}
public void toPrint(){
System.out.println(getMessaggio());
}
public static void main(String[] args) {
HelloWorld messaggio = new HelloWorld("Ciao Mondo");
messaggio.toPrint();
HelloWorld messaggio1 = new HelloWorld("Hello World");
messaggio1.toPrint();
}
}
Cerchiamo di capire un po’ questo linguaggio. Ancora una volta, è necessario
creare un file con lo stesso nome della classe. Dopo aver istanziato
quest’ultima, viene creato un attributo messaggio, che conterrà una
determinata frase. Da notare che gli attributi vengono scritti minuscolo,
mentre i nomi delle classi, vengono scritte in maiuscolo. In successione,
abbiamo il costruttore. Questo blocco di codice, ha lo scopo di facilitare
l’inserimento delle frasi per i vari oggetti “messaggio”. Non a caso, nel
main, abbiamo usato la sintassi HelloWorld(nome della classe) messaggio(nome
dell’oggetto) = new Helloworld(“frase che vogliamo attribuire all’oggetto”).
Questa sintassi permette di creare nuovi oggetti, dalla classe HelloWorld.
Nel codice precedente, sono stati creati tre metodi
getMessaggio() permette di ottenere il testo del messaggio
setMessaggio() permette di creare il testo del messaggio, senza
utilizzare il costruttore
toPrint() permette di stampare a video la frase dell’oggetto messaggio
Nel main, per richiamare i metodi, abbiamo usato la sintassi
nomeOggetto.metodo. Da notare la sintassi del nome dei vari metodi (prima
parola con lettera minuscola, poi le altri parole con lettere maiuscole.
Come ultimo esempio, vediamo un piccolo programma che fa la somma di due
numeri:
/**
* Questo programma calcola la somma di due numeri
* @author Giacomo Bellazzi
*
*/
public class DueNumeri {
private int a;
private int b;
public DueNumeri(int a, int b) {
super();
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int calcolaSomma(){
return a+b;
}
public void stampaSomma(){
System.out.println(calcolaSomma());
}
public static void main(String[] args) {
DueNumeri primoNumero = new DueNumeri(10, 5);
DueNumeri secondoNumero = new DueNumeri(16, 20);
primoNumero.stampaSomma();
secondoNumero.stampaSomma();
}
}
In questo caso, gli attributi sono a e b, due int che rappresentano il primo
e il secondo numero di una coppia di numeri, di cui vogliamo calcolare la
somma, attraverso il metodo calcolaSomma(). Questo metodo viene chiamato
all’interno dell’altro metodo, stampaSomma(). All’interno del main, abbiamo
creato i due oggetti di DueNumeri e abbiamo stampa a video la somma. Tutto
facile no ?
Per poter compilare un programma Java, occorre digitare da terminale:
javac nomeClasse.java
java nomeClasse
Conclusione
Questi semplici programmi, hanno lo scopo di incominciare a capire i concetti
basilari alla base di Java, quali Classe, Oggetto, Metodo. Le principali
caratteristiche, quali Incapsulamento, Ereditarietà e Polimorfismo verrano
trattati in tre differenti post.
Codici presenti nel post