Groovy - Guida rapida

Groovy è un linguaggio orientato agli oggetti basato sulla piattaforma Java. Groovy 1.0 è stato rilasciato il 2 gennaio 2007 con Groovy 2.4 come versione principale corrente. Groovy è distribuito tramite la licenza Apache v 2.0.

Caratteristiche di Groovy

Groovy ha le seguenti caratteristiche:

  • Supporto per la digitazione statica e dinamica.
  • Supporto per il sovraccarico dell'operatore.
  • Sintassi nativa per elenchi e array associativi.
  • Supporto nativo per espressioni regolari.
  • Supporto nativo per vari linguaggi di markup come XML e HTML.
  • Groovy è semplice per gli sviluppatori Java poiché la sintassi per Java e Groovy sono molto simili.
  • È possibile utilizzare le librerie Java esistenti.
  • Groovy estende java.lang.Object.

Il sito ufficiale di Groovy è http://www.groovy-lang.org/

Esistono diversi modi per ottenere la configurazione dell'ambiente Groovy.

Binary download and installation- Vai al link www.groovy-lang.org/download.html per ottenere la sezione Windows Installer. Fare clic su questa opzione per avviare il download del programma di installazione di Groovy.

Una volta avviato il programma di installazione, seguire i passaggi indicati di seguito per completare l'installazione.

Step 1 - Seleziona la lingua del programma di installazione.

Step 2 - Fare clic sul pulsante Avanti nella schermata successiva.

Step 3 - Fare clic sul pulsante "Accetto".

Step 4 - Accetta i componenti predefiniti e fai clic sul pulsante Avanti.

Step 5 - Scegli la cartella di destinazione appropriata, quindi fai clic sul pulsante Avanti.

Step 6 - Fare clic sul pulsante Installa per avviare l'installazione.

Step 7 - Al termine dell'installazione, fare clic sul pulsante Avanti per avviare la configurazione.

Step 8 - Scegli le opzioni predefinite e fai clic sul pulsante Avanti.

Step 9 - Accetta le associazioni di file predefinite e fai clic sul pulsante Avanti.

Step 10 - Fare clic sul pulsante Fine per completare l'installazione.

Dopo aver seguito i passaggi precedenti, è possibile avviare la shell groovy che fa parte dell'installazione di Groovy che aiuta a testare i nostri diversi aspetti del linguaggio Groovy senza la necessità di disporre di un ambiente di sviluppo integrato a tutti gli effetti per Groovy. Questo può essere fatto eseguendo il comando groovysh dal prompt dei comandi.

Se vuoi includere i binari groovy come parte della tua build maven o gradle, puoi aggiungere le seguenti righe

Gradle

'org.codehaus.groovy:groovy:2.4.5'

Esperto di

<groupId>org.codehaus.groovy</groupId> 
<artifactId>groovy</artifactId>  
<version>2.4.5</version>

Per comprendere la sintassi di base di Groovy, diamo prima un'occhiata a un semplice programma Hello World.

Creazione del tuo primo programma Hello World

Creare il tuo primo programma hello world è semplice come inserire la seguente riga di codice:

class Example {
   static void main(String[] args) {
      // Using a simple println statement to print output to the console
      println('Hello World');
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World

Istruzione Import in Groovy

L'istruzione import può essere utilizzata per importare la funzionalità di altre librerie che possono essere utilizzate nel codice. Questo viene fatto usando ilimport parola chiave.

L'esempio seguente mostra come utilizzare una semplice importazione della classe MarkupBuilder che è probabilmente una delle classi più utilizzate per la creazione di markup HTML o XML.

import groovy.xml.MarkupBuilder 
def xml = new MarkupBuilder()

Per impostazione predefinita, Groovy include le seguenti librerie nel codice, quindi non è necessario importarle esplicitamente.

import java.lang.* 
import java.util.* 
import java.io.* 
import java.net.* 

import groovy.lang.* 
import groovy.util.* 

import java.math.BigInteger 
import java.math.BigDecimal

Gettoni in Groovy

Un token è una parola chiave, un identificatore, una costante, una stringa letterale o un simbolo.

println(“Hello World”);

Nella riga di codice sopra, ci sono due token, il primo è la parola chiave println e il successivo è la stringa letterale di "Hello World".

Commenti in Groovy

I commenti vengono utilizzati per documentare il codice. I commenti in Groovy possono essere su una riga o su più righe.

I commenti su una sola riga vengono identificati utilizzando // in qualsiasi posizione della riga. Di seguito è mostrato un esempio:

class Example {
   static void main(String[] args) {
      // Using a simple println statement to print output to the console
      println('Hello World');
   }
}

I commenti su più righe sono identificati con / * all'inizio e * / per identificare la fine del commento su più righe.

class Example {
   static void main(String[] args) {
      /* This program is the first program
      This program shows how to display hello world */
      println('Hello World');
   }
}

Punto e virgola

A differenza del linguaggio di programmazione Java, non è obbligatorio avere un punto e virgola dopo la fine di ogni istruzione, è opzionale.

class Example {
   static void main(String[] args) {
      def x = 5
      println('Hello World');  
   }
}

Se esegui il programma precedente, entrambe le istruzioni nel metodo principale non generano alcun errore.

Identificatori

Gli identificatori vengono utilizzati per definire variabili, funzioni o altre variabili definite dall'utente. Gli identificatori iniziano con una lettera, un dollaro o un trattino basso. Non possono iniziare con un numero. Di seguito sono riportati alcuni esempi di identificatori validi:

def employeename 
def student1 
def student_name

dove def è una parola chiave utilizzata in Groovy per definire un identificatore.

Ecco un esempio di codice di come un identificatore può essere utilizzato nel nostro programma Hello World.

class Example {
   static void main(String[] args) {
      // One can see the use of a semi-colon after each statement
      def x = 5;
      println('Hello World'); 
   }
}

Nell'esempio sopra, la variabile x viene utilizzato come identificatore.

Parole chiave

Le parole chiave come suggerisce il nome sono parole speciali riservate al linguaggio di programmazione Groovy. La tabella seguente elenca le parole chiave definite in Groovy.

come asserire rompere Astuccio
catturare classe const Continua
def predefinito fare altro
enum si estende falso Finalmente
per vai a Se attrezzi
importare in istanza di interfaccia
nuovo Tirare pacchetto ritorno
super interruttore Questo gettare
lanci tratto vero provare
mentre

Spazi bianchi

Whitespace è il termine utilizzato in un linguaggio di programmazione come Java e Groovy per descrivere spazi vuoti, tabulazioni, caratteri di nuova riga e commenti. Lo spazio vuoto separa una parte di un'istruzione da un'altra e consente al compilatore di identificare la posizione di un elemento in un'istruzione.

Ad esempio, nel seguente esempio di codice, c'è uno spazio vuoto tra la parola chiave defe la variabile x. Questo è così che il compilatore lo sadef è la parola chiave che deve essere utilizzata e che x dovrebbe essere il nome della variabile che deve essere definita.

def x = 5;

Letterali

Un letterale è una notazione per rappresentare un valore fisso in groovy. Il linguaggio groovy ha notazioni per interi, numeri in virgola mobile, caratteri e stringhe. Ecco alcuni esempi di letterali nel linguaggio di programmazione Groovy:

12 
1.45 
‘a’ 
“aa”

In qualsiasi linguaggio di programmazione, è necessario utilizzare varie variabili per memorizzare vari tipi di informazioni. Le variabili non sono altro che posizioni di memoria riservate per memorizzare i valori. Ciò significa che quando crei una variabile riservi dello spazio in memoria per memorizzare il valore associato alla variabile.

Potresti voler memorizzare informazioni di vari tipi di dati come stringa, carattere, carattere largo, intero, virgola mobile, booleano, ecc. In base al tipo di dati di una variabile, il sistema operativo alloca memoria e decide cosa può essere memorizzato nel riservato memoria.

Tipi di dati incorporati

Groovy offre un'ampia varietà di tipi di dati incorporati. Di seguito è riportato un elenco di tipi di dati definiti in Groovy:

  • byte- Viene utilizzato per rappresentare un valore di byte. Un esempio è 2.

  • short- Viene utilizzato per rappresentare un numero breve. Un esempio è 10.

  • int- Viene utilizzato per rappresentare numeri interi. Un esempio è 1234.

  • long- Viene utilizzato per rappresentare un numero lungo. Un esempio è 10000090.

  • float- Viene utilizzato per rappresentare i numeri in virgola mobile a 32 bit. Un esempio è 12.34.

  • double- Viene utilizzato per rappresentare numeri in virgola mobile a 64 bit che sono rappresentazioni di numeri decimali più lunghi che possono essere richiesti a volte. Un esempio è 12.3456565.

  • char- Questo definisce un singolo carattere letterale. Un esempio è "a".

  • Boolean - Questo rappresenta un valore booleano che può essere vero o falso.

  • String - Questi sono letterali di testo rappresentati in the formdi catena di personaggi. Ad esempio "Hello World".

Valori vincolati

La tabella seguente mostra i valori massimi consentiti per i valori letterali numerici e decimali.

byte Da -128 a 127
corto Da -32.768 a 32.767
int -2.147.483.648 a 2.147.483.647
lungo -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807
galleggiante Da 1,40129846432481707e-45 a 3,40282346638528860e + 38
Doppio 4.94065645841246544e-324d a 1.79769313486231570e + 308d

Numerico di classe

Tipi Oltre ai tipi primitivi, sono consentiti i seguenti tipi di oggetto (a volte indicati come tipi wrapper):

  • java.lang.Byte
  • java.lang.Short
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Float
  • java.lang.Double

Inoltre, le seguenti classi possono essere utilizzate per supportare l'aritmetica di precisione arbitraria:

Nome Descrizione Esempio
java.math.BigInteger Numeri interi con segno di precisione arbitraria immutabili 30g
java.math.BigDecimal Numeri decimali con segno di precisione arbitraria immutabili 3.5g

Il seguente esempio di codice mostra come possono essere usati i diversi tipi di dati incorporati:

class Example { 
   static void main(String[] args) { 
      //Example of a int datatype 
      int x = 5; 
		
      //Example of a long datatype 
      long y = 100L; 
		
      //Example of a floating point datatype 
      float a = 10.56f; 
		
      //Example of a double datatype 
      double b = 10.5e40; 
		
      //Example of a BigInteger datatype 
      BigInteger bi = 30g; 
		
      //Example of a BigDecimal datatype 
      BigDecimal bd = 3.5g; 
		
      println(x); 
      println(y); 
      println(a); 
      println(b); 
      println(bi); 
      println(bd); 
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

5 
100 
10.56 
1.05E41 
30 
3.5

Le variabili in Groovy possono essere definite in due modi: utilizzando il native syntax per il tipo di dati o il successivo è by using the def keyword. Per le definizioni di variabili è obbligatorio fornire un nome di tipo esplicitamente o utilizzare "def" in sostituzione. Ciò è richiesto dal parser Groovy.

Esistono i seguenti tipi di variabili di base in Groovy come spiegato nel capitolo precedente:

  • byte- Viene utilizzato per rappresentare un valore di byte. Un esempio è 2.

  • short- Viene utilizzato per rappresentare un numero breve. Un esempio è 10.

  • int- Viene utilizzato per rappresentare numeri interi. Un esempio è 1234.

  • long- Viene utilizzato per rappresentare un numero lungo. Un esempio è 10000090.

  • float- Viene utilizzato per rappresentare i numeri in virgola mobile a 32 bit. Un esempio è 12.34.

  • double- Viene utilizzato per rappresentare numeri in virgola mobile a 64 bit che sono rappresentazioni di numeri decimali più lunghi che possono essere richiesti a volte. Un esempio è 12.3456565.

  • char- Questo definisce un singolo carattere letterale. Un esempio è "a".

  • Boolean - Questo rappresenta un valore booleano che può essere vero o falso.

  • String - Questi sono letterali di testo rappresentati in the formdi catena di personaggi. Ad esempio "Hello World".

Groovy consente anche ulteriori tipi di variabili come array, strutture e classi che vedremo nei capitoli successivi.

Dichiarazioni di variabili

Una dichiarazione di variabile dice al compilatore dove e quanto creare la memoria per la variabile.

Di seguito è riportato un esempio di dichiarazione di variabile:

class Example { 
   static void main(String[] args) { 
      // x is defined as a variable 
      String x = "Hello";
		
      // The value of the variable is printed to the console 
      println(x);
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello

Denominazione delle variabili

Il nome di una variabile può essere composto da lettere, cifre e il carattere di sottolineatura. Deve iniziare con una lettera o un trattino basso. Le lettere maiuscole e minuscole sono distinte perché Groovy, proprio come Java, è un linguaggio di programmazione con distinzione tra maiuscole e minuscole.

class Example { 
   static void main(String[] args) { 
      // Defining a variable in lowercase  
      int x = 5;
	  
      // Defining a variable in uppercase  
      int X = 6; 
	  
      // Defining a variable with the underscore in it's name 
      def _Name = "Joe"; 
		
      println(x); 
      println(X); 
      println(_Name); 
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

5 
6 
Joe

Possiamo vederlo x e X sono due variabili diverse a causa della distinzione tra maiuscole e minuscole e nel terzo caso, possiamo vedere che _Name inizia con un trattino basso.

Variabili di stampa

È possibile stampare il valore corrente di una variabile con la funzione println. Il seguente esempio mostra come questo può essere ottenuto.

class Example { 
   static void main(String[] args) { 
      //Initializing 2 variables 
      int x = 5; 
      int X = 6; 
	  
      //Printing the value of the variables to the console 
      println("The value of x is " + x + "The value of X is " + X);  
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

The value of x is 5 The value of X is 6

Un operatore è un simbolo che dice al compilatore di eseguire specifiche manipolazioni matematiche o logiche.

Groovy ha i seguenti tipi di operatori:

  • Operatori aritmetici
  • Operatori relazionali
  • Operatori logici
  • Operatori bit per bit
  • Operatori di assegnazione

Operatori aritmetici

Il linguaggio Groovy supporta i normali operatori aritmetici come qualsiasi altro linguaggio. Di seguito sono riportati gli operatori aritmetici disponibili in Groovy:

Mostra esempio

Operatore Descrizione Esempio
+ Aggiunta di due operandi 1 + 2 darà 3
- Sottrae il secondo operando dal primo 2-1 darà 1
* Moltiplicazione di entrambi gli operandi 2 * 2 darà 4
/ Divisione del numeratore per denominatore 3/2 darà 1.5
% Operatore modulo e resto di dopo una divisione intero / float 3% 2 darà 1
++ Operatori incrementali utilizzati per incrementare il valore di un operando di 1

int x = 5;

x ++;

x darà 6

- Operatori incrementali utilizzati per decrementare il valore di un operando di 1

int x = 5;

X--;

x darà 4

Operatori relazionali

Gli operatori relazionali consentono il confronto di oggetti. Di seguito sono riportati gli operatori relazionali disponibili in Groovy:

Mostra esempio

Operatore Descrizione Esempio
== Verifica l'uguaglianza tra due oggetti 2 == 2 darà vero
! = Verifica la differenza tra due oggetti 3! = 2 darà vero
< Verifica se gli oggetti di sinistra sono minori dell'operando di destra. 2 <3 darà vero
<= Verifica se gli oggetti di sinistra sono minori o uguali all'operando di destra. 2 <= 3 darà vero
> Verifica se gli oggetti di sinistra sono maggiori dell'operando di destra. 3> 2 darà vero
> = Verifica se gli oggetti di sinistra sono maggiori o uguali all'operando di destra. 3> = 2 darà vero

Operatori logici

Gli operatori logici vengono utilizzati per valutare le espressioni booleane. Di seguito sono riportati gli operatori logici disponibili in Groovy:

Mostra esempio

Operatore Descrizione Esempio
&& Questo è l'operatore logico "and" true && true darà true
|| Questo è l'operatore logico "or" vero || vero darà vero
! Questo è l'operatore logico "non" ! false darà vero

Operatori bit per bit

Groovy fornisce quattro operatori bit per bit. Di seguito sono riportati gli operatori bit per bit disponibili in Groovy:

Mostra esempio

Suor n Operatore e descrizione
1

&

Questo è l'operatore "and" bit per bit

2

|

Questo è l'operatore "or" bit per bit

3

^

Questo è l'operatore "xor" o Exclusive or bit per bit

4

~

Questo è l'operatore di negazione bit per bit

Ecco la tabella della verità che mostra questi operatori.

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Operatori di assegnazione

Il linguaggio Groovy fornisce anche operatori di assegnazione. Di seguito sono riportati gli operatori di assegnazione disponibili in Groovy:

Mostra esempio

Operatore Descrizione Esempio
+ = Questo aggiunge l'operando destro all'operando sinistro e assegna il risultato all'operando sinistro.

def A = 5

A + = 3

L'uscita sarà 8

- = Questo sottrae l'operando destro dall'operando sinistro e assegna il risultato all'operando sinistro

def A = 5

A- = 3

L'output sarà 2

* = Questo moltiplica l'operando destro per l'operando sinistro e assegna il risultato all'operando sinistro

def A = 5

A * = 3

L'uscita sarà 15

/ = Questo divide l'operando sinistro con l'operando destro e assegna il risultato all'operando sinistro

def A = 6

A / = 3

L'output sarà 2

% = Questo richiede il modulo utilizzando due operandi e assegna il risultato all'operando sinistro

def A = 5

A% = 3

L'output sarà 2

Operatori di intervallo

Groovy supporta il concetto di intervalli e fornisce una notazione degli operatori di intervallo con l'aiuto della notazione ... Di seguito viene fornito un semplice esempio dell'operatore di intervallo.

def range = 0..5

Questo definisce solo un semplice intervallo di numeri interi, memorizzato in una variabile locale chiamata intervallo con un limite inferiore di 0 e un limite superiore di 5.

Il seguente frammento di codice mostra come possono essere utilizzati i vari operatori.

class Example { 
   static void main(String[] args) { 
      def range = 5..10; 
      println(range); 
      println(range.get(2)); 
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Dal println si può vedere che viene visualizzato l'intero intervallo di numeri definiti nell'istruzione range.

L'istruzione get viene utilizzata per ottenere un oggetto dall'intervallo definito che accetta un valore di indice come parametro.

[5, 6, 7, 8, 9, 10] 
7

Precedenza operatore

La tabella seguente elenca tutti gli operatori groovy in ordine di precedenza.

Suor n Operatori e nomi
1

++ -- + -

pre incremento / decremento, più unario, meno unario

2

* / %

moltiplicare, div, modulo

3

+ -

addizione, sottrazione

4

== != <=>

è uguale, non è uguale, confronta con

5

&

binario / bit per bit e

6

^

xor binario / bit per bit

7

|

binario / bit per bit o

8

&&

logico e

9

||

logico o

10

= **= *= /= %= += -= <<= >>= >>>= &= ^= |=

Vari operatori di assegnazione

Finora abbiamo visto istruzioni che sono state eseguite una dopo l'altra in modo sequenziale. Inoltre, in Groovy vengono fornite istruzioni per alterare il flusso di controllo nella logica di un programma. Vengono quindi classificati in dichiarazioni di flusso di controllo che vedremo in dettaglio.

S.No. Dichiarazioni e descrizione
1 Dichiarazione While

L'istruzione while viene eseguita valutando prima l'espressione della condizione (un valore booleano) e, se il risultato è vero, vengono eseguite le istruzioni nel ciclo while.

2 per Statement

L'istruzione for viene utilizzata per iterare attraverso un insieme di valori.

3 Istruzione for-in

L'istruzione for-in viene utilizzata per iterare attraverso un insieme di valori.

Dichiarazioni di controllo del loop

S.No. Dichiarazioni e descrizione
1 Istruzione Break

L'istruzione break viene utilizzata per alterare il flusso di controllo all'interno di cicli e istruzioni switch.

2 Continua dichiarazione

L'istruzione continue completa l'istruzione break. Il suo utilizzo è limitato ai cicli while e for.

Le strutture decisionali richiedono che il programmatore specifichi una o più condizioni che devono essere valutate o testate dal programma, insieme a una o più istruzioni da eseguire se la condizione è determinata truee, facoltativamente, altre istruzioni da eseguire se si determina che la condizione è false.

Sr.No. Dichiarazioni e descrizione
1 if Statement

Il funzionamento generale di questa istruzione è che prima una condizione viene valutata nell'istruzione if. Se la condizione è vera, esegue le istruzioni.

2 If / else Statement

Il funzionamento generale di questa istruzione è che prima una condizione viene valutata nell'istruzione if. Se la condizione è vera, esegue le istruzioni successive e si ferma prima della condizione else ed esce dal ciclo. Se la condizione è falsa, esegue le istruzioni nel blocco di istruzioni else e quindi esce dal ciclo.

3 Istruzione If annidata

A volte è necessario disporre di più istruzioni if ​​incorporate l'una nell'altra.

4 Istruzione Switch

A volte l'istruzione if-else annidata è così comune ed è usata così spesso che è stata progettata un'istruzione più semplice chiamata istruzione switch.

5 Istruzione Switch annidata

È anche possibile avere un insieme annidato di istruzioni switch.

Un metodo in Groovy è definito con un tipo restituito o con defparola chiave. I metodi possono ricevere un numero qualsiasi di argomenti. Non è necessario che i tipi siano definiti esplicitamente durante la definizione degli argomenti. È possibile aggiungere modificatori come public, private e protected. Per impostazione predefinita, se non viene fornito alcun modificatore di visibilità, il metodo è pubblico.

Il tipo più semplice di un metodo è quello senza parametri come quello mostrato di seguito -

def methodName() { 
   //Method code 
}

Di seguito è riportato un esempio di metodo semplice

class Example {
   static def DisplayName() {
      println("This is how methods work in groovy");
      println("This is an example of a simple method");
   } 
	
   static void main(String[] args) {
      DisplayName();
   } 
}

Nell'esempio precedente, DisplayName è un metodo semplice che consiste in due istruzioni println che vengono utilizzate per inviare del testo alla console. Nel nostro metodo principale statico, stiamo solo chiamando il metodo DisplayName. L'output del metodo sopra sarebbe:

This is how methods work in groovy 
This is an example of a simple method

Parametri del metodo

Un metodo è più generalmente utile se il suo comportamento è determinato dal valore di uno o più parametri. Possiamo trasferire valori al metodo chiamato utilizzando i parametri del metodo. Notare che i nomi dei parametri devono differire l'uno dall'altro.

Il tipo più semplice di un metodo con parametri come quello mostrato di seguito -

def methodName(parameter1, parameter2, parameter3) { 
   // Method code goes here 
}

Di seguito è riportato un esempio di metodo semplice con parametri

class Example {
   static void sum(int a,int b) {
      int c = a+b;
      println(c);
   }  
	
   static void main(String[] args) {
      sum(10,5);
   } 
}

In questo esempio, stiamo creando un metodo di somma con 2 parametri, a e b. Entrambi i parametri sono di tipoint. Chiamiamo quindi il metodo sum dal nostro metodo principale e passiamo i valori alle variabilia e b.

L'output del metodo sopra sarebbe il valore 15.

Parametri predefiniti

C'è anche una disposizione in Groovy per specificare i valori predefiniti per i parametri all'interno dei metodi. Se non vengono passati valori al metodo per i parametri, vengono utilizzati quelli di default. Se vengono utilizzati sia parametri non predefiniti che parametri predefiniti, è necessario notare che i parametri predefiniti devono essere definiti alla fine dell'elenco dei parametri.

Di seguito è riportato un esempio di metodo semplice con parametri:

def someMethod(parameter1, parameter2 = 0, parameter3 = 0) { 
   // Method code goes here 
}

Diamo un'occhiata allo stesso esempio che abbiamo visto prima per l'aggiunta di due numeri e creiamo un metodo che ha un parametro predefinito e un altro non predefinito -

class Example { 
   static void sum(int a,int b = 5) { 
      int c = a+b; 
      println(c); 
   } 
	
   static void main(String[] args) {
      sum(6); 
   } 
}

In questo esempio, stiamo creando un metodo di somma con due parametri, a e b. Entrambi i parametri sono di tipo int. La differenza tra questo esempio e l'esempio precedente è che in questo caso stiamo specificando un valore predefinito perb come 5. Quindi quando chiamiamo il metodo sum dal nostro metodo principale, abbiamo la possibilità di passare solo un valore cheè6 e questo verrà assegnato al parametro a all'interno del sum metodo.

L'output del metodo sopra sarebbe il valore 11.

class Example {
   static void sum(int a,int b = 5) {
      int c = a+b;
      println(c);
   } 
	
   static void main(String[] args) {
      sum(6,6);
   } 
}

Possiamo anche chiamare il metodo sum passando 2 valori, nel nostro esempio sopra stiamo passando 2 valori di 6. Il secondo valore di 6 sostituirà effettivamente il valore predefinito assegnato al parametro b.

L'output del metodo sopra sarebbe il valore 12.

Valori restituiti dal metodo

I metodi possono anche restituire valori al programma chiamante. Ciò è richiesto nel linguaggio di programmazione moderno in cui un metodo esegue una sorta di calcolo e quindi restituisce il valore desiderato al metodo chiamante.

Di seguito è riportato un esempio di metodo semplice con un valore di ritorno.

class Example {
   static int sum(int a,int b = 5) {
      int c = a+b;
      return c;
   } 
	
   static void main(String[] args) {
      println(sum(6));
   } 
}

Nel nostro esempio sopra, nota che questa volta stiamo specificando un tipo di ritorno per il nostro metodo sum che è del tipo int. Nel metodo stiamo usando l'istruzione return per inviare il valore della somma al programma principale chiamante. Poiché il valore del metodo è ora disponibile per il metodo principale, stiamo usando ilprintln funzione per visualizzare il valore nella console.

L'output del metodo sopra sarebbe il valore 11.

Metodi di istanza

I metodi sono normalmente implementati all'interno di classi all'interno di Groovy proprio come il linguaggio Java. Una classe non è altro che un progetto o un modello per la creazione di diversi oggetti che ne definisce le proprietà e i comportamenti. Gli oggetti della classe mostrano le proprietà e i comportamenti definiti dalla sua classe. Quindi i comportamenti vengono definiti creando metodi all'interno della classe.

Vedremo le classi in modo più dettagliato in un capitolo successivo, ma di seguito è riportato un esempio di implementazione di un metodo in una classe. Nei nostri esempi precedenti abbiamo definito il nostro metodo come metodi statici, il che significava che potevamo accedere a quei metodi direttamente dalla classe. Il prossimo esempio di metodi sono i metodi di istanza in cui si accede ai metodi creando oggetti della classe. Di nuovo vedremo le classi in un capitolo successivo, per ora mostreremo come utilizzare i metodi.

Di seguito è riportato un esempio di come i metodi possono essere implementati.

class Example { 
   int x; 
	
   public int getX() { 
      return x; 
   } 
	
   public void setX(int pX) { 
      x = pX; 
   } 
	
   static void main(String[] args) { 
      Example ex = new Example(); 
      ex.setX(100); 
      println(ex.getX()); 
   } 
}

Nel nostro esempio precedente, nota che questa volta non stiamo specificando alcun attributo statico per i nostri metodi di classe. Nella nostra funzione principale stiamo effettivamente creando un'istanza della classe Example e quindi invocando il metodo dell'oggetto "ex".

L'output del metodo sopra sarebbe il valore 100.

Nomi dei parametri locali ed esterni

Groovy fornisce la struttura, proprio come java, per avere parametri locali e globali. Nell'esempio seguente,lx è un parametro locale che ha un ambito solo all'interno della funzione di getX() e xè una proprietà globale a cui è possibile accedere all'interno dell'intera classe Example. Se proviamo ad accedere alla variabilelx al di fuori del getX() funzione, avremo un errore.

class Example { 
   static int x = 100; 
	
   public static int getX() { 
      int lx = 200; 
      println(lx); 
      return x; 
   } 
	
   static void main(String[] args) { 
      println(getX()); 
   }  
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato.

200 
100

questo metodo per le proprietà

Proprio come in Java, groovy può accedere ai membri dell'istanza utilizzando l'estensione thisparola chiave. L'esempio seguente mostra come quando usiamo l'istruzionethis.x, fa riferimento alla sua istanza e imposta il valore di x di conseguenza.

class Example { 
   int x = 100; 
	
   public int getX() { 
      this.x = 200; 
      return x; 
   } 
	
   static void main(String[] args) {
      Example ex = new Example(); 
      println(ex.getX());
   }
}

Quando eseguiamo il programma precedente, otterremo il risultato di 200 stampato sulla console.

Groovy fornisce una serie di metodi di supporto quando si lavora con I / O. Groovy fornisce classi più semplici per fornire le seguenti funzionalità per i file.

  • Lettura di file
  • Scrittura su file
  • Attraversamento di alberi di file
  • Lettura e scrittura di oggetti dati su file

Oltre a ciò, è sempre possibile utilizzare le normali classi Java elencate di seguito per le operazioni di I / O di file.

  • java.io.File
  • java.io.InputStream
  • java.io.OutputStream
  • java.io.Reader
  • java.io.Writer

Lettura di file

Il seguente esempio produrrà tutte le righe di un file di testo in Groovy. Il metodoeachLine è integrato nella classe File in Groovy allo scopo di garantire che ogni riga del file di testo venga letta.

import java.io.File 
class Example { 
   static void main(String[] args) { 
      new File("E:/Example.txt").eachLine {  
         line -> println "line : $line"; 
      } 
   } 
}

La classe File viene utilizzata per creare un'istanza di un nuovo oggetto che prende il nome del file come parametro. Quindi prende la funzione di eachLine, la inserisce in una variabile chiamata line e la stampa di conseguenza.

Se il file contiene le seguenti righe, verranno stampate.

line : Example1
line : Example2

Lettura del contenuto di un file come un'intera stringa

Se vuoi ottenere l'intero contenuto del file come una stringa, puoi usare la proprietà text della classe file. Il seguente esempio mostra come farlo.

class Example { 
   static void main(String[] args) { 
      File file = new File("E:/Example.txt") 
      println file.text 
   } 
}

Se il file contiene le seguenti righe, verranno stampate.

line : Example1 
line : Example2

Scrittura su file

Se vuoi scrivere su file, devi usare la classe writer per emettere testo in un file. Il seguente esempio mostra come farlo.

import java.io.File 
class Example { 
   static void main(String[] args) { 
      new File('E:/','Example.txt').withWriter('utf-8') { 
         writer -> writer.writeLine 'Hello World' 
      }  
   } 
}

Se apri il file Example.txt, vedrai le parole "Hello World" stampate sul file.

Ottenere le dimensioni di un file

Se vuoi ottenere la dimensione del file, puoi usare la proprietà length della classe file per ottenere la dimensione del file. Il seguente esempio mostra come farlo.

class Example {
   static void main(String[] args) {
      File file = new File("E:/Example.txt")
      println "The file ${file.absolutePath} has ${file.length()} bytes"
   } 
}

Il codice sopra mostrerebbe la dimensione del file in byte.

Verifica se un file è una directory

Se vuoi vedere se un percorso è un file o una directory, puoi usare il isFile e isDirectoryopzione della classe File. Il seguente esempio mostra come farlo.

class Example { 
   static void main(String[] args) { 
      def file = new File('E:/') 
      println "File? ${file.isFile()}" 
      println "Directory? ${file.isDirectory()}" 
   } 
}

Il codice sopra mostrerebbe il seguente output:

File? false 
Directory? True

Creazione di una directory

Se vuoi creare una nuova directory puoi usare il file mkdirfunzione della classe File. Il seguente esempio mostra come farlo.

class Example {
   static void main(String[] args) {
      def file = new File('E:/Directory')
      file.mkdir()
   } 
}

La directory E: \ Directory verrà creata se non esiste.

Eliminazione di un file

Se vuoi cancellare un file puoi usare la funzione cancella della classe File. Il seguente esempio mostra come farlo.

class Example {
   static void main(String[] args) {
      def file = new File('E:/Example.txt')
      file.delete()
   } 
}

Il file verrà eliminato se esiste.

Copia di file

Groovy fornisce anche la funzionalità per copiare il contenuto da un file a un altro. Il seguente esempio mostra come farlo.

class Example {
   static void main(String[] args) {
      def src = new File("E:/Example.txt")
      def dst = new File("E:/Example1.txt")
      dst << src.text
   } 
}

Il file Example1.txt verrà creato e tutto il contenuto del file Example.txt verrà copiato in questo file.

Recupero del contenuto della directory

Groovy fornisce anche la funzionalità per elencare le unità ei file in un'unità.

L'esempio seguente mostra come visualizzare le unità su una macchina utilizzando l'estensione listRoots funzione della classe File.

class Example { 
   static void main(String[] args) { 
      def rootFiles = new File("test").listRoots() 
      rootFiles.each { 
         file -> println file.absolutePath 
      }
   }
}

A seconda delle unità disponibili sulla macchina, l'output potrebbe variare. Su una macchina standard l'output sarebbe simile al seguente:

C:\ 
D:\

L'esempio seguente mostra come elencare i file in una determinata directory utilizzando l'estensione eachFile funzione della classe File.

class Example {
   static void main(String[] args) {
      new File("E:/Temp").eachFile() {  
         file->println file.getAbsolutePath()
      }
   } 
}

L'output visualizzerà tutti i file nella directory E: \ Temp

Se vuoi visualizzare in modo ricorsivo tutti i file in una directory e nelle sue sottodirectory, dovresti usare il eachFileRecursefunzione della classe File. Il seguente esempio mostra come farlo.

class Example { 
   static void main(String[] args) {
      new File("E:/temp").eachFileRecurse() {
         file -> println file.getAbsolutePath()
      }
   }
}

L'output visualizzerà tutti i file nella directory E: \ Temp e nelle sue sottodirectory, se esistono.

Groovy è un linguaggio digitato "opzionalmente" e questa distinzione è importante quando si comprendono i fondamenti del linguaggio. Rispetto a Java, che è un linguaggio tipizzato "fortemente", per cui il compilatore conosce tutti i tipi per ogni variabile e può comprendere e rispettare i contratti in fase di compilazione. Ciò significa che le chiamate ai metodi possono essere determinate in fase di compilazione.

Quando si scrive codice in Groovy, gli sviluppatori hanno la flessibilità di fornire un tipo o meno. Questo può offrire una certa semplicità nell'implementazione e, se sfruttato correttamente, può servire la tua applicazione in modo robusto e dinamico.

In Groovy, la digitazione opzionale viene eseguita tramite la parola chiave "def". Di seguito è riportato un esempio di utilizzo didef metodo -

class Example { 
   static void main(String[] args) { 
      // Example of an Integer using def 
      def a = 100; 
      println(a); 
		
      // Example of an float using def 
      def b = 100.10; 
      println(b); 
		
      // Example of an Double using def 
      def c = 100.101; 
      println(c);
		
      // Example of an String using def 
      def d = "HelloWorld"; 
      println(d); 
   } 
}

Dal programma sopra, possiamo vedere che non abbiamo dichiarato le singole variabili come Integer, float, double o string anche se contengono questi tipi di valori.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

100 
100.10 
100.101
HelloWorld

La digitazione opzionale può essere un'utilità potente durante lo sviluppo, ma può portare a problemi di manutenibilità durante le fasi successive dello sviluppo quando il codice diventa troppo vasto e complesso.

Per capire come utilizzare la digitazione opzionale in Groovy senza creare un pasticcio irrefrenabile con la base di codice, è meglio abbracciare la filosofia della "digitazione a papera" nelle applicazioni.

Se riscriviamo il codice precedente usando la digitazione a papera, sarebbe simile a quello indicato di seguito. Ai nomi delle variabili vengono assegnati nomi che il più delle volte assomigliano al tipo che rappresentano, il che rende il codice più comprensibile.

class Example { 
   static void main(String[] args) { 
      // Example of an Integer using def 
      def aint = 100; 
      println(aint); 
		
      // Example of an float using def 
      def bfloat = 100.10; 
      println(bfloat); 
		
      // Example of an Double using def 
      def cDouble = 100.101; 
      println(cDouble);
		
      // Example of an String using def 
      def dString = "HelloWorld"; 
      println(dString); 
   } 
}

In Groovy, i numeri sono effettivamente rappresentati come oggetti, essendo tutti un'istanza della classe Integer. Per fare in modo che un oggetto faccia qualcosa, dobbiamo invocare uno dei metodi dichiarati nella sua classe.

Groovy supporta numeri interi e in virgola mobile.

  • Un numero intero è un valore che non include una frazione.
  • Un numero a virgola mobile è un valore decimale che include una frazione decimale.

Di seguito è mostrato un esempio di numeri in Groovy:

Integer x = 5; 
Float y = 1.25;

Dove x è del tipo Integer e y è il galleggiante.

Il motivo per cui i numeri in groovy sono definiti come oggetti è generalmente perché ci sono requisiti per eseguire operazioni sui numeri. Il concetto di fornire una classe sui tipi primitivi è noto come classi wrapper.

Per impostazione predefinita, le seguenti classi wrapper sono fornite in Groovy.

L'oggetto della classe wrapper contiene o racchiude il rispettivo tipo di dati primitivo. Il processo di conversione di un tipo di dati primitivo in oggetto è chiamato boxing, e questo è curato dal compilatore. Il processo di riconversione dell'oggetto nel suo tipo primitivo corrispondente è chiamato unboxing.

Esempio

Di seguito è riportato un esempio di boxe e unboxing:

class Example { 
   static void main(String[] args) {
      Integer x = 5,y = 10,z = 0; 
		
      // The the values of 5,10 and 0 are boxed into Integer types 
      // The values of x and y are unboxed and the addition is performed 
      z = x+y; 
      println(z);
   }
}

L'output del programma precedente sarebbe 15. Nell'esempio sopra, i valori di 5, 10 e 0 vengono prima inseriti nelle variabili Integer x, yez di conseguenza. E poi quando viene eseguita l'aggiunta di x e y, i valori vengono unboxed dai loro tipi Integer.

Metodi numerici

Poiché i numeri in Groovy sono rappresentati come classi, di seguito è riportato l'elenco dei metodi disponibili.

S.No. Metodi e descrizione
1 xxxValue ()

Questo metodo assume il numero come parametro e restituisce un tipo primitivo basato sul metodo richiamato.

2 confrontare con()

Il metodo compareTo consiste nell'usare il confronto tra un numero e un altro. Questo è utile se vuoi confrontare il valore dei numeri.

3 equivale()

Il metodo determina se l'oggetto Number che richiama il metodo è uguale all'oggetto passato come argomento.

4 valore di()

Il metodo valueOf restituisce il relativo oggetto numero contenente il valore dell'argomento passato.

5 accordare()

Il metodo viene utilizzato per ottenere un oggetto String che rappresenta il valore dell'oggetto Number.

6 parseInt ()

Questo metodo viene utilizzato per ottenere il tipo di dati primitivo di una determinata stringa. parseXxx () è un metodo statico e può avere uno o due argomenti.

7 addominali()

Il metodo fornisce il valore assoluto dell'argomento. L'argomento può essere int, float, long, double, short, byte.

8 ceil ()

Il metodo ceil fornisce il numero intero più piccolo maggiore o uguale all'argomento.

9 pavimento()

Il floor del metodo fornisce il numero intero più grande minore o uguale all'argomento.

10 rint ()

Il metodo rint restituisce l'intero che è il valore più vicino all'argomento.

11 il giro()

Il metodo round restituisce il long o int più vicino, come indicato dal tipo restituito dai metodi.

12 min ()

Il metodo fornisce il più piccolo dei due argomenti. L'argomento può essere int, float, long, double.

13 max ()

Il metodo fornisce il massimo dei due argomenti. L'argomento può essere int, float, long, double.

14 exp ()

Il metodo restituisce la base dei logaritmi naturali, e, alla potenza dell'argomento.

15 log ()

Il metodo restituisce il logaritmo naturale dell'argomento.

16 pow ()

Il metodo restituisce il valore del primo argomento elevato alla potenza del secondo argomento.

17 sqrt ()

Il metodo restituisce la radice quadrata dell'argomento.

18 peccato()

Il metodo restituisce il seno del valore double specificato.

19 cos ()

Il metodo restituisce il coseno del valore double specificato.

20 tan ()

Il metodo restituisce la tangente del valore double specificato.

21 come in()

Il metodo restituisce l'arcoseno del valore double specificato.

22 acos ()

Il metodo restituisce l'arcoseno del valore double specificato.

23 un'abbronzatura()

Il metodo restituisce l'arcotangente del valore double specificato.

24 atan2 ()

Il metodo Converte le coordinate rettangolari (x, y) in coordinate polari (r, theta) e restituisce theta.

25 toDegrees ()

Il metodo converte il valore dell'argomento in gradi.

26 radiante()

Il metodo converte il valore dell'argomento in radianti.

27 casuale()

Il metodo viene utilizzato per generare un numero casuale compreso tra 0,0 e 1,0. L'intervallo è: 0,0 = <Math.random <1.0. È possibile ottenere intervalli diversi utilizzando l'aritmetica.

Un valore letterale String viene costruito in Groovy racchiudendo il testo della stringa tra virgolette.

Groovy offre una varietà di modi per denotare un letterale String. Le stringhe in Groovy possono essere racchiuse tra virgolette singole ('), virgolette doppie (") o virgolette triple (" ""). Inoltre, una stringa Groovy racchiusa tra virgolette triple può estendersi su più righe.

Di seguito è riportato un esempio di utilizzo delle stringhe in Groovy:

class Example { 
   static void main(String[] args) { 
      String a = 'Hello Single'; 
      String b = "Hello Double"; 
      String c = "'Hello Triple" + "Multiple lines'";
		
      println(a); 
      println(b); 
      println(c); 
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello Single 
Hello Double 
'Hello TripleMultiple lines'

Indicizzazione delle stringhe

Le stringhe in Groovy sono sequenze ordinate di caratteri. È possibile accedere al singolo carattere di una stringa dalla sua posizione. Questo è dato da una posizione di indice.

Gli indici di stringa iniziano da zero e finiscono da uno in meno rispetto alla lunghezza della stringa. Groovy consente anche il conteggio a ritroso degli indici negativi dalla fine della stringa.

Di seguito è riportato un esempio dell'utilizzo dell'indicizzazione delle stringhe in Groovy:

class Example { 
   static void main(String[] args) { 
      String sample = "Hello world"; 
      println(sample[4]); // Print the 5 character in the string
		
      //Print the 1st character in the string starting from the back 
      println(sample[-1]); 
      println(sample[1..2]);//Prints a string starting from Index 1 to 2 
      println(sample[4..2]);//Prints a string starting from Index 4 back to 2 
      
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

o 
d 
el 
oll

Operazioni di base sulle stringhe

Per prima cosa impariamo le operazioni di base sulle corde in groovy. Sono riportati di seguito.

S.No. Operazione e descrizione delle stringhe
1 Concatenazione di due stringhe

La concatenazione di stringhe può essere eseguita dal semplice operatore "+".

2 Ripetizione di stringhe

La ripetizione di stringhe può essere eseguita dal semplice operatore "*".

3 Lunghezza della stringa

La lunghezza della stringa determinata dal metodo length () della stringa.

Metodi di stringa

Ecco l'elenco dei metodi supportati dalla classe String.

S.No. Metodi e descrizione
1 centro()

Restituisce una nuova stringa di lunghezza numberOfChars composta dal destinatario riempito a sinistra ea destra con spazi.

2 compareToIgnoreCase ()

Confronta due stringhe lessicograficamente, ignorando le differenze tra maiuscole e minuscole.

3 concat ()

Concatena la stringa specificata alla fine di questa stringa.

4 eachMatch ()

Elabora ogni sottostringa corrispondente della stringa data (vedere la sezione successiva).

5 finisce con()

Verifica se questa stringa termina con il suffisso specificato.

6 equalsIgnoreCase ()

Confronta questa stringa con un'altra stringa, ignorando le considerazioni sul caso.

7 arrivare a()

Restituisce il valore della stringa nella posizione dell'indice

8 indice di()

Restituisce l'indice all'interno di questa stringa della prima occorrenza della sottostringa specificata.

9 fiammiferi ()

Restituisce se una stringa corrisponde all'espressione regolare data.

10 meno()

Rimuove la parte del valore della stringa.

11 Il prossimo()

Questo metodo viene chiamato dall'operatore ++ per la classe String. Incrementa l'ultimo carattere nella stringa data.

12 padLeft ()

Riempi la stringa con gli spazi aggiunti a sinistra.

13 padRight ()

Riempi la stringa con gli spazi aggiunti a destra.

14 più()

Aggiunge una stringa

15 precedente()

Questo metodo viene chiamato dall'operatore - per CharSequence.

16 sostituisci tutto()

Sostituisce tutte le occorrenze di un gruppo acquisito con il risultato di una chiusura su quel testo.

17 inversione()

Crea una nuova stringa che è il contrario di questa stringa.

18 Diviso()

Divide questa stringa attorno alle corrispondenze dell'espressione regolare data.

19 subString ()

Restituisce una nuova stringa che è una sottostringa di questa stringa.

20 toUpperCase ()

Converte tutti i caratteri in questa stringa in maiuscolo.

21 toLowerCase ()

Converte tutti i caratteri in questa stringa in minuscolo.

Un intervallo è una scorciatoia per specificare una sequenza di valori. Un intervallo è indicato dal primo e dall'ultimo valore nella sequenza e l'intervallo può essere inclusivo o esclusivo. Un intervallo inclusivo include tutti i valori dal primo all'ultimo, mentre un intervallo esclusivo include tutti i valori tranne l'ultimo. Ecco alcuni esempi di valori letterali di intervallo:

  • 1..10 - Un esempio di un intervallo inclusivo
  • 1 .. <10 - Un esempio di Gamma esclusiva
  • 'a' .. 'x' - Gli intervalli possono anche essere costituiti da caratteri
  • 10..1 - Gli intervalli possono anche essere in ordine decrescente
  • 'x' .. 'a' - Gli intervalli possono anche essere costituiti da caratteri ed essere in ordine decrescente.

Di seguito sono riportati i vari metodi disponibili per gli intervalli.

Sr.No. Metodi e descrizione
1 contiene ()

Verifica se un intervallo contiene un valore specifico

2 ottenere()

Restituisce l'elemento nella posizione specificata in questo intervallo.

3 ottenere da()

Ottieni il valore più basso di questo intervallo.

4 raggiungere()

Ottieni il valore superiore di questo intervallo.

5 isReverse ()

È questo un intervallo invertito, iterando all'indietro

6 taglia()

Restituisce il numero di elementi in questo intervallo.

7 subList ()

Restituisce una visualizzazione della parte di questo intervallo compresa tra l'oggetto fromIndex, incluso e toIndex, esclusivo specificato

L'elenco è una struttura utilizzata per memorizzare una raccolta di elementi di dati. In Groovy, l'elenco contiene una sequenza di riferimenti a oggetti. I riferimenti agli oggetti in una lista occupano una posizione nella sequenza e sono contraddistinti da un indice intero. Un valore letterale List viene presentato come una serie di oggetti separati da virgole e racchiusi tra parentesi quadre.

Per elaborare i dati in un elenco, dobbiamo essere in grado di accedere ai singoli elementi. Gli elenchi Groovy vengono indicizzati utilizzando l'operatore di indicizzazione []. Gli indici di elenco iniziano da zero, che si riferisce al primo elemento.

Di seguito sono riportati alcuni esempi di elenchi:

  • [11, 12, 13, 14] - Un elenco di valori interi
  • ["Angular", "Groovy", "Java"] - Un elenco di stringhe
  • [1, 2, [3, 4], 5] - Un elenco nidificato
  • ['Groovy', 21, 2.11] - Un elenco eterogeneo di riferimenti a oggetti
  • [] - Un elenco vuoto

In questo capitolo discuteremo i metodi di elenco disponibili in Groovy.

Sr.No. Metodi e descrizione
1 Inserisci()

Aggiungi il nuovo valore alla fine di questo elenco.

2 contiene ()

Restituisce vero se questo elenco contiene il valore specificato.

3 ottenere()

Restituisce l'elemento nella posizione specificata in questo elenco.

4 è vuoto()

Restituisce vero se questo elenco non contiene elementi

5 meno()

Crea un nuovo List composto dagli elementi dell'originale senza quelli specificati nella raccolta.

6 più()

Crea un nuovo List composto dagli elementi dell'originale insieme a quelli specificati nella raccolta.

7 pop()

Rimuove l'ultimo elemento da questo elenco

8 rimuovere()

Rimuove l'elemento nella posizione specificata in questo elenco.

9 inversione()

Crea una nuova lista che è il contrario degli elementi della lista originale

10 taglia()

Ottiene il numero di elementi in questo elenco.

11 ordinare()

Restituisce una copia ordinata dell'elenco originale.

Una mappa (nota anche come array associativo, dizionario, tabella e hash) è una raccolta non ordinata di riferimenti a oggetti. Gli elementi in una raccolta di mappe sono accessibili tramite un valore chiave. Le chiavi utilizzate in una mappa possono essere di qualsiasi classe. Quando inseriamo in una raccolta di mappe, sono richiesti due valori: la chiave e il valore.

Di seguito sono riportati alcuni esempi di mappe:

  • ["TopicName": "Lists", "TopicName": "Maps"] - Raccolte di coppie di valori-chiave che hanno TopicName come chiave e i rispettivi valori.

  • [:] - Una mappa vuota.

In questo capitolo discuteremo i metodi di mappatura disponibili in Groovy.

Sr.No. Metodi e descrizione
1 contieneKey ()

Questa mappa contiene questa chiave?

2 ottenere()

Cerca la chiave in questa mappa e restituisci il valore corrispondente. Se in questa mappa non è presente alcuna voce per la chiave, restituire null.

3 mazzo di chiavi()

Ottieni un set di chiavi in ​​questa mappa.

4 mettere()

Associa il valore specificato alla chiave specificata in questa mappa. Se questa mappa conteneva in precedenza una mappatura per questa chiave, il vecchio valore viene sostituito dal valore specificato.

5 taglia()

Restituisce il numero di mappature valore-chiave in questa mappa.

6 valori()

Restituisce una vista della raccolta dei valori contenuti in questa mappa.

La classe Date rappresenta un istante di tempo specifico, con precisione al millisecondo. La classe Date ha due costruttori come mostrato di seguito.

Data()

Sintassi

public Date()

Parameters - Nessuno.

Return Value

Alloca un oggetto Date e lo inizializza in modo che rappresenti l'ora in cui è stato allocato, misurato al millisecondo più vicino.

Esempio

Di seguito è riportato un esempio di utilizzo di questo metodo:

class Example { 
   static void main(String[] args) { 
      Date date = new Date(); 
      
      // display time and date using toString() 
      System.out.println(date.toString()); 
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato. Il seguente output ti darà la data e l'ora correnti:

Thu Dec 10 21:31:15 GST 2015

Data (lungo millisec)

Sintassi

public Date(long millisec)

Parameters

Millisecondi: il numero di millisecondi da specificare dall'ora di base standard.

Return Value - Assegna a Date oggetto e lo inizializza per rappresentare il numero specificato di millisecondi dall'ora di base standard nota come "l'epoca", ovvero 1 gennaio 1970, 00:00:00 GMT.

Esempio

Di seguito è riportato un esempio di utilizzo di questo metodo:

class Example {
   static void main(String[] args) {
      Date date = new Date(100);
      
      // display time and date using toString()
      System.out.println(date.toString());
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Thu Jan 01 04:00:00 GST 1970

Di seguito sono riportati i metodi forniti della classe Date. In tutti i metodi della classe Date che accettano o restituiscono valori di anno, mese, data, ore, minuti e secondi, vengono utilizzate le seguenti rappresentazioni:

  • Un anno y è rappresentato dall'intero y - 1900.

  • Un mese è rappresentato da un numero intero compreso tra 0 e 11; 0 è gennaio, 1 è febbraio e così via; quindi l'11 è dicembre.

  • Una data (giorno del mese) è rappresentata da un numero intero compreso tra 1 e 31 nel modo consueto.

  • Un'ora è rappresentata da un numero intero compreso tra 0 e 23. Pertanto, l'ora da mezzanotte all'1 del mattino è l'ora 0 e l'ora da mezzogiorno all'1 del pomeriggio è l'ora 12.

  • Un minuto è rappresentato da un numero intero compreso tra 0 e 59 nel modo consueto.

  • Un secondo è rappresentato da un numero intero compreso tra 0 e 61.

Sr.No. Metodi e descrizione
1 dopo()

Verifica se questa data è successiva alla data specificata.

2 equivale()

Confronta due date per l'uguaglianza. Il risultato è vero se e solo se l'argomento non è null ed è un oggetto Date che rappresenta lo stesso punto nel tempo, al millisecondo, di questo oggetto.

3 confrontare con()

Confronta due date per l'ordinazione.

4 accordare()

Converte questo oggetto Date in una stringa

5 prima()

Verifica se questa data è precedente alla data specificata.

6 prendi tempo()

Restituisce il numero di millisecondi dall'1 gennaio 1970, 00:00:00 GMT rappresentato da questo oggetto Date.

7 tempo impostato()

Imposta questo oggetto Date per rappresentare un punto nel tempo che è il tempo in millisecondi successivo alle 00:00:00 GMT del 1 gennaio 1970.

Un'espressione regolare è un modello utilizzato per trovare sottostringhe nel testo. Groovy supporta le espressioni regolari in modo nativo utilizzando l'espressione ~ "regex". Il testo racchiuso tra le virgolette rappresenta l'espressione di confronto.

Ad esempio, possiamo creare un oggetto espressione regolare come mostrato di seguito:

def regex = ~'Groovy'

Quando l'operatore Groovy = ~ appare come predicato (espressione che restituisce un booleano) in if e while(vedere il Capitolo 8), l'operando String a sinistra viene confrontato con l'operando delle espressioni regolari a destra. Quindi, ciascuna delle seguenti opzioni fornisce il valore true.

Quando si definisce un'espressione regolare, è possibile utilizzare i seguenti caratteri speciali:

  • Sono disponibili due caratteri posizionali speciali utilizzati per indicare l'inizio e la fine di una riga: caret (∧) e simbolo del dollaro ($).

  • Le espressioni regolari possono includere anche quantificatori. Il segno più (+) rappresenta una o più volte, applicato all'elemento precedente dell'espressione. L'asterisco (*) viene utilizzato per rappresentare zero o più occorrenze. Il punto interrogativo (?) Indica zero o una volta.

  • Il metacarattere {e} viene utilizzato per abbinare un numero specifico di istanze del carattere precedente.

  • In un'espressione regolare, il simbolo del punto (.) Può rappresentare qualsiasi carattere. Questo è descritto come il carattere jolly.

  • Un'espressione regolare può includere classi di caratteri. Un insieme di caratteri può essere dato come una semplice sequenza di caratteri racchiusi nei metacaratteri [e] come in [aeiou]. Per intervalli di lettere o numeri, è possibile utilizzare un separatore di trattini come in [a – z] o [a – mA – M]. Il complemento di una classe di caratteri è indicato da un accento circonflesso all'interno delle racchette quadrate come in [∧a – z] e rappresenta tutti i caratteri diversi da quelli specificati. Di seguito vengono forniti alcuni esempi di espressioni regolari

'Groovy' =~ 'Groovy' 
'Groovy' =~ 'oo' 
'Groovy' ==~ 'Groovy' 
'Groovy' ==~ 'oo' 
'Groovy' =~ '∧G' 
‘Groovy' =~ 'G$' 
‘Groovy' =~ 'Gro*vy' 'Groovy' =~ 'Gro{2}vy'

La gestione delle eccezioni è richiesta in qualsiasi linguaggio di programmazione per gestire gli errori di runtime in modo da poter mantenere il normale flusso dell'applicazione.

L'eccezione normalmente interrompe il normale flusso dell'applicazione, motivo per cui dobbiamo utilizzare la gestione delle eccezioni nella nostra applicazione.

Le eccezioni sono generalmente classificate nelle seguenti categorie:

  • Checked Exception - Le classi che estendono la classe Throwable eccetto RuntimeException ed Error sono note come eccezioni controllate egIOException, SQLException ecc. Le eccezioni selezionate vengono verificate in fase di compilazione.

Un caso classico è FileNotFoundException. Supponi di avere il seguente codice nella tua applicazione che legge da un file nell'unità E.

class Example {
   static void main(String[] args) {
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file);
   } 
}

se il File (file.txt) non è presente nell'unità E, verrà sollevata la seguente eccezione.

Catturato: java.io.FileNotFoundException: E: \ file.txt (il sistema non riesce a trovare il file specificato).

java.io.FileNotFoundException: E: \ file.txt (il sistema non riesce a trovare il file specificato).

  • Unchecked Exception - Le classi che estendono RuntimeException sono note come eccezioni non controllate, ad esempio, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException ecc. Le eccezioni non controllate non vengono controllate in fase di compilazione, piuttosto vengono controllate in fase di esecuzione.

Un caso classico è ArrayIndexOutOfBoundsException che si verifica quando si tenta di accedere a un indice di un array che è maggiore della lunghezza dell'array. Di seguito è riportato un tipico esempio di questo tipo di errore.

class Example {
   static void main(String[] args) {
      def arr = new int[3];
      arr[5] = 5;
   } 
}

Quando il codice precedente viene eseguito, verrà sollevata la seguente eccezione.

Catturato: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - L'errore è irrecuperabile, ad esempio OutOfMemoryError, VirtualMachineError, AssertionError ecc.

Questi sono errori da cui il programma non potrà mai ripristinarsi e causeranno il crash del programma.

Il diagramma seguente mostra come è organizzata la gerarchia delle eccezioni in Groovy. È tutto basato sulla gerarchia definita in Java.

Catturare le eccezioni

Un metodo rileva un'eccezione utilizzando una combinazione di try e catchparole chiave. Un blocco try / catch viene posizionato attorno al codice che potrebbe generare un'eccezione.

try { 
   //Protected code 
} catch(ExceptionName e1) {
   //Catch block 
}

Tutto il codice che potrebbe sollevare un'eccezione viene inserito nel blocco di codice protetto.

Nel blocco catch è possibile scrivere codice personalizzato per gestire l'eccezione in modo che l'applicazione possa eseguire il ripristino dall'eccezione.

Diamo un'occhiata a un esempio del codice simile che abbiamo visto sopra per accedere a un array con un valore di indice maggiore della dimensione dell'array. Ma questa volta racchiudiamo il nostro codice in un blocco try / catch.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the exception 
Let's move on after the exception

Dal codice sopra, inseriamo il codice difettoso nel blocco try. Nel blocco catch stiamo solo catturando la nostra eccezione e inviando un messaggio che si è verificata un'eccezione.

Blocchi multipli di cattura

Si possono avere più blocchi catch per gestire più tipi di eccezioni. Per ogni blocco catch, a seconda del tipo di eccezione sollevata, dovresti scrivere codice per gestirlo di conseguenza.

Modifichiamo il nostro codice sopra per catturare specificamente l'eccezione ArrayIndexOutOfBoundsException. Di seguito è riportato lo snippet di codice.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the Aray out of Bounds exception 
Let's move on after the exception

Dal codice sopra puoi vedere che il blocco catch ArrayIndexOutOfBoundsException viene catturato per primo perché indica i criteri dell'eccezione.

Infine Block

Il finallyil blocco segue un blocco try o un blocco catch. Un blocco di codice infine viene sempre eseguito, indipendentemente dal verificarsi di un'eccezione.

L'utilizzo di un blocco finalmente consente di eseguire qualsiasi istruzione di tipo cleanup che si desidera eseguire, indipendentemente da ciò che accade nel codice protetto. La sintassi per questo blocco è fornita di seguito.

try { 
   //Protected code 
} catch(ExceptionType1 e1) { 
   //Catch block 
} catch(ExceptionType2 e2) { 
   //Catch block 
} catch(ExceptionType3 e3) { 
   //Catch block 
} finally {
   //The finally block always executes. 
}

Modifichiamo il nostro codice sopra e aggiungiamo il blocco di codice finalmente. Di seguito è riportato lo snippet di codice.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      } finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the Array out of Bounds exception 
The final block 
Let's move on after the exception

Di seguito sono riportati i metodi di eccezione disponibili in Groovy:

public String getMessage ()

Restituisce un messaggio dettagliato sull'eccezione che si è verificata. Questo messaggio viene inizializzato nel costruttore Throwable.

getCause lanciabili public ()

Restituisce la causa dell'eccezione rappresentata da un oggetto Throwable.

public String toString ()

Restituisce il nome della classe concatenato con il risultato di getMessage ()

public void printStackTrace ()

Stampa il risultato di toString () insieme alla traccia dello stack su System.err, il flusso di output dell'errore.

public StackTraceElement [] getStackTrace ()

Restituisce un array contenente ogni elemento nella traccia dello stack. L'elemento all'indice 0 rappresenta la parte superiore dello stack di chiamate e l'ultimo elemento dell'array rappresenta il metodo in fondo allo stack di chiamate.

public Throwable fillInStackTrace ()

Riempie la traccia dello stack di questo oggetto Throwable con la traccia dello stack corrente, aggiungendosi a qualsiasi informazione precedente nella traccia dello stack.

Esempio

Di seguito è riportato l'esempio di codice che utilizza alcuni dei metodi sopra indicati:

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println(ex.toString());
         println(ex.getMessage());
         println(ex.getStackTrace());  
      } catch(Exception ex) {
         println("Catching the exception");
      }finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

java.lang.ArrayIndexOutOfBoundsException: 5 
5 
[org.codehaus.groovy.runtime.dgmimpl.arrays.IntegerArrayPutAtMetaMethod$MyPojoMetaMet 
hodSite.call(IntegerArrayPutAtMetaMethod.java:75), 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ,
Example.main(Sample:8), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93),
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325),
groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1443),
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:893),
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:287),
groovy.lang.GroovyShell.run(GroovyShell.java:524),
groovy.lang.GroovyShell.run(GroovyShell.java:513),
groovy.ui.GroovyMain.processOnce(GroovyMain.java:652),
groovy.ui.GroovyMain.run(GroovyMain.java:384),
groovy.ui.GroovyMain.process(GroovyMain.java:370),
groovy.ui.GroovyMain.processArgs(GroovyMain.java:129),
groovy.ui.GroovyMain.main(GroovyMain.java:109),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109),
org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)]
 
The final block 
Let's move on after the exception

In Groovy, come in qualsiasi altro linguaggio orientato agli oggetti, esiste il concetto di classi e oggetti per rappresentare la natura orientata agli oggetti del linguaggio di programmazione. Una classe Groovy è una raccolta di dati e dei metodi che operano su tali dati. Insieme, i dati ei metodi di una classe vengono utilizzati per rappresentare alcuni oggetti del mondo reale dal dominio del problema.

Una classe in Groovy dichiara lo stato (dati) e il comportamento degli oggetti definiti da quella classe. Quindi, una classe Groovy descrive sia i campi di istanza che i metodi per quella classe.

Di seguito è riportato un esempio di una classe in Groovy. Il nome della classe è Studente che ha due campi:StudentID e StudentName. Nella funzione principale, stiamo creando un oggetto di questa classe e assegnando valori al fileStudentID e StudentName dell'oggetto.

class Student {
   int StudentID;
   String StudentName;
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe"     
   } 
}

Metodi getter e setter

In qualsiasi linguaggio di programmazione, è sempre una pratica nascondere i membri dell'istanza con la parola chiave private e fornire invece metodi getter e setter per impostare e ottenere di conseguenza i valori delle variabili di istanza. Il seguente esempio mostra come farlo.

class Student {
   private int StudentID;
   private String StudentName;
	
   void setStudentID(int pID) {
      StudentID = pID;
   }
	
   void setStudentName(String pName) {
      StudentName = pName;
   }
	
   int getStudentID() {
      return this.StudentID;
   }
	
   String getStudentName() {
      return this.StudentName;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.setStudentID(1);
      st.setStudentName("Joe");
		
      println(st.getStudentID());
      println(st.getStudentName());
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

1 
Joe

Notare i seguenti punti chiave sul programma di cui sopra:

  • Nella classe sia studentID che studentName sono contrassegnati come privati, il che significa che non è possibile accedervi dall'esterno della classe.

  • Ogni membro dell'istanza ha il proprio metodo getter e setter. Il metodo getter restituisce il valore della variabile di istanza, ad esempio il metodo int getStudentID () e il metodo setter imposta il valore dell'ID istanza, ad esempio il metodo - void setStudentName (String pName)

Metodi di istanza

Normalmente è naturale includere più metodi all'interno della classe che effettivamente esegue una sorta di funzionalità per la classe. Nel nostro esempio di studente, aggiungiamo membri di istanza di Marks1, Marks2 e Marks3 per denotare i voti dello studente in 3 materie. Aggiungeremo quindi un nuovo metodo di istanza che calcolerà i voti totali dello studente. Di seguito è riportato l'aspetto del codice.

Nell'esempio seguente, il metodo Total è un metodo Instance aggiuntivo che ha una logica incorporata.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() {
      return Marks1+Marks2+Marks3;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName="Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total());
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

60

Creazione di più oggetti

Si possono anche creare più oggetti di una classe. Di seguito è riportato l'esempio di come questo può essere ottenuto. Qui stiamo creando 3 oggetti (st, st1 e st2) e chiamando i loro membri di istanza e metodi di istanza di conseguenza.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() { 
      return Marks1+Marks2+Marks3;
   } 
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total()); 
   
      Student st1 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 40;
		
      println(st.Total());  
        
      Student st3 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10; 
      st.Marks2 = 20;
      st.Marks3 = 50;
		
      println(st.Total());
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

60 
70 
80

Eredità

L'ereditarietà può essere definita come il processo in cui una classe acquisisce le proprietà (metodi e campi) di un'altra. Con l'uso dell'ereditarietà le informazioni vengono rese gestibili in ordine gerarchico.

La classe che eredita le proprietà di altri è nota come sottoclasse (classe derivata, classe figlia) e la classe le cui proprietà sono ereditate è nota come superclasse (classe base, classe genitore).

Si estende

extendsè la parola chiave utilizzata per ereditare le proprietà di una classe. Di seguito è riportata la sintassi della parola chiave extends. Nell'esempio seguente stiamo facendo le seguenti cose:

  • Creare una classe chiamata Person. Questa classe ha un membro dell'istanza chiamato nome.

  • Creazione di una classe chiamata Student che si estende dalla classe Person. Si noti che il membro dell'istanza del nome definito nella classe Person viene ereditato nella classe Student.

  • Nel costruttore della classe Student, stiamo chiamando il costruttore della classe base.

  • Nella nostra classe Student, stiamo aggiungendo 2 membri di istanza aggiuntivi di StudentID e Marks1.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      st.Marks1 = 10;
      st.name = "Joe";
		
      println(st.name);
   }
} 

class Person {
   public String name;
   public Person() {}  
} 

class Student extends Person {
   int StudentID
   int Marks1;
	
   public Student() {
      super();
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Joe

Classi interne

Le classi interne sono definite all'interno di altre classi. La classe che la racchiude può usare la classe interna come al solito. Dall'altro lato, una classe interna può accedere ai membri della sua classe che lo racchiude, anche se sono privati. Le classi diverse dalla classe di inclusione non sono autorizzate ad accedere alle classi interne.

Di seguito è riportato un esempio di una classe esterna e interna. Nell'esempio seguente stiamo facendo le seguenti cose:

  • Creazione di una classe chiamata Outer che sarà la nostra classe esterna.
  • Definizione di una stringa chiamata nome nella nostra classe Outer.
  • Creazione di una classe interna o nidificata all'interno della nostra classe esterna.
  • Si noti che nella classe interna siamo in grado di accedere al membro dell'istanza del nome definito nella classe Outer.
class Example { 
   static void main(String[] args) { 
      Outer outobj = new Outer(); 
      outobj.name = "Joe"; 
      outobj.callInnerMethod() 
   } 
} 

class Outer { 
   String name;
	
   def callInnerMethod() { 
      new Inner().methodA() 
   } 
	
   class Inner {
      def methodA() { 
         println(name); 
      } 
   } 
	
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Joe

Classi astratte

Le classi astratte rappresentano concetti generici, quindi non possono essere istanziate, essendo create per essere sottoclasse. I loro membri includono campi / proprietà e metodi astratti o concreti. I metodi astratti non hanno implementazione e devono essere implementati da sottoclassi concrete. Le classi astratte devono essere dichiarate con la parola chiave abstract. Anche i metodi astratti devono essere dichiarati con la parola chiave abstract.

Nell'esempio seguente, notare che la classe Person è ora trasformata in una classe astratta e non può essere istanziata. Si noti inoltre che esiste un metodo astratto chiamato DisplayMarks nella classe abstract che non ha dettagli di implementazione. Nella classe studente è obbligatorio aggiungere i dettagli di implementazione.

class Example { 
   static void main(String[] args) { 
      Student st = new Student(); 
      st.StudentID = 1;
		
      st.Marks1 = 10; 
      st.name="Joe"; 
		
      println(st.name); 
      println(st.DisplayMarks()); 
   } 
} 

abstract class Person { 
   public String name; 
   public Person() { } 
   abstract void DisplayMarks();
}
 
class Student extends Person { 
   int StudentID 
   int Marks1; 
	
   public Student() { 
      super(); 
   } 
	
   void DisplayMarks() { 
      println(Marks1); 
   }  
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Joe 
10 
null

Interfacce

Un'interfaccia definisce un contratto a cui una classe deve conformarsi. Un'interfaccia definisce solo un elenco di metodi che devono essere implementati, ma non definisce l'implementazione dei metodi. Un'interfaccia deve essere dichiarata utilizzando la parola chiave interface. Un'interfaccia definisce solo le firme del metodo. I metodi di un'interfaccia sono semprepublic. È un errore utilizzare metodi protetti o privati ​​nelle interfacce.

Di seguito è riportato un esempio di un'interfaccia in groovy. Nell'esempio seguente stiamo facendo le seguenti cose:

  • Creazione di un'interfaccia denominata Marks e creazione di un metodo di interfaccia denominato DisplayMarks.

  • Nella definizione della classe, stiamo usando la parola chiave implements per implementare l'interfaccia.

  • Poiché stiamo implementando l'interfaccia, dobbiamo fornire l'implementazione per il metodo DisplayMarks.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
      println(st.DisplayMarks());
   } 
} 

interface Marks { 
   void DisplayMarks(); 
} 

class Student implements Marks {
   int StudentID
   int Marks1;
	
   void DisplayMarks() {
      println(Marks1);
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

10
null

I generici consentono ai tipi (classi e interfacce) di essere parametri durante la definizione di classi, interfacce e metodi. In modo molto simile ai parametri formali più familiari utilizzati nelle dichiarazioni di metodo, i parametri di tipo forniscono un modo per riutilizzare lo stesso codice con input diversi. La differenza è che gli input per i parametri formali sono valori, mentre gli input per i parametri di tipo sono tipi.

Generico per le raccolte

Le classi di raccolte come la classe List possono essere generalizzate in modo che nell'applicazione vengano accettate solo raccolte di quel tipo. Di seguito è mostrato un esempio di ArrayList generalizzato. Quello che fa la seguente dichiarazione è che accetta solo gli elementi della lista che sono di tipo stringa -

List<String> list = new ArrayList<String>();

Nel seguente esempio di codice, stiamo facendo quanto segue:

  • Creazione di una raccolta ArrayList generalizzata che conterrà solo stringhe.
  • Aggiungi 3 stringhe all'elenco.
  • Per ogni elemento della lista, stampa il valore delle stringhe.
class Example {
   static void main(String[] args) {
      // Creating a generic List collection
      List<String> list = new ArrayList<String>();
      list.add("First String");
      list.add("Second String");
      list.add("Third String");
		
      for(String str : list) {
         println(str);
      }
   } 
}

L'output del programma di cui sopra sarebbe:

First String 
Second String 
Third String

Classi generalizzate

L'intera classe può anche essere generalizzata. Ciò rende la classe più flessibile nell'accettare qualsiasi tipo e nel lavorare di conseguenza con quei tipi. Diamo un'occhiata a un esempio di come possiamo ottenere questo risultato.

Nel seguente programma, stiamo eseguendo i seguenti passaggi:

  • Stiamo creando una classe chiamata ListType. Notare le parole chiave <T> poste davanti alla definizione della classe. Questo dice al compilatore che questa classe può accettare qualsiasi tipo. Quindi quando dichiariamo un oggetto di questa classe, possiamo specificare un tipo durante la dichiarazione e quel tipo verrebbe sostituito nel segnaposto <T>

  • La classe generica ha semplici metodi getter e setter per lavorare con la variabile membro definita nella classe.

  • Notate nel programma principale che siamo in grado di dichiarare oggetti della classe ListType, ma di diverso tipo. Il primo è del tipo Integer e il secondo è del tipo String.

class Example {
   static void main(String[] args) {
      // Creating a generic List collection 
      ListType<String> lststr = new ListType<>();
      lststr.set("First String");
      println(lststr.get()); 
		
      ListType<Integer> lstint = new ListType<>();
      lstint.set(1);
      println(lstint.get());
   }
} 

public class ListType<T> {
   private T localt;
	
   public T get() {
      return this.localt;
   }
	
   public void set(T plocal) {
      this.localt = plocal;
   } 
}

L'output del programma di cui sopra sarebbe:

First String 
1

I tratti sono un costrutto strutturale del linguaggio che consente:

  • Composizione dei comportamenti.
  • Implementazione runtime delle interfacce.
  • Compatibilità con il controllo / compilazione del tipo statico

Possono essere visti come interfacce che trasportano sia le implementazioni predefinite che lo stato. Un tratto viene definito utilizzando la parola chiave tratto.

Di seguito viene fornito un esempio di un tratto:

trait Marks {
   void DisplayMarks() {
      println("Display Marks");
   } 
}

È quindi possibile utilizzare la parola chiave implement per implementare il tratto in modo simile alle interfacce.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10; 
      println(st.DisplayMarks());
   } 
} 

trait Marks { 
   void DisplayMarks() {
      println("Display Marks");
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;
}

Implementazione delle interfacce

I tratti possono implementare interfacce, nel qual caso le interfacce vengono dichiarate utilizzando la parola chiave implements.

Di seguito viene fornito un esempio di un tratto che implementa un'interfaccia. Nell'esempio seguente si possono notare i seguenti punti chiave.

  • Un'interfaccia Total viene definita con il metodo DisplayTotal.

  • Il tratto Marks implementa l'interfaccia Total e quindi deve fornire un'implementazione per il metodo DisplayTotal.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
} 

interface Total {
   void DisplayTotal() 
} 

trait Marks implements Total {
   void DisplayMarks() {
      println("Display Marks");
   }
	
   void DisplayTotal() {
      println("Display Total"); 
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;  
}

L'output del programma di cui sopra sarebbe:

Display Marks 
Display Total

Proprietà

Un tratto può definire proprietà. Di seguito viene fornito un esempio di un tratto con una proprietà.

Nell'esempio seguente, Marks1 di tipo integer è una proprietà.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
	
   interface Total {
      void DisplayTotal() 
   } 
	
   trait Marks implements Total {
      int Marks1;
		
      void DisplayMarks() {
         this.Marks1 = 10;
         println(this.Marks1);
      }
		
      void DisplayTotal() {
         println("Display Total");
      } 
   } 
	
   class Student implements Marks {
      int StudentID 
   }
}

L'output del programma di cui sopra sarebbe:

10 
Display Total

Composizione dei comportamenti

I tratti possono essere utilizzati per implementare l'ereditarietà multipla in modo controllato, evitando il problema del diamante. Nel seguente esempio di codice, abbiamo definito due tratti:Marks e Total. La nostra classe Student implementa entrambi i tratti. Poiché la classe studentesca estende entrambi i tratti, è in grado di accedere a entrambi i metodi:DisplayMarks e DisplayTotal.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal()); 
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total {
   void DisplayTotal() { 
      println("Total");
   } 
}  

class Student implements Marks,Total {
   int StudentID 
}

L'output del programma di cui sopra sarebbe:

Total 
Marks1

Tratti estesi

I tratti possono estendere un altro tratto, nel qual caso devi usare il extendsparola chiave. Nel seguente esempio di codice, stiamo estendendo il tratto Total con il tratto Marks.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      println(st.DisplayMarks());
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total extends Marks {
   void DisplayMarks() {
      println("Total");
   } 
}  

class Student implements Total {
   int StudentID 
}

L'output del programma di cui sopra sarebbe:

Total

Una chiusura è un breve blocco anonimo di codice. Normalmente si estende su poche righe di codice. Un metodo può anche prendere il blocco di codice come parametro. Sono di natura anonima.

Di seguito è riportato un esempio di una semplice chiusura e come appare.

class Example {
   static void main(String[] args) {
      def clos = {println "Hello World"};
      clos.call();
   } 
}

Nell'esempio precedente, la riga di codice - {println "Hello World"} è nota come chiusura. Il blocco di codice a cui fa riferimento questo identificatore può essere eseguito con l'istruzione call.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World

Parametri formali nelle chiusure

Le chiusure possono anche contenere parametri formali per renderle più utili proprio come i metodi in Groovy.

class Example {
   static void main(String[] args) {
      def clos = {param->println "Hello ${param}"};
      clos.call("World");
   } 
}

Nell'esempio di codice precedente, notare l'uso di $ {param} che fa sì che la chiusura prenda un parametro. Quando si chiama la chiusura tramite l'istruzione clos.call, ora abbiamo la possibilità di passare un parametro alla chiusura.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World

L'illustrazione successiva ripete l'esempio precedente e produce lo stesso risultato, ma mostra che un singolo parametro implicito a cui si fa riferimento può essere utilizzato. Qui "it" è una parola chiave in Groovy.

class Example {
   static void main(String[] args) {
      def clos = {println "Hello ${it}"};
      clos.call("World");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World

Chiusure e variabili

Più formalmente, le chiusure possono riferirsi a variabili nel momento in cui viene definita la chiusura. Di seguito è riportato un esempio di come questo può essere ottenuto.

class Example {     
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = {param -> println "${str1} ${param}"}
      clos.call("World");
		
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
   } 
}

Nell'esempio sopra, oltre a passare un parametro alla chiusura, stiamo anche definendo una variabile chiamata str1. La chiusura assume anche la variabile insieme al parametro.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World 
Welcome World

Utilizzo delle chiusure nei metodi

Le chiusure possono anche essere utilizzate come parametri per i metodi. In Groovy, molti metodi incorporati per i tipi di dati come elenchi e raccolte hanno chiusure come tipo di parametro.

L'esempio seguente mostra come inviare una chiusura a un metodo come parametro.

class Example { 
   def static Display(clo) {
      // This time the $param parameter gets replaced by the string "Inner"         
      clo.call("Inner");
   } 
	
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = { param -> println "${str1} ${param}" }
      clos.call("World");
		
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
		
      // Passing our closure to a method
      Example.Display(clos);
   } 
}

Nell'esempio sopra,

  • Stiamo definendo un metodo statico chiamato Display che accetta una chiusura come argomento.

  • Stiamo quindi definendo una chiusura nel nostro metodo principale e passandola al nostro metodo Display come parametro.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Hello World 
Welcome World 
Welcome Inner

Chiusure in collezioni e stringhe

Diversi metodi List, Map e String accettano una chiusura come argomento. Vediamo un esempio di come le chiusure possono essere utilizzate in questi tipi di dati.

Utilizzo di chiusure con elenchi

L'esempio seguente mostra come è possibile utilizzare le chiusure con gli elenchi. Nell'esempio seguente definiamo prima un semplice elenco di valori. Il tipo di raccolta elenco definisce quindi una funzione chiamata.each. Questa funzione assume una chiusura come parametro e applica la chiusura a ogni elemento della lista.

class Example {
   static void main(String[] args) {
      def lst = [11, 12, 13, 14];
      lst.each {println it}
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

11 
12 
13 
14

Utilizzo di chiusure con mappe

L'esempio seguente mostra come è possibile utilizzare le chiusure con Maps. Nell'esempio seguente definiamo prima una semplice mappa di elementi valore chiave. Il tipo di raccolta di mappe definisce quindi una funzione chiamata .each. Questa funzione assume una chiusura come parametro e applica la chiusura a ciascuna coppia chiave-valore della mappa.

class Example {
   static void main(String[] args) {
      def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]             
      mp.each {println it}
      mp.each {println "${it.key} maps to: ${it.value}"}
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

TopicName = Maps 
TopicDescription = Methods in Maps 
TopicName maps to: Maps 
TopicDescription maps to: Methods in Maps

Spesso, potremmo desiderare di iterare tra i membri di una raccolta e applicare una logica solo quando l'elemento soddisfa un criterio. Questo è prontamente gestito con una dichiarazione condizionale nella chiusura.

class Example {
   static void main(String[] args) {
      def lst = [1,2,3,4];
      lst.each {println it}
      println("The list will only display those numbers which are divisible by 2")
      lst.each{num -> if(num % 2 == 0) println num}
   } 
}

L'esempio precedente mostra l'espressione condizionale if (num% 2 == 0) utilizzata nella chiusura che viene utilizzata per verificare se ogni elemento nell'elenco è divisibile per 2.

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

1 
2 
3 
4 
The list will only display those numbers which are divisible by 2.
2 
4

Metodi utilizzati con le chiusure

Le stesse chiusure forniscono alcuni metodi.

Sr.No. Metodi e descrizione
1 trova()

Il metodo find trova il primo valore in una raccolta che corrisponde a un criterio.

2 trova tutto()

Trova tutti i valori nell'oggetto ricevente che corrispondono alla condizione di chiusura.

3 any () & every ()

Il metodo any esegue l'iterazione di ogni elemento di una raccolta verificando se un predicato booleano è valido per almeno un elemento.

4 raccogliere()

Il metodo collect itera attraverso una raccolta, convertendo ogni elemento in un nuovo valore utilizzando la chiusura come trasformatore.

Le annotazioni sono una forma di metadati in cui forniscono dati su un programma che non fa parte del programma stesso. Le annotazioni non hanno alcun effetto diretto sul funzionamento del codice che annotano.

Le annotazioni vengono utilizzate principalmente per i seguenti motivi:

  • Information for the compiler - Le annotazioni possono essere utilizzate dal compilatore per rilevare errori o sopprimere gli avvisi.

  • Compile-time and deployment-time processing - Gli strumenti software possono elaborare le informazioni di annotazione per generare codice, file XML e così via.

  • Runtime processing - Alcune annotazioni sono disponibili per essere esaminate in fase di esecuzione.

In Groovy, un'annotazione di base appare come segue:

@interface - Il carattere at sign (@) indica al compilatore che ciò che segue è un'annotazione.

Un'annotazione può definire membri in the form di metodi senza corpi e un valore predefinito opzionale.

Le annotazioni possono essere applicate ai seguenti tipi:

Tipo di stringa

Di seguito viene fornito un esempio di annotazione per una stringa:

@interface Simple { 
   String str1() default "HelloWorld"; 
}

Tipo di enumerazione

enum DayOfWeek { mon, tue, wed, thu, fri, sat, sun } 
@interface Scheduled {
   DayOfWeek dayOfWeek() 
}

Tipo di classe

@interface Simple {} 
@Simple 
class User {
   String username
   int age
}
 
def user = new User(username: "Joe",age:1); 
println(user.age); 
println(user.username);

Valori dei membri dell'annotazione

Quando viene utilizzata un'annotazione, è necessario impostare almeno tutti i membri che non hanno un valore predefinito. Un esempio è dato seguito. Quando l'annotazione Esempio viene utilizzata dopo essere stata definita, deve essere assegnato un valore.

@interface Example {
   int status() 
}

@Example(status = 1)

Parametri di annotazione di chiusura

Una buona caratteristica delle annotazioni in Groovy è che puoi usare una chiusura anche come valore di annotazione. Pertanto le annotazioni possono essere utilizzate con un'ampia varietà di espressioni.

Di seguito viene fornito un esempio su questo. L'annotazione Onlyif viene creata in base a un valore di classe. Quindi l'annotazione viene applicata a due metodi che inviano messaggi diversi alla variabile di risultato in base al valore della variabile numerica.

@interface OnlyIf {
   Class value() 
}  

@OnlyIf({ number<=6 }) 
void Version6() {
   result << 'Number greater than 6' 
} 

@OnlyIf({ number>=6 }) 
void Version7() {
   result << 'Number greater than 6' 
}

Meta annotazioni

Questa è una caratteristica abbastanza utile delle annotazioni in groovy. Potrebbero arrivare momenti in cui potresti avere più annotazioni per un metodo come quello mostrato di seguito. A volte può diventare complicato avere più annotazioni.

@Procedure 
@Master class 
MyMasterProcedure {}

In tal caso è possibile definire una meta-annotazione che raggruppa più annotazioni insieme e applicare la meta annotazione al metodo. Quindi, per l'esempio precedente, puoi definire per prima cosa la raccolta di annotazioni utilizzando AnnotationCollector.

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector

Fatto ciò, puoi applicare il seguente meta-annotatore al metodo:

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector
  
@MasterProcedure 
class MyMasterProcedure {}

XML è un linguaggio portatile e open source che consente ai programmatori di sviluppare applicazioni che possono essere lette da altre applicazioni, indipendentemente dal sistema operativo e / o dal linguaggio di sviluppo. Questa è una delle lingue più comuni utilizzate per lo scambio di dati tra le applicazioni.

Cos'è l'XML?

L'XML Extensible Markup Language è un linguaggio di markup molto simile a HTML o SGML. Questo è consigliato dal World Wide Web Consortium e disponibile come standard aperto. XML è estremamente utile per tenere traccia di piccole e medie quantità di dati senza richiedere un backbone basato su SQL.

Supporto XML in Groovy

Il linguaggio Groovy fornisce anche un ricco supporto del linguaggio XML. Le due classi XML più basilari utilizzate sono:

  • XML Markup Builder- Groovy supporta un generatore di markup basato su albero, BuilderSupport, che può essere suddiviso in sottoclassi per creare una varietà di rappresentazioni di oggetti strutturati ad albero. Comunemente, questi builder vengono utilizzati per rappresentare markup XML, markup HTML. Il generatore di markup di Groovy cattura le chiamate a pseudometodi e le converte in elementi o nodi di una struttura ad albero. I parametri di questi pseudometodi vengono trattati come attributi dei nodi. Le chiusure come parte della chiamata al metodo sono considerate come contenuto secondario annidato per il nodo della struttura ad albero risultante.

  • XML Parser- La classe Groovy XmlParser utilizza un semplice modello per analizzare un documento XML in un albero di istanze di Node. Ogni nodo ha il nome dell'elemento XML, gli attributi dell'elemento e riferimenti a qualsiasi nodo figlio. Questo modello è sufficiente per l'elaborazione XML più semplice.

Per tutti i nostri esempi di codice XML, utilizziamo il seguente semplice file XML movies.xml per la costruzione del file XML e la successiva lettura del file.

<collection shelf = "New Arrivals"> 

   <movie title = "Enemy Behind"> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Talk about a US-Japan war</description> 
   </movie> 
	
   <movie title = "Transformers"> 
      <type>Anime, Science Fiction</type>
      <format>DVD</format> 
      <year>1989</year> 
      <rating>R</rating> 
      <stars>8</stars> 
      <description>A schientific fiction</description> 
   </movie> 
	
   <movie title = "Trigun"> 
      <type>Anime, Action</type> 
      <format>DVD</format> 
      <year>1986</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Vash the Stam pede!</description> 
   </movie> 
	
   <movie title = "Ishtar"> 
      <type>Comedy</type> 
      <format>VHS</format> 
      <year>1987</year> 
      <rating>PG</rating> 
      <stars>2</stars> 
      <description>Viewable boredom </description> 
   </movie> 
	
</collection>

Generatore di markup XML

Sintassi

public MarkupBuilder()

MarkupBuilder viene utilizzato per costruire l'intero documento XML. Il documento XML viene creato creando prima un oggetto della classe del documento XML. Una volta creato l'oggetto, è possibile richiamare uno pseudometodo per creare i vari elementi del documento XML.

Diamo un'occhiata a un esempio di come creare un blocco, cioè un elemento del film dal documento XML sopra -

import groovy.xml.MarkupBuilder 

class Example {
   static void main(String[] args) {
      def mB = new MarkupBuilder()
		
      // Compose the builder
      mB.collection(shelf : 'New Arrivals') {
         movie(title : 'Enemy Behind')
         type('War, Thriller')
         format('DVD')
         year('2003')
         rating('PG')
         stars(10)
         description('Talk about a US-Japan war') 
      }
   } 
}

Nell'esempio sopra, è necessario notare quanto segue:

  • mB.collection() - Questo è un generatore di markup che crea il tag XML head di <collection> </collection>

  • movie(title : 'Enemy Behind')- Questi pseudometodi creano i tag figlio con questo metodo creando il tag con il valore. Specificando un valore chiamato titolo, ciò indica effettivamente che è necessario creare un attributo per l'elemento.

  • Viene fornita una chiusura allo pseudometodo per creare gli elementi rimanenti del documento XML.

  • Il costruttore predefinito per la classe MarkupBuilder viene inizializzato in modo che l'XML generato venga emesso nel flusso di output standard

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

<collection shelf = 'New Arrivals'> 
   <movie title = 'Enemy Behind' /> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Talk about a US-Japan war</description> 
   </movie> 
</collection>

Per creare l'intero documento XML, è necessario eseguire le seguenti operazioni.

  • È necessario creare una voce di mappa per memorizzare i diversi valori degli elementi.
  • Per ogni elemento della mappa, stiamo assegnando il valore a ciascun elemento.
import groovy.xml.MarkupBuilder 

class Example {
   static void main(String[] args) {
      def mp = [1 : ['Enemy Behind', 'War, Thriller','DVD','2003', 
         'PG', '10','Talk about a US-Japan war'],
         2 : ['Transformers','Anime, Science Fiction','DVD','1989', 
         'R', '8','A scientific fiction'],
         3 : ['Trigun','Anime, Action','DVD','1986', 
         'PG', '10','Vash the Stam pede'],
         4 : ['Ishtar','Comedy','VHS','1987', 'PG', 
         '2','Viewable boredom ']] 
			
      def mB = new MarkupBuilder()  
		
      // Compose the builder
      def MOVIEDB = mB.collection('shelf': 'New Arrivals') {
         mp.each {
            sd -> 
            mB.movie('title': sd.value[0]) {  
               type(sd.value[1])
               format(sd.value[2])
               year(sd.value[3]) 
               rating(sd.value[4])
               stars(sd.value[4]) 
               description(sd.value[5]) 
            }
         }
      }
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

<collection shelf = 'New Arrivals'> 
   <movie title = 'Enemy Behind'> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>10</description> 
   </movie> 
   <movie title = 'Transformers'> 
      <type>Anime, Science Fiction</type> 
      <format>DVD</format> 
      <year>1989</year>
	  <rating>R</rating> 
      <stars>R</stars> 
      <description>8</description> 
   </movie> 
   <movie title = 'Trigun'> 
      <type>Anime, Action</type> 
      <format>DVD</format> 
      <year>1986</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>10</description> 
   </movie> 
   <movie title = 'Ishtar'> 
      <type>Comedy</type> 
      <format>VHS</format> 
      <year>1987</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>2</description> 
   </movie> 
</collection>

Analisi XML

La classe Groovy XmlParser utilizza un semplice modello per analizzare un documento XML in un albero di istanze di Node. Ogni nodo ha il nome dell'elemento XML, gli attributi dell'elemento e riferimenti a qualsiasi nodo figlio. Questo modello è sufficiente per l'elaborazione XML più semplice.

Sintassi

public XmlParser() 
   throws ParserConfigurationException, 
      SAXException

Il codice seguente mostra un esempio di come il parser XML può essere utilizzato per leggere un documento XML.

Supponiamo di avere lo stesso documento chiamato Movies.xml e di voler analizzare il documento XML e visualizzare un output appropriato per l'utente. Il codice seguente è un frammento di come possiamo attraversare l'intero contenuto del documento XML e visualizzare una risposta adeguata all'utente.

import groovy.xml.MarkupBuilder 
import groovy.util.*

class Example {

   static void main(String[] args) { 
	
      def parser = new XmlParser()
      def doc = parser.parse("D:\\Movies.xml");
		
      doc.movie.each{
         bk->
         print("Movie Name:")
         println "${bk['@title']}" print("Movie Type:") println "${bk.type[0].text()}"
			
         print("Movie Format:")
         println "${bk.format[0].text()}" print("Movie year:") println "${bk.year[0].text()}"
			
         print("Movie rating:")
         println "${bk.rating[0].text()}" print("Movie stars:") println "${bk.stars[0].text()}"
			
         print("Movie description:")
         println "${bk.description[0].text()}"
         println("*******************************")
      }
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Movie Name:Enemy Behind 
Movie Type:War, Thriller 
Movie Format:DVD 
Movie year:2003 
Movie rating:PG 
Movie stars:10 
Movie description:Talk about a US-Japan war 
******************************* 
Movie Name:Transformers 
Movie Type:Anime, Science Fiction 
Movie Format:DVD 
Movie year:1989 
Movie rating:R 
Movie stars:8 
Movie description:A schientific fiction 
******************************* 
Movie Name:Trigun 
Movie Type:Anime, Action
Movie Format:DVD 
Movie year:1986 
Movie rating:PG 
Movie stars:10 
Movie description:Vash the Stam pede! 
******************************* 
Movie Name:Ishtar 
Movie Type:Comedy 
Movie Format:VHS 
Movie year:1987 
Movie rating:PG 
Movie stars:2 
Movie description:Viewable boredom

Le cose importanti da notare sul codice sopra.

  • Si sta formando un oggetto della classe XmlParser in modo che possa essere utilizzato per analizzare il documento XML.

  • Al parser viene data la posizione del file XML.

  • Per ogni elemento del film, utilizziamo una chiusura per navigare in ogni nodo figlio e visualizzare le informazioni pertinenti.

Per l'elemento film stesso, stiamo usando il simbolo @ per visualizzare l'attributo titolo allegato all'elemento film.

JMX è lo standard di fatto utilizzato per monitorare tutte le applicazioni che hanno qualcosa a che fare con l'ambiente virtuale Java. Dato che Groovy si trova direttamente sopra Java, Groovy può sfruttare l'enorme quantità di lavoro già svolto per JMX con Java.

Monitoraggio della JVM

Si possono utilizzare le classi standard disponibili in java.lang.management per effettuare il monitoraggio della JVM. Il seguente esempio di codice mostra come eseguire questa operazione.

import java.lang.management.*

def os = ManagementFactory.operatingSystemMXBean 
println """OPERATING SYSTEM: 
\tOS architecture = $os.arch 
\tOS name = $os.name \tOS version = $os.version 
\tOS processors = $os.availableProcessors """ def rt = ManagementFactory.runtimeMXBean println """RUNTIME: \tRuntime name = $rt.name 
   \tRuntime spec name = $rt.specName \tRuntime vendor = $rt.specVendor 
   \tRuntime spec version = $rt.specVersion \tRuntime management spec version = $rt.managementSpecVersion 
   """ 

def mem = ManagementFactory.memoryMXBean 
def heapUsage = mem.heapMemoryUsage 
def nonHeapUsage = mem.nonHeapMemoryUsage 

println """MEMORY: 
   HEAP STORAGE: 
      \tMemory committed = $heapUsage.committed \tMemory init = $heapUsage.init 
      \tMemory max = $heapUsage.max \tMemory used = $heapUsage.used NON-HEAP STORAGE: 
      \tNon-heap memory committed = $nonHeapUsage.committed \tNon-heap memory init = $nonHeapUsage.init 
      \tNon-heap memory max = $nonHeapUsage.max \tNon-heap memory used = $nonHeapUsage.used 
   """
  
println "GARBAGE COLLECTION:" 
ManagementFactory.garbageCollectorMXBeans.each { gc ->
   println "\tname = $gc.name" println "\t\tcollection count = $gc.collectionCount"
   println "\t\tcollection time = $gc.collectionTime" String[] mpoolNames = gc.memoryPoolNames mpoolNames.each { mpoolName -> println "\t\tmpool name = $mpoolName"
   } 
}

Quando il codice viene eseguito, l'output varierà a seconda del sistema su cui viene eseguito il codice. Di seguito viene fornito un esempio dell'output.

OPERATING SYSTEM: 
   OS architecture = x86 
   OS name = Windows 7 
   OS version = 6.1 
   OS processors = 4
   
RUNTIME: 
   Runtime name = 5144@Babuli-PC 
   Runtime spec name = Java Virtual Machine Specification 
   Runtime vendor = Oracle Corporation 
   Runtime spec version = 1.7 
   Runtime management spec version = 1.2
   
MEMORY: 
   HEAP STORAGE: 
      Memory committed = 16252928 
      Memory init = 16777216 
      Memory max = 259522560 
      Memory used = 7355840
   
NON-HEAP STORAGE: 
   Non-heap memory committed = 37715968 
   Non-heap memory init = 35815424 
   Non-heap memory max = 123731968 
   Non-heap memory used = 18532232 
   
GARBAGE COLLECTION: 
   name = Copy 
   collection count = 15 
   collection time = 47 
   mpool name = Eden Space 
   mpool name = Survivor Space
		
   name = MarkSweepCompact 
      collection count = 0 
      collection time = 0 
		
      mpool name = Eden Space 
      mpool name = Survivor Space 
      mpool name = Tenured Gen 
      mpool name = Perm Gen 
      mpool name = Perm Gen [shared-ro] 
      mpool name = Perm Gen [shared-rw]

Monitoraggio di Tomcat

Per monitorare Tomcat, è necessario impostare il seguente parametro all'avvio di Tomcat:

set JAVA_OPTS = -Dcom.sun.management.jmxremote 
Dcom.sun.management.jmxremote.port = 9004\
 
-Dcom.sun.management.jmxremote.authenticate=false 
Dcom.sun.management.jmxremote.ssl = false

Il codice seguente utilizza JMX per rilevare gli MBean disponibili nel Tomcat in esecuzione, determinare quali sono i moduli Web ed estrarre il tempo di elaborazione per ciascun modulo Web.

import groovy.swing.SwingBuilder
  
import javax.management.ObjectName 
import javax.management.remote.JMXConnectorFactory as JmxFactory 
import javax.management.remote.JMXServiceURL as JmxUrl 
import javax.swing.WindowConstants as WC 
 
import org.jfree.chart.ChartFactory 
import org.jfree.data.category.DefaultCategoryDataset as Dataset 
import org.jfree.chart.plot.PlotOrientation as Orientation 
 
def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi' 
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection 
def serverInfo = new GroovyMBean(server, 'Catalina:type = Server').serverInfo 
println "Connected to: $serverInfo" def query = new ObjectName('Catalina:*') String[] allNames = server.queryNames(query, null) def modules = allNames.findAll { name -> name.contains('j2eeType=WebModule') }.collect{ new GroovyMBean(server, it) } println "Found ${modules.size()} web modules. Processing ..." 
def dataset = new Dataset() 
 
modules.each { m ->
   println m.name()
   dataset.addValue m.processingTime, 0, m.path 
}

Questo capitolo spiega come utilizzare il linguaggio Groovy per analizzare e produrre oggetti JSON.

Funzioni JSON

Suor n Funzioni e librerie
1

JsonSlurper

JsonSlurper è una classe che analizza il testo JSON o il contenuto del lettore in dati Groovy

Strutture come mappe, elenchi e tipi primitivi come Integer, Double, Boolean e String.

2

JsonOutput

Questo metodo è responsabile della serializzazione di oggetti Groovy in stringhe JSON.

Analisi dei dati utilizzando JsonSlurper

JsonSlurper è una classe che analizza il testo JSON o il contenuto del lettore in strutture dati Groovy come mappe, elenchi e tipi primitivi come Integer, Double, Boolean e String.

Sintassi

def slurper = new JsonSlurper()

Lo slurper JSON analizza il testo o il contenuto del lettore in una struttura di dati di elenchi e mappe.

La classe JsonSlurper viene fornita con un paio di varianti per le implementazioni del parser. A volte potresti avere requisiti diversi quando si tratta di analizzare determinate stringhe. Prendiamo un'istanza in cui è necessario leggere il JSON restituito dalla risposta da un server web. In tal caso è utile utilizzare la variante parser JsonParserLax. Questo parsee consente commenti nel testo JSON così come nessuna stringa di virgolette ecc. Per specificare questo tipo di parser è necessario utilizzare il tipo di parser JsonParserType.LAX quando si definisce un oggetto di JsonSlurper.

Vediamo un esempio di questo dato di seguito. L'esempio è per ottenere dati JSON da un server Web utilizzando il modulo http. Per questo tipo di attraversamento, l'opzione migliore è impostare il tipo di parser sulla variante JsonParserLax.

http.request( GET, TEXT ) {
   headers.Accept = 'application/json'
   headers.'User-Agent' = USER_AGENT
	
   response.success = { 
      res, rd ->  
      def jsonText = rd.text 
		
      //Setting the parser type to JsonParserLax
      def parser = new JsonSlurper().setType(JsonParserType.LAX)
      def jsonResp = parser.parseText(jsonText)
   }
}

Allo stesso modo i seguenti tipi di parser aggiuntivi sono disponibili in Groovy:

  • Il parser JsonParserCharArray prende fondamentalmente una stringa JSON e opera sulla matrice di caratteri sottostante. Durante la conversione del valore, copia i sotto-array di caratteri (un meccanismo noto come "taglio") e opera su di essi individualmente.

  • JsonFastParser è una variante speciale di JsonParserCharArray ed è il parser più veloce. JsonFastParser è anche noto come parser di overlay dell'indice. Durante l'analisi della stringa JSON data, cerca il più possibile di evitare di creare nuovi array di caratteri o istanze di stringa. Mantiene solo i puntatori all'array di caratteri originale sottostante. Inoltre, differisce la creazione dell'oggetto il più tardi possibile.

  • JsonParserUsingCharacterSource è un parser speciale per file di grandi dimensioni. Utilizza una tecnica chiamata "windowing dei caratteri" per analizzare file JSON di grandi dimensioni (in questo caso grandi significa file di dimensioni superiori a 2 MB) con prestazioni costanti.

Analisi del testo

Diamo un'occhiata ad alcuni esempi di come possiamo usare la classe JsonSlurper.

import groovy.json.JsonSlurper 

class Example {
   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      def object = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}') 
		
      println(object.name);
      println(object.ID);
   } 
}

Nell'esempio sopra, siamo:

  • Prima creazione di un'istanza della classe JsonSlurper

  • Stiamo quindi utilizzando la funzione parseText della classe JsonSlurper per analizzare del testo JSON.

  • Quando otteniamo l'oggetto, puoi vedere che possiamo effettivamente accedere ai valori nella stringa JSON tramite la chiave.

L'output del programma di cui sopra è dato di seguito:

John 
1

Elenco di analisi di numeri interi

Diamo un'occhiata a un altro esempio del metodo di analisi JsonSlurper. Nell'esempio seguente, stiamo passando un elenco di numeri interi. Noterai dal seguente codice che siamo in grado di utilizzare il metodo List di ciascuno e di chiuderlo.

import groovy.json.JsonSlurper 
class Example {
   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      Object lst = jsonSlurper.parseText('{ "List": [2, 3, 4, 5] }')
      lst.each { println it }
   } 
}

L'output del programma di cui sopra è dato di seguito:

List=[2, 3, 4, 5]

Elenco di analisi dei tipi di dati primitivi

Il parser JSON supporta anche i tipi di dati primitivi di stringa, numero, oggetto, vero, falso e null. La classe JsonSlurper converte questi tipi JSON nei corrispondenti tipi Groovy.

L'esempio seguente mostra come utilizzare JsonSlurper per analizzare una stringa JSON. E qui puoi vedere che JsonSlurper è in grado di analizzare i singoli elementi nei rispettivi tipi primitivi.

import groovy.json.JsonSlurper 
class Example {

   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      def obj = jsonSlurper.parseText ''' {"Integer": 12, "fraction": 12.55, "double": 12e13}'''
		
      println(obj.Integer);
      println(obj.fraction);
      println(obj.double); 
   } 
}

L'output del programma di cui sopra è dato di seguito:

12 
12.55 
1.2E+14

JsonOutput

Ora parliamo di come stampare l'output in Json. Questo può essere fatto con il metodo JsonOutput. Questo metodo è responsabile della serializzazione di oggetti Groovy in stringhe JSON.

Sintassi

Static string JsonOutput.toJson(datatype obj)

Parameters - I parametri possono essere un oggetto di un tipo di dati: numero, booleano, carattere, stringa, data, mappa, chiusura ecc.

Return type - Il tipo restituito è una stringa json.

Esempio

Di seguito è riportato un semplice esempio di come questo può essere ottenuto.

import groovy.json.JsonOutput 
class Example {
   static void main(String[] args) {
      def output = JsonOutput.toJson([name: 'John', ID: 1])
      println(output);  
   }
}

L'output del programma di cui sopra è dato di seguito:

{"name":"John","ID":1}

JsonOutput può essere utilizzato anche per semplici oggetti vecchi e groovy. Nell'esempio seguente, puoi vedere che stiamo effettivamente passando oggetti del tipo Student al metodo JsonOutput.

import groovy.json.JsonOutput  
class Example {
   static void main(String[] args) {
      def output = JsonOutput.toJson([ new Student(name: 'John',ID:1),
         new Student(name: 'Mark',ID:2)])
      println(output);  
   } 
}
 
class Student {
   String name
   int ID; 
}

L'output del programma di cui sopra è dato di seguito:

[{"name":"John","ID":1},{"name":"Mark","ID":2}]

Groovy consente di omettere le parentesi attorno agli argomenti di una chiamata di metodo per le istruzioni di primo livello. Questa funzione è nota come "catena di comandi". Questa estensione funziona consentendo di concatenare tali chiamate di metodo senza parentesi, senza richiedere né parentesi attorno agli argomenti, né punti tra le chiamate concatenate.

Se una chiamata viene eseguita come a b c d, questo sarà effettivamente equivalente a a(b).c(d).

Il linguaggio DSL o Domain specifico ha lo scopo di semplificare il codice scritto in Groovy in modo tale da renderlo facilmente comprensibile per l'utente comune. Il seguente esempio mostra cosa si intende esattamente per avere una lingua specifica del dominio.

def lst = [1,2,3,4] 
print lst

Il codice precedente mostra un elenco di numeri stampati sulla console utilizzando l'istruzione println. In una lingua specifica del dominio i comandi sarebbero come:

Given the numbers 1,2,3,4
 
Display all the numbers

Quindi l'esempio sopra mostra la trasformazione del linguaggio di programmazione per soddisfare le esigenze di un linguaggio specifico del dominio.

Diamo un'occhiata a un semplice esempio di come possiamo implementare i DSL in Groovy:

class EmailDsl {  
   String toText 
   String fromText 
   String body 
	
   /** 
   * This method accepts a closure which is essentially the DSL. Delegate the 
   * closure methods to 
   * the DSL class so the calls can be processed 
   */ 
   
   def static make(closure) { 
      EmailDsl emailDsl = new EmailDsl() 
      // any method called in closure will be delegated to the EmailDsl class 
      closure.delegate = emailDsl
      closure() 
   }
   
   /** 
   * Store the parameter as a variable and use it later to output a memo 
   */ 
	
   def to(String toText) { 
      this.toText = toText 
   }
   
   def from(String fromText) { 
      this.fromText = fromText 
   }
   
   def body(String bodyText) { 
      this.body = bodyText 
   } 
}

EmailDsl.make { 
   to "Nirav Assar" 
   from "Barack Obama" 
   body "How are things? We are doing well. Take care" 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

How are things? We are doing well. Take care

Quanto segue deve essere notato sull'implementazione del codice precedente:

  • Viene utilizzato un metodo statico che accetta una chiusura. Questo è principalmente un modo semplice per implementare un DSL.

  • Nell'esempio di posta elettronica, la classe EmailDsl ha un metodo make. Crea un'istanza e delega tutte le chiamate nella chiusura all'istanza. Questo è il meccanismo in cui le sezioni "a" e "da" finiscono per eseguire metodi all'interno della classe EmailDsl.

  • Una volta chiamato il metodo to (), memorizziamo il testo nell'istanza per la formattazione in seguito.

  • Ora possiamo chiamare il metodo EmailDSL con un linguaggio semplice e di facile comprensione per gli utenti finali.

Il modulo groovy-sql di Groovy fornisce un'astrazione di livello superiore rispetto all'attuale tecnologia JDBC di Java. L'API Groovy sql supporta un'ampia varietà di database, alcuni dei quali sono mostrati di seguito.

  • HSQLDB
  • Oracle
  • server SQL
  • MySQL
  • MongoDB

Nel nostro esempio, useremo MySQL DB come esempio. Per utilizzare MySQL con Groovy, la prima cosa da fare è scaricare il file jar jdbc di MySQL dal sito mysql.The format di MySQL verrà mostrato di seguito.

mysql-connector-java-5.1.38-bin

Quindi assicurati di aggiungere il file jar sopra al classpath nella tua workstation.

Connessione al database

Prima di connetterti a un database MySQL, assicurati di quanto segue:

  • Hai creato un database TESTDB.
  • Hai creato una tabella EMPLOYEE in TESTDB.
  • Questa tabella ha i campi FIRST_NAME, LAST_NAME, AGE, SEX e INCOME.
  • L'ID utente "testuser" e la password "test123" sono impostati per accedere a TESTDB.
  • Assicurati di aver scaricato il file jar mysql e di averlo aggiunto al tuo classpath.
  • Hai seguito il tutorial di MySQL per comprendere le basi di MySQL

Il seguente esempio mostra come connettersi al database MySQL "TESTDB".

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 
         'testuser', 'test123', 'com.mysql.jdbc.Driver')
			
      // Executing the query SELECT VERSION which gets the version of the database
      // Also using the eachROW method to fetch the result from the database
   
      sql.eachRow('SELECT VERSION()'){ row ->
         println row[0]
      }
		
      sql.close()  
   } 
}

Durante l'esecuzione di questo script, produce il seguente risultato:

5.7.10-log 
The Sql.newInstance method is used to establish a connection to the database.

Creazione della tabella del database

Il passaggio successivo dopo la connessione al database è creare le tabelle nel nostro database. L'esempio seguente mostra come creare una tabella nel database utilizzando Groovy. Il metodo di esecuzione della classe Sql viene utilizzato per eseguire istruzioni sul database.

import java.sql.*; 
import groovy.sql.Sql 

class Example { 
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser',  
         'test123', 'com.mysql.jdbc.Driver')
			
      def sqlstr = """CREATE TABLE EMPLOYEE ( 
         FIRST_NAME CHAR(20) NOT NULL,
         LAST_NAME CHAR(20),
         AGE INT,
         SEX CHAR(1),
         INCOME FLOAT )""" 
							
      sql.execute(sqlstr);
      sql.close() 
   } 
}

Inserisci operazione

È necessario quando si desidera creare i record in una tabella di database.

Esempio

Il seguente esempio inserirà un record nella tabella dei dipendenti. Il codice viene inserito in un blocco try catch in modo che, se il record viene eseguito correttamente, la transazione viene salvata nel database. Se la transazione fallisce, viene eseguito un rollback.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) { 
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
		
      def sqlstr = """INSERT INTO EMPLOYEE(FIRST_NAME,
         LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" 
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed") 
      }catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback") 
      }
		
      sql.close()
   } 
}

Supponiamo di voler selezionare solo determinate righe in base a un criterio. Il codice seguente mostra come aggiungere un segnaposto di parametro per cercare i valori. L'esempio precedente può anche essere scritto per accettare i parametri come mostrato nel codice seguente. Il simbolo $ viene utilizzato per definire un parametro che può quindi essere sostituito da valori quando viene eseguita l'istruzione sql.

import java.sql.*; 
import groovy.sql.Sql
 
class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false  
      
      def firstname = "Mac"
      def lastname ="Mohan"
      def age = 20
      def sex = "M"
      def income = 2000  
		
      def sqlstr = "INSERT INTO EMPLOYEE(FIRST_NAME,LAST_NAME, AGE, SEX, 
         INCOME) VALUES " + "(${firstname}, ${lastname}, ${age}, ${sex}, ${income} )"
			
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed") 
      } catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback")
      }
		
      sql.close()
   }
}

Operazione READ

READ Operare su qualsiasi database significa prelevare alcune informazioni utili dal database. Una volta stabilita la connessione al database, sei pronto per eseguire una query in questo database.

L'operazione di lettura viene eseguita utilizzando il metodo eachRow della classe sql.

Sintassi

eachRow(GString gstring, Closure closure)

Esegue la query SQL specificata chiamando il Closure specificato con ogni riga del set di risultati.

Parameters

  • Gstring - L'istruzione sql che deve essere eseguita.

  • Closure- L'istruzione di chiusura per elaborare le righe recuperate dall'operazione di lettura. Esegue la query SQL specificata chiamando il Closure specificato con ogni riga del set di risultati.

Il seguente esempio di codice mostra come recuperare tutti i record dalla tabella Employee.

import java.sql.*; 
import groovy.sql.Sql
 
class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')  
			
      sql.eachRow('select * from employee') {
         tp -> 
         println([tp.FIRST_NAME,tp.LAST_NAME,tp.age,tp.sex,tp.INCOME])
      }  
		
      sql.close()
   } 
}

L'output del programma precedente sarebbe:

[Mac, Mohan, 20, M, 2000.0]

Operazione di aggiornamento

AGGIORNAMENTO Operare su qualsiasi database significa aggiornare uno o più record, già disponibili nel database. La seguente procedura aggiorna tutti i record che hanno SEX come "M". Qui, aumentiamo l'ETÀ di tutti i maschi di un anno.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args){
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test@123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
      def sqlstr = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = 'M'" 
	  
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed")
      }catch(Exception ex) {
         sql.rollback() 
         println("Transaction rollback")
      }
		
      sql.close()
   } 
}

Operazione DELETE

L'operazione DELETE è necessaria quando si desidera eliminare alcuni record dal database. Di seguito è riportata la procedura per eliminare tutti i record da DIPENDENTE di cui ETÀ è superiore a 20.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test@123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
      def sqlstr = "DELETE FROM EMPLOYEE WHERE AGE > 20"
   
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed")
      }catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback")
      }
   
      sql.close()
   } 
}

Esecuzione di transazioni

Le transazioni sono un meccanismo che garantisce la coerenza dei dati. Le transazioni hanno le seguenti quattro proprietà:

  • Atomicity - O una transazione viene completata o non accade nulla.

  • Consistency - Una transazione deve iniziare in uno stato coerente e lasciare il sistema in uno stato coerente.

  • Isolation - I risultati intermedi di una transazione non sono visibili al di fuori della transazione corrente.

  • Durability - Una volta che una transazione è stata confermata, gli effetti sono persistenti, anche dopo un errore di sistema.

Ecco un semplice esempio di come implementare le transazioni. Abbiamo già visto questo esempio dal nostro argomento precedente dell'operazione DELETE.

def sqlstr = "DELETE FROM EMPLOYEE WHERE AGE > 20" 
 
try {
   sql.execute(sqlstr); 
   sql.commit()
   println("Successfully committed") 
}catch(Exception ex) {
   sql.rollback()
   println("Transaction rollback") 
} 
sql.close()

Commit Operation

L'operazione di commit è ciò che dice al database di procedere con l'operazione e finalizzare tutte le modifiche al database.

Nel nostro esempio sopra, ciò si ottiene con la seguente dichiarazione:

sql.commit()

Operazione di rollback

Se non sei soddisfatto di una o più modifiche e desideri ripristinarle completamente, utilizza il metodo di rollback. Nel nostro esempio sopra, ciò si ottiene con la seguente dichiarazione:

sql.rollback()

Disconnessione dei database

Per disconnettere la connessione al database, utilizzare il metodo di chiusura.

sql.close()

Durante il processo di sviluppo del software, a volte gli sviluppatori trascorrono molto tempo nella creazione di strutture dati, classi di dominio, XML, layout GUI, flussi di output ecc. Ea volte il codice utilizzato per creare questi requisiti specifici si traduce nella ripetizione dello stesso frammento di codice in molti posti. È qui che entrano in gioco i costruttori di Groovy. Groovy dispone di builder che possono essere utilizzati per creare oggetti e strutture standard. Questi builder fanno risparmiare tempo poiché gli sviluppatori non hanno bisogno di scrivere il proprio codice per creare questi builder. Nel corso di questo capitolo vedremo i diversi builder disponibili in groovy.

Costruttore di oscillazioni

In groovy si possono anche creare interfacce utente grafiche utilizzando i costruttori di swing disponibili in groovy. La classe principale per lo sviluppo di componenti swing è la classe SwingBuilder. Questa classe ha molti metodi per creare componenti grafici come:

  • JFrame - Serve per creare l'elemento del telaio.

  • JTextField - Viene utilizzato per creare il componente textfield.

Diamo un'occhiata a un semplice esempio di come creare un'applicazione Swing utilizzando la classe SwingBuilder. Nell'esempio seguente, puoi vedere i seguenti punti:

  • È necessario importare le classi groovy.swing.SwingBuilder e javax.swing. *.

  • Tutti i componenti visualizzati nell'applicazione Swing fanno parte della classe SwingBuilder.

  • Per il frame stesso, è possibile specificare la posizione iniziale e le dimensioni del frame. È inoltre possibile specificare il titolo della cornice.

  • È necessario impostare la proprietà Visibility su true per visualizzare il frame.

import groovy.swing.SwingBuilder 
import javax.swing.* 

// Create a builder 
def myapp = new SwingBuilder()

// Compose the builder 
def myframe = myapp.frame(title : 'Tutorials Point', location : [200, 200], 
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE {         
      label(text : 'Hello world')
   } 
	
// The following  statement is used for displaying the form 
frame.setVisible(true)

L'output del programma precedente è fornito di seguito. L'output seguente mostra un JFrame insieme a un JLabel con un testo di Hello World.

Diamo un'occhiata al nostro prossimo esempio per creare una schermata di input con caselle di testo. Nell'esempio seguente, vogliamo creare un modulo che abbia caselle di testo per il nome dello studente, l'argomento e il nome della scuola. Nell'esempio seguente, puoi vedere i seguenti punti chiave:

  • Stiamo definendo un layout per i nostri controlli sullo schermo. In questo caso stiamo usando il layout a griglia.
  • Stiamo usando una proprietà di allineamento per le nostre etichette.
  • Stiamo usando il metodo textField per visualizzare le caselle di testo sullo schermo.
import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.*
 
// Create a builder 
def myapp = new SwingBuilder() 

// Compose the builder 
def myframe = myapp.frame(title : 'Tutorials Point', location : [200, 200], 
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE) { 
      panel(layout: new GridLayout(3, 2, 5, 5)) { 
         label(text : 'Student Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10) 
			
         label(text : 'Subject Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10)
			
         label(text : 'School Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10) 
      } 
   } 
	
// The following  statement is used for displaying the form 
myframe.setVisible(true)

L'output del programma di cui sopra è dato di seguito:

Gestori di eventi

Ora diamo un'occhiata ai gestori di eventi. I gestori di eventi vengono utilizzati affinché il pulsante esegua una sorta di elaborazione quando viene premuto un pulsante. Ogni chiamata allo pseudometodo del pulsante include il parametro actionPerformed. Questo rappresenta un blocco di codice presentato come chiusura.

Diamo un'occhiata al nostro prossimo esempio per la creazione di una schermata con 2 pulsanti. Quando uno dei pulsanti viene premuto, viene inviato un messaggio corrispondente allo schermo della console. Nell'esempio seguente, puoi vedere i seguenti punti chiave:

  • Per ogni pulsante definito, stiamo utilizzando il metodo actionPerformed e definendo una chiusura per inviare un output alla console quando si fa clic sul pulsante.

import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.* 

def myapp = new SwingBuilder()
  
def buttonPanel = {
   myapp.panel(constraints : BorderLayout.SOUTH) {
	
      button(text : 'Option A', actionPerformed : {
         println 'Option A chosen'
      })
		
      button(text : 'Option B', actionPerformed : {
         println 'Option B chosen'
      })
   }
}
  
def mainPanel = {
   myapp.panel(layout : new BorderLayout()) {
      label(text : 'Which Option do you want', horizontalAlignment : 
      JLabel.CENTER,
      constraints : BorderLayout.CENTER)
      buttonPanel()
   }
}
  
def myframe = myapp.frame(title : 'Tutorials Point', location : [100, 100],
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE){
      mainPanel()
   }
	
myframe.setVisible(true)

L'output del programma precedente è fornito di seguito. Quando si fa clic su uno dei pulsanti, il messaggio richiesto viene inviato alla schermata del registro della console.

Un'altra variazione dell'esempio precedente consiste nel definire metodi che possono agire come gestori. Nell'esempio seguente stiamo definendo 2 gestori di DisplayA e DisplayB.

import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.* 

def myapp = new SwingBuilder()
  
def DisplayA = {
   println("Option A") 
} 

def DisplayB = {
   println("Option B")
}

def buttonPanel = {
   myapp.panel(constraints : BorderLayout.SOUTH) {
      button(text : 'Option A', actionPerformed : DisplayA) 
      button(text : 'Option B', actionPerformed : DisplayB)
   }
}  

def mainPanel = {
   myapp.panel(layout : new BorderLayout()) {
      label(text : 'Which Option do you want', horizontalAlignment : JLabel.CENTER,
      constraints : BorderLayout.CENTER)
      buttonPanel()
   }
}  

def myframe = myapp.frame(title : 'Tutorials Point', location : [100, 100],
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE) {
      mainPanel()
   } 
	
myframe.setVisible(true)

L'output del programma precedente rimarrebbe lo stesso dell'esempio precedente.

DOM Builder

Il generatore DOM può essere utilizzato per analizzare HTML, XHTML e XML e convertirlo in un albero DOM W3C.

Il seguente esempio mostra come utilizzare il generatore DOM.

String records = '''
   <library>
	
      <Student>
         <StudentName division = 'A'>Joe</StudentName>
         <StudentID>1</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'B'>John</StudentName>
         <StudentID>2</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'C'>Mark</StudentName>
         <StudentID>3</StudentID>
      </Student>
		
   </library>'''
   
def rd = new StringReader(records) 
def doc = groovy.xml.DOMBuilder.parse(rd)

JsonBuilder

JsonBuilder viene utilizzato per creare oggetti di tipo json.

L'esempio seguente mostra come utilizzare il builder Json.

def builder = new groovy.json.JsonBuilder() 

def root = builder.students {
   student {
      studentname 'Joe'
      studentid '1'
		
      Marks(
         Subject1: 10,
         Subject2: 20,
         Subject3:30,
      )
   } 
} 
println(builder.toString());

L'output del programma precedente è fornito di seguito. L'output clearlt mostra che Jsonbuilder è stato in grado di creare l'oggetto json da un insieme strutturato di nodi.

{"students":{"student":{"studentname":"Joe","studentid":"1","Marks":{"Subject1":10,
"S ubject2":20,"Subject3":30}}}}

Il jsonbuilder può anche prendere in un elenco e convertirlo in un oggetto json. Il seguente esempio mostra come questo può essere realizzato.

def builder = new groovy.json.JsonBuilder() 
def lst = builder([1, 2, 3]) 
println(builder.toString());

L'output del programma di cui sopra è fornito di seguito.

[1,2,3]

Il jsonBuilder può essere utilizzato anche per le classi. L'esempio seguente mostra come gli oggetti di una classe possono diventare input per il generatore di json.

def builder = new groovy.json.JsonBuilder() 

class Student {
   String name  
} 

def studentlist = [new Student (name: "Joe"), new Student (name: "Mark"), 
   new Student (name: "John")] 
	
builder studentlist, { Student student ->name student.name} 
println(builder)

L'output del programma di cui sopra è fornito di seguito.

[{"name":"Joe"},{"name":"Mark"},{"name":"John"}]

NodeBuilder

NodeBuilder viene utilizzato per creare alberi nidificati di oggetti Node per la gestione di dati arbitrari. Di seguito è mostrato un esempio di utilizzo di un Nodebuilder.

def nodeBuilder = new NodeBuilder() 

def studentlist = nodeBuilder.userlist {
   user(id: '1', studentname: 'John', Subject: 'Chemistry')
   user(id: '2', studentname: 'Joe', Subject: 'Maths')
   user(id: '3', studentname: 'Mark', Subject: 'Physics') 
} 

println(studentlist)

FileTreeBuilder

FileTreeBuilder è un builder per la generazione di una struttura di directory di file da una specifica. Di seguito è riportato un esempio di come può essere utilizzato FileTreeBuilder.

tmpDir = File.createTempDir() 
def fileTreeBuilder = new FileTreeBuilder(tmpDir) 

fileTreeBuilder.dir('main') {
   dir('submain') {
      dir('Tutorial') {
        file('Sample.txt', 'println "Hello World"')
      }
   } 
}

Dall'esecuzione del codice sopra verrà creato un file chiamato sample.txt nella cartella main / submain / Tutorial. E il file sample.txt avrà il testo di "Hello World".

La shell Groovy nota come groovysh può essere facilmente utilizzata per valutare espressioni groovy, definire classi ed eseguire semplici programmi. La shell della riga di comando viene installata quando Groovy è installato.

Di seguito sono riportate le opzioni della riga di comando disponibili in Groovy:

Parametro della riga di comando Nome e cognome Dettagli
-C --color [= FLAG] Abilita o disabilita l'uso dei colori ANSI
-D --define = NOME = VALORE Definisci una proprietà di sistema
-T --terminal = TYPE Specificare il TIPO di terminale da utilizzare
-V --versione Visualizza la versione
-classpath Specificare dove trovare i file di classe: deve essere il primo argomento
-cp --classpath Alias ​​per "-classpath"
-d - debug --debug Abilita l'output di debug
-e --evaluate = arg Valuta l'opzione pugno all'inizio della sessione interattiva
-h --Aiuto Visualizza questo messaggio di aiuto
-q --silenzioso Elimina l'output superfluo
-v --verbose Abilita output dettagliato

La seguente istantanea mostra un semplice esempio di un'espressione eseguita nella shell Groovy. Nell'esempio seguente stiamo solo stampando "Hello World" nella shell groovy.

Classi e funzioni

È molto facile definire una classe nel prompt dei comandi, creare un nuovo oggetto e invocare un metodo sulla classe. L'esempio seguente mostra come implementarlo. Nell'esempio seguente, stiamo creando una semplice classe Student con un metodo semplice. Nel prompt dei comandi stesso, stiamo creando un oggetto della classe e chiamando il metodo Display.

È molto semplice definire un metodo nel prompt dei comandi e richiamare il metodo. Si noti che il metodo viene definito utilizzando il tipo def. Si noti inoltre che abbiamo incluso un parametro chiamato name che viene quindi sostituito con il valore effettivo quando viene chiamato il metodo Display. Il seguente esempio mostra come questo può essere implementato.

Comandi

La shell ha una serie di comandi differenti, che forniscono un ricco accesso all'ambiente della shell. Di seguito è riportato l'elenco di loro e cosa fanno.

Suor n Comando & smp; Descrizione comando
1

:help

(: h) Visualizza questo messaggio di aiuto

2

?

(:?) Alias ​​di:: help

3

:exit

(: x) Esci dalla shell

4

:quit

(: q) Alias ​​a:: exit

5

import

(: i) Importa una classe nello spazio dei nomi

6

:display

(: d) Visualizza il buffer corrente

7

:clear

(: c) Cancella il buffer e reimposta il contatore dei prompt

8

:show

(: S) Mostra variabili, classi o importazioni

9

:inspect

(: n) Esamina una variabile o l'ultimo risultato con il browser degli oggetti della GUI

10

:purge

(: p) Elimina variabili, classi, importazioni o preferenze

11

:edit

(: e) Modifica il buffer corrente

12

:load

(: l) Carica un file o un URL nel buffer

13

.

(:.) Alias ​​a:: load

14

.save

(: s) Salva il buffer corrente in un file

15

.record

(: r) Registra la sessione corrente in un file

16

:alias

(: a) Crea un alias

17

:set

(: =) Imposta (o elenca) le preferenze

18

:register

(: rc) Registra un nuovo comando con la shell

19

:doc

(: D) Apre una finestra del browser che mostra il documento per l'argomento

20

:history

(: H) Visualizza, gestisci e richiama la cronologia della riga di modifica

L'unità fondamentale di un sistema orientato agli oggetti è la classe. Pertanto il test unitario consiste nel testare all'interno di una classe. L'approccio adottato consiste nel creare un oggetto della classe in prova e utilizzarlo per verificare che i metodi selezionati vengano eseguiti come previsto. Non tutti i metodi possono essere testati, poiché non è sempre pratico testare ogni cosa. Ma i test unitari dovrebbero essere condotti per metodi chiave e critici.

JUnit è un framework di test open source che è lo standard industriale accettato per il test di unità automatizzato del codice Java. Fortunatamente, il framework JUnit può essere facilmente utilizzato per testare le classi Groovy. Tutto ciò che serve è estendere la classe GroovyTestCase che fa parte dell'ambiente Groovy standard. La classe del test case Groovy si basa sul test case Junit.

Scrivere un semplice test case Junit

Supponiamo di avere la seguente classe definita in un file di classe dell'applicazione:

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.name = "Joe";
      mst.ID = 1;
      println(mst.Display())
   } 
} 
 
public class Student {
   String name;
   int ID;
	
   String Display() {
      return name +ID;
   }  
}

L'output del programma di cui sopra è fornito di seguito.

Joe1

E ora supponiamo di voler scrivere un test case per la classe Student. Un tipico caso di test sarebbe simile a quello qui sotto. I seguenti punti devono essere annotati riguardo al seguente codice:

  • La classe del test case estende la classe GroovyTestCase
  • Stiamo utilizzando l'istruzione assert per garantire che il metodo Display restituisca la stringa corretta.
class StudentTest extends GroovyTestCase {
   void testDisplay() {
      def stud = new Student(name : 'Joe', ID : '1')
      def expected = 'Joe1'
      assertToString(stud.Display(), expected)
   }
}

La suite di test Groovy

Normalmente all'aumentare del numero di unit test, diventerebbe difficile continuare a eseguire tutti i casi di test uno per uno. Quindi Groovy fornisce una struttura per creare una suite di test in grado di incapsulare tutti i casi di test in un'unica unità logica. Il codenippet seguente mostra come questo può essere ottenuto. Le seguenti cose dovrebbero essere annotate sul codice:

  • GroovyTestSuite viene utilizzato per incapsulare tutti i casi di test in uno solo.

  • Nell'esempio seguente, supponiamo di avere due file di test case, uno chiamato StudentTest e l'altro è EmployeeTest che contiene tutti i test necessari.

import groovy.util.GroovyTestSuite 
import junit.framework.Test 
import junit.textui.TestRunner 

class AllTests { 
   static Test suite() { 
      def allTests = new GroovyTestSuite() 
      allTests.addTestSuite(StudentTest.class) 
      allTests.addTestSuite(EmployeeTest.class) 
      return allTests 
   } 
} 

TestRunner.run(AllTests.suite())

Il motore dei modelli di Groovy funziona come una stampa unione (l'aggiunta automatica di nomi e indirizzi da un database a lettere e buste per facilitare l'invio di posta, soprattutto pubblicità, a molti indirizzi) ma è molto più generale.

Modelli semplici in stringhe

Se prendi il semplice esempio di seguito, definiamo prima una variabile nome per contenere la stringa "Groovy". Nell'istruzione println, stiamo usando $ symbol per definire un parametro o un modello in cui è possibile inserire un valore.

def name = "Groovy" 
println "This Tutorial is about ${name}"

Se il codice sopra viene eseguito in groovy, verrà mostrato il seguente output. L'output mostra chiaramente che $ name è stato sostituito dal valore assegnato dall'istruzione def.

Motore di modelli semplice

Di seguito è riportato un esempio di SimpleTemplateEngine che consente di utilizzare scriptlet simili a JSP ed espressioni EL nel modello per generare testo parametrizzato. Il motore di modelli consente di associare un elenco di parametri e dei loro valori in modo che possano essere sostituiti nella stringa che ha i segnaposto definiti.

def text ='This Tutorial focuses on $TutorialName. In this tutorial you will learn 

about $Topic'  

def binding = ["TutorialName":"Groovy", "Topic":"Templates"]  
def engine = new groovy.text.SimpleTemplateEngine() 
def template = engine.createTemplate(text).make(binding) 

println template

Se il codice sopra viene eseguito in groovy, verrà mostrato il seguente output.

Utilizziamo ora la funzionalità di creazione dei modelli per un file XML. Come primo passo aggiungiamo il codice seguente a un file chiamato Student.template. Nel file seguente noterai che non abbiamo aggiunto i valori effettivi per gli elementi, ma i segnaposto. Quindi $ name,$is and $oggetto sono tutti messi come segnaposto che dovranno essere sostituiti in fase di esecuzione.

<Student> 
   <name>${name}</name> <ID>${id}</ID> 
   <subject>${subject}</subject> 
</Student>

Ora aggiungiamo il nostro codice di script Groovy per aggiungere la funzionalità che può essere utilizzata per sostituire il modello sopra con i valori effettivi. Le seguenti cose dovrebbero essere annotate sul codice seguente.

  • La mappatura dei segnaposto ai valori effettivi viene eseguita tramite un'associazione e un SimpleTemplateEngine. L'associazione è una mappa con i segnaposto come chiavi e le sostituzioni come valori.

import groovy.text.* 
import java.io.* 

def file = new File("D:/Student.template") 
def binding = ['name' : 'Joe', 'id' : 1, 'subject' : 'Physics']
				  
def engine = new SimpleTemplateEngine() 
def template = engine.createTemplate(file) 
def writable = template.make(binding) 

println writable

Se il codice sopra viene eseguito in groovy, verrà mostrato il seguente output. Dall'output si può vedere che i valori vengono sostituiti con successo nei relativi segnaposto.

<Student> 
   <name>Joe</name> 
   <ID>1</ID> 
   <subject>Physics</subject> 
</Student>

StreamingTemplateEngine

Il motore StreamingTemplateEngine è un altro motore di modelli disponibile in Groovy. Questo è un po 'equivalente al SimpleTemplateEngine, ma crea il modello utilizzando chiusure scrivibili rendendolo più scalabile per modelli di grandi dimensioni. In particolare, questo motore di modelli può gestire stringhe più grandi di 64k.

Di seguito è riportato un esempio di come vengono utilizzati StreamingTemplateEngine:

def text = '''This Tutorial is <% out.print TutorialName %> The Topic name 

is ${TopicName}''' 
def template = new groovy.text.StreamingTemplateEngine().createTemplate(text)
  
def binding = [TutorialName : "Groovy", TopicName  : "Templates",]
String response = template.make(binding) 
println(response)

Se il codice sopra viene eseguito in groovy, verrà mostrato il seguente output.

This Tutorial is Groovy The Topic name is Templates

XMLTemplateEngine

XmlTemplateEngine viene utilizzato negli scenari di creazione di modelli in cui sia l'origine del modello che l'output previsto devono essere XML. I modelli usano il normale${expression} and $notazioni variabili per inserire un'espressione arbitraria nel modello.

Di seguito è riportato un esempio di come viene utilizzato XMLTemplateEngine.

def binding = [StudentName: 'Joe', id: 1, subject: 'Physics'] 
def engine = new groovy.text.XmlTemplateEngine() 

def text = '''\
   <document xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
      <Student>
         <name>${StudentName}</name> <ID>${id}</ID>
         <subject>${subject}</subject>
      </Student>
   </document> 
''' 

def template = engine.createTemplate(text).make(binding) 
println template.toString()

Se il codice sopra viene eseguito in groovy, verrà mostrato il seguente output

Joe
    
    
   1
    
    
   Physics

La programmazione di meta oggetti o MOP può essere utilizzata per invocare metodi dinamicamente e anche creare classi e metodi al volo.

Che cosa significa questo? Consideriamo una classe chiamata Student, che è una specie di classe vuota senza variabili o metodi membri. Supponi di dover invocare le seguenti istruzioni su questa classe.

Def myStudent = new Student() 
myStudent.Name = ”Joe”; 
myStudent.Display()

Ora nella programmazione dei meta oggetti, anche se la classe non ha la variabile membro Nome o il metodo Display (), il codice precedente funzionerà comunque.

Come può funzionare? Bene, perché questo funzioni, è necessario implementare l'interfaccia GroovyInterceptable per agganciarsi al processo di esecuzione di Groovy. Di seguito sono riportati i metodi disponibili per questa interfaccia.

Public interface GroovyInterceptable { 
   Public object invokeMethod(String methodName, Object args) 
   Public object getproperty(String propertyName) 
   Public object setProperty(String propertyName, Object newValue) 
   Public MetaClass getMetaClass() 
   Public void setMetaClass(MetaClass metaClass) 
}

Quindi, nella descrizione dell'interfaccia sopra, supponiamo che se dovessi implementare invokeMethod (), sarebbe chiamato per ogni metodo che esiste o non esiste.

Proprietà mancanti

Quindi diamo un'occhiata a un esempio di come possiamo implementare la programmazione di meta oggetti per le proprietà mancanti. Le seguenti cose chiave dovrebbero essere annotate sul codice seguente.

  • La classe Studente non ha una variabile membro denominata Nome o ID definito.

  • La classe Student implementa l'interfaccia GroovyInterceptable.

  • C'è un parametro chiamato dynamicProps che verrà usato per contenere il valore delle variabili membro che vengono create al volo.

  • I metodi getproperty e setproperty sono stati implementati per ottenere e impostare i valori delle proprietà della classe in fase di esecuzione.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
   }
}

class Student implements GroovyInterceptable { 
   protected dynamicProps=[:]
	
   void setProperty(String pName,val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   } 
}

L'output del codice seguente sarebbe:

Joe 
1

Metodi mancanti

Quindi diamo un'occhiata a un esempio di come possiamo implementare la programmazione di meta oggetti per le proprietà mancanti. Le seguenti cose chiave dovrebbero essere annotate sul seguente codice:

  • La classe Student ora implementa il metodo invokeMethod che viene chiamato indipendentemente dal fatto che il metodo esista o meno.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
}
 
class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   } 
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def invokeMethod(String name, Object args) {
      return "called invokeMethod $name $args"
   }
}

L'output del codice seguente dovrebbe essere mostrato di seguito. Si noti che non vi è alcun errore di eccezione del metodo mancante anche se il metodo Display non esiste.

Joe 
1

Metaclasse

Questa funzionalità è correlata all'implementazione di MetaClass. Nell'implementazione predefinita puoi accedere ai campi senza richiamare i loro getter e setter. L'esempio seguente mostra come utilizzando la funzione metaClass siamo in grado di modificare il valore delle variabili private nella classe.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      println mst.getName()
      mst.metaClass.setAttribute(mst, 'name', 'Mark')
      println mst.getName()
   } 
} 

class Student {
   private String name = "Joe";
	
   public String getName() {
      return this.name;
   } 
}

L'output del codice seguente sarebbe:

Joe 
Mark

Metodo mancante

Groovy supporta il concetto di methodMissing. Questo metodo differisce da invokeMethod in quanto viene richiamato solo in caso di invio di un metodo non riuscito, quando non è possibile trovare alcun metodo per il nome e / o gli argomenti forniti. L'esempio seguente mostra come utilizzare methodMissing.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
} 

class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def methodMissing(String name, def args) {         
      println "Missing method"
   }  
}

L'output del codice seguente sarebbe:

Joe 
1 
Missing method