Groovy - Guia rápido

Groovy é uma linguagem orientada a objetos baseada na plataforma Java. Groovy 1.0 foi lançado em 2 de janeiro de 2007 com Groovy 2.4 como a versão principal atual. Groovy é distribuído por meio da Licença Apache v 2.0.

Recursos do Groovy

O Groovy tem os seguintes recursos -

  • Suporte para tipagem estática e dinâmica.
  • Suporte para sobrecarga do operador.
  • Sintaxe nativa para listas e matrizes associativas.
  • Suporte nativo para expressões regulares.
  • Suporte nativo para várias linguagens de marcação, como XML e HTML.
  • Groovy é simples para desenvolvedores Java, pois a sintaxe para Java e Groovy são muito semelhantes.
  • Você pode usar bibliotecas Java existentes.
  • Groovy estende o java.lang.Object.

O site oficial do Groovy é http://www.groovy-lang.org/

Existem várias maneiras de obter a configuração do ambiente Groovy.

Binary download and installation- Acesse o link www.groovy-lang.org/download.html para obter a seção do Windows Installer. Clique nesta opção para iniciar o download do instalador Groovy.

Depois de iniciar o instalador, siga as etapas abaixo para completar a instalação.

Step 1 - Selecione o instalador de idioma.

Step 2 - Clique no botão Avançar na próxima tela.

Step 3 - Clique no botão 'Concordo'.

Step 4 - Aceite os componentes padrão e clique no botão Avançar.

Step 5 - Escolha a pasta de destino apropriada e clique no botão Avançar.

Step 6 - Clique no botão Instalar para iniciar a instalação.

Step 7 - Depois de concluída a instalação, clique no botão Avançar para iniciar a configuração.

Step 8 - Escolha as opções padrão e clique no botão Avançar.

Step 9 - Aceite as associações de arquivo padrão e clique no botão Avançar.

Step 10 - Clique no botão Concluir para concluir a instalação.

Depois que as etapas acima forem seguidas, você poderá iniciar o shell groovy que faz parte da instalação do Groovy que ajuda a testar nossos diferentes aspectos da linguagem Groovy sem a necessidade de ter um ambiente de desenvolvimento integrado completo para Groovy. Isso pode ser feito executando o comando groovysh no prompt de comando.

Se você quiser incluir os binários incríveis como parte de sua compilação do maven ou gradle, você pode adicionar as seguintes linhas

Gradle

'org.codehaus.groovy:groovy:2.4.5'

Maven

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

Para entender a sintaxe básica do Groovy, vamos primeiro examinar um programa simples Hello World.

Criando seu primeiro programa Hello World

Criar seu primeiro programa hello world é tão simples quanto inserir a seguinte linha de código -

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

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World

Declaração de importação em Groovy

A instrução import pode ser usada para importar a funcionalidade de outras bibliotecas que podem ser usadas em seu código. Isso é feito usando oimport palavra-chave.

O exemplo a seguir mostra como usar uma importação simples da classe MarkupBuilder, que provavelmente é uma das classes mais usadas para criar marcação HTML ou XML.

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

Por padrão, o Groovy inclui as seguintes bibliotecas em seu código, portanto, você não precisa importá-las explicitamente.

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

Tokens em Groovy

Um token é uma palavra-chave, um identificador, uma constante, um literal de string ou um símbolo.

println(“Hello World”);

Na linha de código acima, há dois tokens, o primeiro é a palavra-chave println e o próximo é a string literal de “Hello World”.

Comentários no Groovy

Os comentários são usados ​​para documentar seu código. Os comentários no Groovy podem ser de linha única ou multilinha.

Comentários de linha única são identificados usando // em qualquer posição na linha. Um exemplo é mostrado abaixo -

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

Os comentários de várias linhas são identificados com / * no início e * / para identificar o final do comentário de várias linhas.

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

Ponto e vírgula

Ao contrário da linguagem de programação Java, não é obrigatório ter ponto-e-vírgula após o final de cada instrução, é opcional.

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

Se você executar o programa acima, ambas as instruções no método principal não geram nenhum erro.

Identificadores

Identificadores são usados ​​para definir variáveis, funções ou outras variáveis ​​definidas pelo usuário. Os identificadores começam com uma letra, um dólar ou um sublinhado. Eles não podem começar com um número. Aqui estão alguns exemplos de identificadores válidos -

def employeename 
def student1 
def student_name

Onde def é uma palavra-chave usada no Groovy para definir um identificador.

Aqui está um exemplo de código de como um identificador pode ser usado em nosso programa 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'); 
   }
}

No exemplo acima, a variável x é usado como um identificador.

Palavras-chave

Palavras-chave como o nome sugere são palavras especiais que são reservadas na linguagem de programação Groovy. A tabela a seguir lista as palavras-chave definidas no Groovy.

Como afirmar pausa caso
pegar classe const continuar
def padrão Faz outro
enum estende falso Finalmente
para vamos para E se implementos
importar dentro instancia de interface
Novo puxar pacote Retorna
super interruptor esta lançar
lança traço verdadeiro experimentar
enquanto

Espaços em branco

Espaço em branco é o termo usado em uma linguagem de programação como Java e Groovy para descrever espaços em branco, guias, caracteres de nova linha e comentários. O espaço em branco separa uma parte de uma instrução de outra e permite ao compilador identificar onde um elemento em uma instrução.

Por exemplo, no exemplo de código a seguir, há um espaço em branco entre a palavra-chave defe a variável x. Isso é para que o compilador saiba quedef é a palavra-chave que precisa ser usada e que x deve ser o nome da variável que precisa ser definida.

def x = 5;

Literais

Um literal é uma notação para representar um valor fixo em groovy. A linguagem groovy possui notações para inteiros, números de ponto flutuante, caracteres e strings. Aqui estão alguns dos exemplos de literais na linguagem de programação Groovy -

12 
1.45 
‘a’ 
“aa”

Em qualquer linguagem de programação, você precisa usar várias variáveis ​​para armazenar vários tipos de informações. As variáveis ​​nada mais são do que locais de memória reservados para armazenar valores. Isso significa que, ao criar uma variável, você reserva algum espaço na memória para armazenar o valor associado à variável.

Você pode gostar de armazenar informações de vários tipos de dados como string, caractere, caractere largo, inteiro, ponto flutuante, Booleano, etc. Com base no tipo de dados de uma variável, o sistema operacional aloca memória e decide o que pode ser armazenado no reservado memória.

Tipos de dados integrados

O Groovy oferece uma ampla variedade de tipos de dados integrados. A seguir está uma lista de tipos de dados que são definidos no Groovy -

  • byte- Isso é usado para representar um valor de byte. Um exemplo é 2.

  • short- Isso é usado para representar um número curto. Um exemplo é 10.

  • int- Isso é usado para representar números inteiros. Um exemplo é 1234.

  • long- Isso é usado para representar um número longo. Um exemplo é 10000090.

  • float- Isso é usado para representar números de ponto flutuante de 32 bits. Um exemplo é 12,34.

  • double- Isso é usado para representar números de ponto flutuante de 64 bits que são representações de números decimais mais longos que podem ser necessários às vezes. Um exemplo é 12.3456565.

  • char- Isso define um único literal de caractere. Um exemplo é 'a'.

  • Boolean - Isso representa um valor booleano que pode ser verdadeiro ou falso.

  • String - Estes são literais de texto que são representados em the formde cadeia de personagens. Por exemplo, “Hello World”.

Valores limite

A tabela a seguir mostra os valores máximos permitidos para os literais numéricos e decimais.

byte -128 a 127
baixo -32.768 a 32.767
int -2.147.483.648 a 2.147.483.647
grandes -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807
flutuador 1.40129846432481707e-45 a 3.40282346638528860e + 38
em dobro 4.94065645841246544e-324d a 1.79769313486231570e + 308d

Classe Numérica

Tipos Além dos tipos primitivos, os seguintes tipos de objetos (às vezes chamados de tipos de invólucro) são permitidos -

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

Além disso, as seguintes classes podem ser usadas para suportar aritmética de precisão arbitrária -

Nome Descrição Exemplo
java.math.BigInteger Números inteiros assinados de precisão arbitrária imutáveis 30g
java.math.BigDecimal Números decimais assinados de precisão arbitrária imutável 3,5g

O exemplo de código a seguir mostra como os diferentes tipos de dados integrados podem ser usados ​​-

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 executamos o programa acima, obteremos o seguinte resultado -

5 
100 
10.56 
1.05E41 
30 
3.5

As variáveis ​​no Groovy podem ser definidas de duas maneiras - usando o native syntax para o tipo de dados ou o próximo é by using the def keyword. Para definições de variáveis, é obrigatório fornecer um nome de tipo explicitamente ou usar "def" em substituição. Isso é exigido pelo analisador Groovy.

Existem os seguintes tipos básicos de variáveis ​​no Groovy, conforme explicado no capítulo anterior -

  • byte- Isso é usado para representar um valor de byte. Um exemplo é 2.

  • short- Isso é usado para representar um número curto. Um exemplo é 10.

  • int- Isso é usado para representar números inteiros. Um exemplo é 1234.

  • long- Isso é usado para representar um número longo. Um exemplo é 10000090.

  • float- Isso é usado para representar números de ponto flutuante de 32 bits. Um exemplo é 12,34.

  • double- Isso é usado para representar números de ponto flutuante de 64 bits que são representações de números decimais mais longos que podem ser necessários às vezes. Um exemplo é 12.3456565.

  • char- Isso define um único literal de caractere. Um exemplo é 'a'.

  • Boolean - Isso representa um valor booleano que pode ser verdadeiro ou falso.

  • String - Estes são literais de texto que são representados em the formde cadeia de personagens. Por exemplo, “Hello World”.

O Groovy também permite tipos adicionais de variáveis, como arrays, estruturas e classes, que veremos nos capítulos subsequentes.

Declarações de variáveis

Uma declaração de variável informa ao compilador onde e quanto criar o armazenamento para a variável.

A seguir está um exemplo de declaração de variável -

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 executamos o programa acima, obteremos o seguinte resultado -

Hello

Nomeando Variáveis

O nome de uma variável pode ser composto de letras, dígitos e o caractere de sublinhado. Deve começar com uma letra ou um sublinhado. Letras maiúsculas e minúsculas são distintas porque Groovy, assim como Java, é uma linguagem de programação que diferencia maiúsculas de minúsculas.

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 executamos o programa acima, obteremos o seguinte resultado -

5 
6 
Joe

Nós podemos ver isso x e X são duas variáveis ​​diferentes por causa da distinção entre maiúsculas e minúsculas e, no terceiro caso, podemos ver que _Name começa com um sublinhado.

Variáveis ​​de impressão

Você pode imprimir o valor atual de uma variável com a função println. O exemplo a seguir mostra como isso pode ser alcançado.

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 executamos o programa acima, obteremos o seguinte resultado -

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

Um operador é um símbolo que informa ao compilador para executar manipulações matemáticas ou lógicas específicas.

Groovy tem os seguintes tipos de operadores -

  • Operadores aritméticos
  • Operadores relacionais
  • Operadores lógicos
  • Operadores bit a bit
  • Operadores de atribuição

Operadores aritméticos

A linguagem Groovy suporta os operadores aritméticos normais como qualquer outra linguagem. A seguir estão os operadores aritméticos disponíveis no Groovy -

Mostrar exemplo

Operador Descrição Exemplo
+ Adição de dois operandos 1 + 2 dará 3
- Subtrai o segundo operando do primeiro 2 - 1 dará 1
* Multiplicação de ambos os operandos 2 * 2 dará 4
/ Divisão do numerador por denominador 3/2 dará 1,5
% Operador de Módulo e o restante após uma divisão inteiro / flutuante 3% 2 dará 1
++ Operadores incrementais usados ​​para incrementar o valor de um operando em 1

int x = 5;

x ++;

x dará 6

- Operadores incrementais usados ​​para diminuir o valor de um operando em 1

int x = 5;

x--;

x dará 4

Operadores relacionais

Operadores relacionais permitem a comparação de objetos. A seguir estão os operadores relacionais disponíveis no Groovy -

Mostrar exemplo

Operador Descrição Exemplo
== Testa a igualdade entre dois objetos 2 == 2 dará verdadeiro
! = Testa a diferença entre dois objetos 3! = 2 dará verdadeiro
< Verifica se os objetos à esquerda são menores que o operando à direita. 2 <3 dará verdadeiro
<= Verifica se os objetos à esquerda são menores ou iguais ao operando à direita. 2 <= 3 dará verdadeiro
> Verifica se os objetos à esquerda são maiores que o operando à direita. 3> 2 dará verdadeiro
> = Verifica se os objetos à esquerda são maiores ou iguais ao operando à direita. 3> = 2 dará verdadeiro

Operadores lógicos

Operadores lógicos são usados ​​para avaliar expressões booleanas. A seguir estão os operadores lógicos disponíveis no Groovy -

Mostrar exemplo

Operador Descrição Exemplo
&& Este é o operador lógico “e” verdadeiro && verdadeiro dará verdadeiro
|| Este é o operador lógico “ou” verdade || verdadeiro dará verdadeiro
! Este é o operador lógico “não” ! falso dará verdadeiro

Operadores bit a bit

O Groovy fornece quatro operadores bit a bit. A seguir estão os operadores bit a bit disponíveis no Groovy -

Mostrar exemplo

Sr. Não Operador e descrição
1

&

Este é o operador bit a bit “e”

2

|

Este é o operador bit a bit “ou”

3

^

Este é o bit a bit “xor” ou Exclusivo ou operador

4

~

Este é o operador de negação bit a bit

Aqui está a tabela verdade mostrando esses operadores.

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

Operadores de atribuição

A linguagem Groovy também fornece operadores de atribuição. A seguir estão os operadores de atribuição disponíveis no Groovy -

Mostrar exemplo

Operador Descrição Exemplo
+ = Isso adiciona o operando direito ao operando esquerdo e atribui o resultado ao operando esquerdo.

def A = 5

A + = 3

A saída será 8

- = Isso subtrai o operando direito do operando esquerdo e atribui o resultado ao operando esquerdo

def A = 5

A- = 3

A saída será 2

* = Isso multiplica o operando direito com o operando esquerdo e atribui o resultado ao operando esquerdo

def A = 5

A * = 3

A produção será de 15

/ = Isso divide o operando esquerdo com o operando direito e atribui o resultado ao operando esquerdo

def A = 6

A / = 3

A saída será 2

% = Isso leva o módulo usando dois operandos e atribui o resultado ao operando esquerdo

def A = 5

A% = 3

A saída será 2

Operadores de alcance

O Groovy apóia o conceito de intervalos e fornece uma notação de operadores de intervalo com a ajuda da notação ... Um exemplo simples do operador de alcance é fornecido abaixo.

def range = 0..5

Isso apenas define um intervalo simples de inteiros, armazenado em uma variável local chamada intervalo com um limite inferior de 0 e um limite superior de 5.

O fragmento de código a seguir mostra como os vários operadores podem ser usados.

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

Quando executamos o programa acima, obteremos o seguinte resultado -

De println declaração, você pode ver que toda a gama de números que são definidos na declaração de intervalo são exibidos.

A instrução get é usada para obter um objeto do intervalo definido que leva um valor de índice como parâmetro.

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

operador precedente

A tabela a seguir lista todos os operadores bacanas em ordem de precedência.

Sr. Não Operadores e nomes
1

++ -- + -

pré incremento / decremento, mais unário, menos unário

2

* / %

multiplicar, div, módulo

3

+ -

adição subtração

4

== != <=>

igual, não igual, comparar com

5

&

binário / bit a bit e

6

^

xor binário / bit a bit

7

|

binário / bit a bit ou

8

&&

lógico e

9

||

lógico ou

10

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

Vários operadores de atribuição

Até agora, vimos instruções que foram executadas uma após a outra de maneira sequencial. Além disso, as instruções são fornecidas no Groovy para alterar o fluxo de controle na lógica de um programa. Eles são então classificados em declarações de fluxo de controle que veremos em detalhes.

S.No. Declarações e descrição
1 Declaração While

A instrução while é executada avaliando primeiro a expressão da condição (um valor booleano) e, se o resultado for verdadeiro, as instruções no loop while são executadas.

2 para declaração

A instrução for é usada para iterar por meio de um conjunto de valores.

3 declaração for-in

A instrução for-in é usada para iterar por meio de um conjunto de valores.

Declarações de controle de loop

S.No. Declarações e descrição
1 Declaração de quebra

A instrução break é usada para alterar o fluxo de controle dentro de loops e instruções switch.

2 Continue Statement

A instrução continue complementa a instrução break. Seu uso é restrito a loops while e for.

As estruturas de tomada de decisão requerem que o programador especifique uma ou mais condições a serem avaliadas ou testadas pelo programa, junto com uma instrução ou instruções a serem executadas se a condição for determinada como truee, opcionalmente, outras instruções a serem executadas se a condição for determinada como false.

Sr. Não. Declarações e descrição
1 declaração if

O funcionamento geral desta instrução é que primeiro uma condição é avaliada na instrução if. Se a condição for verdadeira, ele executa as instruções.

2 Declaração if / else

O funcionamento geral desta instrução é que primeiro uma condição é avaliada na instrução if. Se a condição for verdadeira, ele executa as instruções a partir de então, para antes da condição else e sai do loop. Se a condição for falsa, ele então executa as instruções no bloco de instruções else e sai do loop.

3 Declaração aninhada If

Às vezes, é necessário ter várias instruções if incorporadas umas às outras.

4 Declaração de mudança

Às vezes, a instrução if-else aninhada é tão comum e usada com tanta frequência que uma instrução mais fácil foi projetada, chamada instrução switch.

5 Instrução de switch aninhada

Também é possível ter um conjunto aninhado de instruções switch.

Um método em Groovy é definido com um tipo de retorno ou com o defpalavra-chave. Os métodos podem receber qualquer número de argumentos. Não é necessário que os tipos sejam definidos explicitamente ao definir os argumentos. Modificadores como público, privado e protegido podem ser adicionados. Por padrão, se nenhum modificador de visibilidade for fornecido, o método é público.

O tipo mais simples de método é aquele sem parâmetros como o mostrado abaixo -

def methodName() { 
   //Method code 
}

A seguir está um exemplo de método simples

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();
   } 
}

No exemplo acima, DisplayName é um método simples que consiste em duas instruções println que são usadas para enviar algum texto para o console. Em nosso método principal estático, estamos apenas chamando o método DisplayName. A saída do método acima seria -

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

Parâmetros do Método

Um método é geralmente mais útil se seu comportamento é determinado pelo valor de um ou mais parâmetros. Podemos transferir valores para o método chamado usando os parâmetros do método. Observe que os nomes dos parâmetros devem ser diferentes uns dos outros.

O tipo mais simples de método com parâmetros como o mostrado abaixo -

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

A seguir está um exemplo de método simples com parâmetros

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

Neste exemplo, estamos criando um método de soma com 2 parâmetros, a e b. Ambos os parâmetros são do tipoint. Em seguida, estamos chamando o método de soma de nosso método principal e passando os valores para as variáveisa e b.

A saída do método acima seria o valor 15.

Parâmetros padrão

Também há uma provisão no Groovy para especificar valores padrão para parâmetros dentro de métodos. Se nenhum valor for passado ao método para os parâmetros, os valores padrão serão usados. Se forem usados ​​parâmetros não padrão e padrão, então deve-se observar que os parâmetros padrão devem ser definidos no final da lista de parâmetros.

A seguir está um exemplo de método simples com parâmetros -

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

Vejamos o mesmo exemplo que vimos antes para a adição de dois números e criar um método que tem um parâmetro padrão e outro não padrão -

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

Neste exemplo, estamos criando um método de soma com dois parâmetros, a e b. Ambos os parâmetros são do tipo int. A diferença entre este exemplo e o exemplo anterior é que, neste caso, estamos especificando um valor padrão parab como 5. Então, quando chamamos o método sum do nosso método principal, temos a opção de apenas passar um valor que é 6 e este será atribuído ao parâmetro a dentro do sum método.

A saída do método acima seria o valor 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);
   } 
}

Também podemos chamar o método de soma passando 2 valores, em nosso exemplo acima estamos passando 2 valores de 6. O segundo valor de 6 irá substituir o valor padrão que é atribuído ao parâmetro b.

A saída do método acima seria o valor 12.

Valores de retorno do método

Os métodos também podem retornar valores ao programa de chamada. Isso é necessário na linguagem de programação moderna, em que um método faz algum tipo de cálculo e retorna o valor desejado para o método de chamada.

A seguir está um exemplo de método simples com um valor de retorno.

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

Em nosso exemplo acima, observe que, desta vez, estamos especificando um tipo de retorno para o nosso método sum, que é do tipo int. No método, estamos usando a instrução return para enviar o valor da soma ao programa principal de chamada. Uma vez que o valor do método agora está disponível para o método principal, estamos usando oprintln função para exibir o valor no console.

A saída do método acima seria o valor 11.

Métodos de instância

Os métodos são normalmente implementados dentro de classes dentro do Groovy, assim como a linguagem Java. Uma classe nada mais é que um projeto ou modelo para a criação de diferentes objetos que definem suas propriedades e comportamentos. Os objetos de classe exibem as propriedades e comportamentos definidos por sua classe. Portanto, os comportamentos são definidos criando métodos dentro da classe.

Veremos as classes com mais detalhes em um capítulo posterior, mas a seguir está um exemplo de implementação de método em uma classe. Em nossos exemplos anteriores, definimos nosso método como métodos estáticos, o que significa que poderíamos acessar esses métodos diretamente da classe. O próximo exemplo de métodos são os métodos de instância em que os métodos são acessados ​​criando objetos da classe. Mais uma vez, veremos as classes em um capítulo posterior, por enquanto demonstraremos como usar os métodos.

A seguir está um exemplo de como os métodos podem ser implementados.

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()); 
   } 
}

Em nosso exemplo acima, observe que, desta vez, não estamos especificando nenhum atributo estático para nossos métodos de classe. Em nossa função principal, estamos realmente criando uma instância da classe Example e, em seguida, chamando o método do objeto 'ex'.

A saída do método acima seria o valor 100.

Nomes de parâmetros locais e externos

Groovy fornece a facilidade, assim como o java, de ter parâmetros locais e globais. No exemplo a seguir,lx é um parâmetro local que tem um escopo apenas dentro da função de getX() e xé uma propriedade global que pode ser acessada dentro de toda a classe Exemplo. Se tentarmos acessar a variávellx fora do getX() função, obteremos um erro.

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 executamos o programa acima, obteremos o seguinte resultado.

200 
100

este método para propriedades

Assim como em Java, o groovy pode acessar seus membros de instância usando o thispalavra-chave. O exemplo a seguir mostra como quando usamos a instruçãothis.x, ele se refere à sua instância e define o valor de x adequadamente.

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 executarmos o programa acima, obteremos o resultado de 200 impresso no console.

O Groovy fornece vários métodos auxiliares ao trabalhar com E / S. O Groovy fornece classes mais fáceis para fornecer as seguintes funcionalidades para arquivos.

  • Lendo arquivos
  • Gravando em arquivos
  • Percorrendo árvores de arquivos
  • Ler e gravar objetos de dados em arquivos

Além disso, você sempre pode usar as classes Java normais listadas abaixo para operações de E / S de arquivo.

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

Lendo arquivos

O exemplo a seguir produzirá todas as linhas de um arquivo de texto no Groovy. O métodoeachLine está embutido na classe File no Groovy com o propósito de garantir que cada linha do arquivo de texto seja lida.

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

A classe File é usada para instanciar um novo objeto que leva o nome do arquivo como parâmetro. Ele então pega a função de eachLine, coloca-a em uma variável chamada line e a imprime de acordo.

Se o arquivo contiver as seguintes linhas, elas serão impressas.

line : Example1
line : Example2

Lendo o conteúdo de um arquivo como uma string inteira

Se você deseja obter todo o conteúdo do arquivo como uma string, pode usar a propriedade text da classe do arquivo. O exemplo a seguir mostra como isso pode ser feito.

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

Se o arquivo contiver as seguintes linhas, elas serão impressas.

line : Example1 
line : Example2

Escrevendo em arquivos

Se você deseja gravar em arquivos, você precisa usar a classe de gravador para enviar texto para um arquivo. O exemplo a seguir mostra como isso pode ser feito.

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 você abrir o arquivo Example.txt, verá as palavras “Hello World” impressas no arquivo.

Obtendo o tamanho de um arquivo

Se você deseja obter o tamanho do arquivo, pode-se usar a propriedade length da classe de arquivo para obter o tamanho do arquivo. O exemplo a seguir mostra como isso pode ser feito.

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

O código acima mostraria o tamanho do arquivo em bytes.

Testando se um arquivo é um diretório

Se você quiser ver se um caminho é um arquivo ou diretório, pode-se usar o isFile e isDirectoryopção da classe Arquivo. O exemplo a seguir mostra como isso pode ser feito.

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

O código acima mostraria a seguinte saída -

File? false 
Directory? True

Criação de um diretório

Se você deseja criar um novo diretório, você pode usar o mkdirfunção da classe File. O exemplo a seguir mostra como isso pode ser feito.

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

O diretório E: \ Directory será criado se não existir.

Excluindo um Arquivo

Se você deseja excluir um arquivo, pode usar a função de exclusão da classe Arquivo. O exemplo a seguir mostra como isso pode ser feito.

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

O arquivo será excluído se existir.

Copiando arquivos

O Groovy também oferece a funcionalidade de copiar o conteúdo de um arquivo para outro. O exemplo a seguir mostra como isso pode ser feito.

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

O arquivo Example1.txt será criado e todo o conteúdo do arquivo Example.txt será copiado para este arquivo.

Obtendo o conteúdo do diretório

O Groovy também fornece a funcionalidade de listar as unidades e arquivos em uma unidade.

O exemplo a seguir mostra como as unidades em uma máquina podem ser exibidas usando o listRoots função da classe File.

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

Dependendo das unidades disponíveis em sua máquina, a saída pode variar. Em uma máquina padrão, a saída seria semelhante à seguinte -

C:\ 
D:\

O exemplo a seguir mostra como listar os arquivos em um diretório específico usando o eachFile função da classe File.

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

A saída exibiria todos os arquivos no diretório E: \ Temp

Se você deseja exibir recursivamente todos os arquivos em um diretório e seus subdiretórios, use o eachFileRecursefunção da classe File. O exemplo a seguir mostra como isso pode ser feito.

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

A saída exibiria todos os arquivos no diretório E: \ Temp e em seus subdiretórios, se existirem.

Groovy é uma linguagem tipada “opcionalmente”, e essa distinção é importante para a compreensão dos fundamentos da linguagem. Quando comparado ao Java, que é uma linguagem de tipagem “forte”, na qual o compilador conhece todos os tipos de cada variável e pode entender e honrar contratos em tempo de compilação. Isso significa que as chamadas de método podem ser determinadas em tempo de compilação.

Ao escrever código em Groovy, os desenvolvedores têm a flexibilidade de fornecer um tipo ou não. Isso pode oferecer alguma simplicidade na implementação e, quando aproveitado corretamente, pode atender seu aplicativo de maneira robusta e dinâmica.

No Groovy, a digitação opcional é feita por meio da palavra-chave 'def'. A seguir está um exemplo do uso dodef método -

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); 
   } 
}

No programa acima, podemos ver que não declaramos as variáveis ​​individuais como Integer, float, double ou string, embora contenham esses tipos de valores.

Quando executamos o programa acima, obteremos o seguinte resultado -

100 
100.10 
100.101
HelloWorld

A digitação opcional pode ser um utilitário poderoso durante o desenvolvimento, mas pode levar a problemas de manutenção durante os estágios posteriores de desenvolvimento, quando o código se torna muito vasto e complexo.

Para entender como você pode utilizar a digitação opcional no Groovy sem colocar sua base de código em uma bagunça insuportável, é melhor abraçar a filosofia de “digitação de pato” em seus aplicativos.

Se reescrevermos o código acima usando digitação duck, ele se parecerá com o dado abaixo. Os nomes das variáveis ​​recebem nomes que se assemelham mais frequentemente ao tipo que representam, o que torna o código mais compreensível.

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); 
   } 
}

No Groovy, os números são na verdade representados como objetos, sendo todos eles uma instância da classe Integer. Para fazer um objeto fazer algo, precisamos invocar um dos métodos declarados em sua classe.

Groovy suporta números inteiros e de ponto flutuante.

  • Um número inteiro é um valor que não inclui uma fração.
  • Um número de ponto flutuante é um valor decimal que inclui uma fração decimal.

Um exemplo de números no Groovy é mostrado abaixo -

Integer x = 5; 
Float y = 1.25;

Onde x é do tipo Inteiro e y é o flutuador.

A razão pela qual os números em groovy são definidos como objetos é geralmente porque existem requisitos para executar operações em números. O conceito de fornecer uma classe sobre tipos primitivos é conhecido como classes de invólucro.

Por padrão, as seguintes classes de wrapper são fornecidas no Groovy.

O objeto da classe wrapper contém ou envolve seu respectivo tipo de dados primitivo. O processo de conversão de tipos de dados primitivos em objetos é chamado de boxing e é cuidado pelo compilador. O processo de conversão do objeto de volta ao seu tipo primitivo correspondente é denominado unboxing.

Exemplo

A seguir está um exemplo de boxing 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);
   }
}

A saída do programa acima seria 15. No exemplo acima, os valores de 5, 10 e 0 são primeiro encaixotados nas variáveis ​​inteiras x, y e z de acordo. E então, quando a adição de x e y é realizada, os valores são desempacotados de seus tipos Inteiros.

Métodos Numéricos

Como os Números no Groovy são representados como classes, a seguir está a lista de métodos disponíveis.

S.No. Métodos e Descrição
1 xxxValue ()

Este método assume o Número como parâmetro e retorna um tipo primitivo baseado no método que é invocado.

2 comparado a()

O método compareTo é usar comparar um número contra outro. Isso é útil se você deseja comparar o valor dos números.

3 é igual a()

O método determina se o objeto Number que invoca o método é igual ao objeto que é passado como argumento.

4 valor de()

O método valueOf retorna o objeto Number relevante contendo o valor do argumento passado.

5 para sequenciar()

O método é usado para obter um objeto String que representa o valor do objeto Number.

6 parseInt ()

Este método é usado para obter o tipo de dados primitivo de uma determinada String. parseXxx () é um método estático e pode ter um ou dois argumentos.

7 abdômen()

O método fornece o valor absoluto do argumento. O argumento pode ser int, float, long, double, short, byte.

8 ceil ()

O método ceil fornece o menor inteiro maior ou igual ao argumento.

9 chão()

O método floor fornece o maior número inteiro menor ou igual ao argumento.

10 rint ()

O método rint retorna o inteiro que está mais próximo do valor do argumento.

11 volta()

O método round retorna o mais próximo long ou int, conforme fornecido pelo tipo de retorno do método.

12 min ()

O método fornece o menor dos dois argumentos. O argumento pode ser int, float, long, double.

13 max ()

O método fornece o máximo dos dois argumentos. O argumento pode ser int, float, long, double.

14 exp ()

O método retorna a base dos logaritmos naturais, e, para a potência do argumento.

15 registro()

O método retorna o logaritmo natural do argumento.

16 Pancada()

O método retorna o valor do primeiro argumento elevado à potência do segundo argumento.

17 sqrt ()

O método retorna a raiz quadrada do argumento.

18 pecado()

O método retorna o seno do valor duplo especificado.

19 cos ()

O método retorna o cosseno do valor duplo especificado.

20 bronzeado()

O método retorna a tangente do valor duplo especificado.

21 como em()

O método retorna o arco seno do valor duplo especificado.

22 acos ()

O método retorna o arco-cosseno do valor duplo especificado.

23 numa()

O método retorna o arco tangente do valor duplo especificado.

24 atan2 ()

O método converte coordenadas retangulares (x, y) em coordenadas polares (r, theta) e retorna theta.

25 toDegrees ()

O método converte o valor do argumento em graus.

26 radiano()

O método converte o valor do argumento em radianos.

27 aleatória()

O método é usado para gerar um número aleatório entre 0,0 e 1,0. O intervalo é: 0,0 = <Math.random <1,0. Diferentes intervalos podem ser alcançados usando aritmética.

Um literal String é construído em Groovy colocando o texto da string entre aspas.

Groovy oferece uma variedade de maneiras de denotar um literal String. Strings em Groovy podem ser colocadas entre aspas simples ('), aspas duplas (“) ou aspas triplas (“ ””). Além disso, uma String Groovy entre aspas triplas pode abranger várias linhas.

A seguir está um exemplo do uso de strings no 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 executamos o programa acima, obteremos o seguinte resultado -

Hello Single 
Hello Double 
'Hello TripleMultiple lines'

Indexação de String

Strings no Groovy são sequências ordenadas de caracteres. O caractere individual em uma string pode ser acessado por sua posição. Isso é dado por uma posição de índice.

Índices de string começam em zero e terminam em um a menos que o comprimento da string. Groovy também permite que índices negativos façam uma contagem regressiva a partir do final da string.

A seguir está um exemplo do uso de indexação de string no 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 executamos o programa acima, obteremos o seguinte resultado -

o 
d 
el 
oll

Operações básicas de string

Primeiro, vamos aprender as operações básicas com cordas no groovy. Eles são fornecidos abaixo.

S.No. Operação e descrição da string
1 Concatenação de duas strings

A concatenação de strings pode ser feita pelo simples operador '+'.

2 String Repetição

A repetição de strings pode ser feita pelo simples operador '*'.

3 Comprimento da corda

O comprimento da string determinado pelo método length () da string.

Métodos de String

Aqui está a lista de métodos suportados pela classe String.

S.No. Métodos e Descrição
1 Centro()

Retorna uma nova String de comprimento numberOfChars consistindo no destinatário preenchido à esquerda e à direita com caracteres de espaço.

2 compareToIgnoreCase ()

Compara duas strings lexicograficamente, ignorando diferenças entre maiúsculas e minúsculas.

3 concat ()

Concatena a String especificada ao final desta String.

4 eachMatch ()

Processa cada grupo regex (consulte a próxima seção) substring correspondente da String fornecida.

5 termina com()

Testa se esta string termina com o sufixo especificado.

6 equalsIgnoreCase ()

Compara esta String com outra String, ignorando as considerações de caso.

7 getAt ()

Ele retorna o valor da string na posição do índice

8 índice de()

Retorna o índice dentro desta String da primeira ocorrência da substring especificada.

9 partidas()

Ele mostra se uma String corresponde à expressão regular fornecida.

10 menos()

Remove a parte do valor da String.

11 Próximo()

Este método é chamado pelo operador ++ para a classe String. Ele incrementa o último caractere na String fornecida.

12 padLeft ()

Preencha a string com os espaços acrescentados à esquerda.

13 padRight ()

Preencha a string com os espaços acrescentados à direita.

14 mais()

Acrescenta uma string

15 anterior()

Este método é chamado pelo operador - para CharSequence.

16 substitua tudo()

Substitui todas as ocorrências de um grupo capturado pelo resultado de um fechamento naquele texto.

17 reverter()

Cria uma nova String que é o reverso desta String.

18 Dividido()

Divide esta String em torno das correspondências da expressão regular fornecida.

19 subString ()

Retorna uma nova String que é uma substring desta String.

20 toUpperCase ()

Converte todos os caracteres nesta String em maiúsculas.

21 toLowerCase ()

Converte todos os caracteres nesta String em minúsculas.

Um intervalo é uma abreviatura para especificar uma sequência de valores. Um intervalo é denotado pelo primeiro e último valores na sequência e o intervalo pode ser inclusivo ou exclusivo. Um intervalo inclusivo inclui todos os valores do primeiro ao último, enquanto um intervalo exclusivo inclui todos os valores, exceto o último. Aqui estão alguns exemplos de literais de intervalo -

  • 1..10 - Um exemplo de um intervalo inclusivo
  • 1 .. <10 - Um exemplo de um intervalo exclusivo
  • 'a' .. 'x' - Os intervalos também podem consistir em caracteres
  • 10..1 - Os intervalos também podem ser em ordem decrescente
  • 'x' .. 'a' - Os intervalos também podem consistir em caracteres e estar em ordem decrescente.

A seguir estão os vários métodos disponíveis para intervalos.

Sr. Não. Métodos e Descrição
1 contém ()

Verifica se um intervalo contém um valor específico

2 pegue()

Retorna o elemento na posição especificada neste intervalo.

3 ganhar()

Obtenha o valor mais baixo deste intervalo.

4 chegar ao()

Obtenha o valor superior deste intervalo.

5 isReverse ()

Este é um intervalo invertido, iterando para trás

6 Tamanho()

Retorna o número de elementos neste intervalo.

7 subList ()

Retorna uma visualização da parte deste intervalo entre o fromIndex especificado, inclusive, e toIndex, exclusivo

A lista é uma estrutura usada para armazenar uma coleção de itens de dados. No Groovy, a Lista contém uma sequência de referências de objeto. As referências de objeto em uma Lista ocupam uma posição na sequência e são distinguidas por um índice inteiro. Um literal de Lista é apresentado como uma série de objetos separados por vírgulas e entre colchetes.

Para processar os dados em uma lista, devemos ser capazes de acessar os elementos individuais. As listas Groovy são indexadas usando o operador de indexação []. Os índices da lista começam em zero, que se refere ao primeiro elemento.

A seguir estão alguns exemplos de listas -

  • [11, 12, 13, 14] - Uma lista de valores inteiros
  • ['Angular', 'Groovy', 'Java'] - Uma lista de Strings
  • [1, 2, [3, 4], 5] - uma lista aninhada
  • ['Groovy', 21, 2.11] - Uma lista heterogênea de referências de objetos
  • [] - Uma lista vazia

Neste capítulo, discutiremos os métodos de lista disponíveis no Groovy.

Sr. Não. Métodos e Descrição
1 adicionar()

Anexe o novo valor ao final desta lista.

2 contém ()

Retorna verdadeiro se esta Lista contiver o valor especificado.

3 pegue()

Retorna o elemento na posição especificada nesta lista.

4 está vazia()

Retorna verdadeiro se esta lista não contiver elementos

5 menos()

Cria uma nova lista composta pelos elementos do original sem os especificados na coleção.

6 mais()

Cria uma nova lista composta pelos elementos do original juntamente com os especificados na coleção.

7 pop ()

Remove o último item desta lista

8 retirar()

Remove o elemento na posição especificada nesta lista.

9 reverter()

Crie uma nova lista que é o inverso dos elementos da lista original

10 Tamanho()

Obtém o número de elementos desta Lista.

11 ordenar()

Retorna uma cópia classificada da Lista original.

Um mapa (também conhecido como array associativo, dicionário, tabela e hash) é uma coleção não ordenada de referências de objeto. Os elementos em uma coleção de mapas são acessados ​​por um valor-chave. As chaves usadas em um mapa podem ser de qualquer classe. Quando inserimos em uma coleção de mapas, dois valores são necessários: a chave e o valor.

A seguir estão alguns exemplos de mapas -

  • ['TopicName': 'Lists', 'TopicName': 'Maps'] - Coleções de pares de valores-chave que têm TopicName como a chave e seus respectivos valores.

  • [:] - Um mapa vazio.

Neste capítulo, discutiremos os métodos de mapa disponíveis no Groovy.

Sr. Não. Métodos e Descrição
1 containsKey ()

Este mapa contém esta chave?

2 pegue()

Procure a chave neste mapa e retorne o valor correspondente. Se não houver nenhuma entrada neste Mapa para a chave, retorne nulo.

3 conjunto de chaves()

Obtenha um conjunto de chaves neste mapa.

4 colocar()

Associa o valor especificado à chave especificada neste mapa. Se este mapa continha anteriormente um mapeamento para esta chave, o valor antigo é substituído pelo valor especificado.

5 Tamanho()

Retorna o número de mapeamentos de valores-chave neste mapa.

6 valores ()

Retorna uma visão de coleção dos valores contidos neste mapa.

A classe Date representa um instante específico no tempo, com precisão de milissegundos. A classe Date tem dois construtores, conforme mostrado abaixo.

Encontro()

Sintaxe

public Date()

Parameters - Nenhum.

Return Value

Aloca um objeto Date e o inicializa de forma que represente a hora em que foi alocado, medida com precisão de milissegundos.

Exemplo

A seguir está um exemplo do uso deste método -

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

Quando executamos o programa acima, obteremos o seguinte resultado. O resultado a seguir fornecerá a data e hora atuais -

Thu Dec 10 21:31:15 GST 2015

Data (milissegundos longos)

Sintaxe

public Date(long millisec)

Parameters

Milissegundos - O número de milissegundos a serem especificados desde o tempo base padrão.

Return Value - Aloca um Date objeto e inicializa-o para representar o número especificado de milissegundos desde o tempo base padrão conhecido como "a época", ou seja, 1º de janeiro de 1970, 00:00:00 GMT.

Exemplo

A seguir está um exemplo do uso deste método -

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

Quando executamos o programa acima, obteremos o seguinte resultado -

Thu Jan 01 04:00:00 GST 1970

A seguir estão os métodos fornecidos para a classe Date. Em todos os métodos da classe Date que aceitam ou retornam valores de ano, mês, data, horas, minutos e segundos, as seguintes representações são usadas -

  • Um ano y é representado pelo inteiro y - 1900.

  • Um mês é representado por um número inteiro de 0 a 11; 0 é janeiro, 1 é fevereiro e assim por diante; portanto, 11 é dezembro.

  • Uma data (dia do mês) é representada por um número inteiro de 1 a 31 da maneira usual.

  • Uma hora é representada por um número inteiro de 0 a 23. Assim, a hora da meia-noite à 1h é a hora 0 e a hora do meio-dia às 13h é a 12h.

  • Um minuto é representado por um número inteiro de 0 a 59 da maneira usual.

  • Um segundo é representado por um número inteiro de 0 a 61.

Sr. Não. Métodos e Descrição
1 depois de()

Testa se esta data é posterior à data especificada.

2 é igual a()

Compara duas datas de igualdade. O resultado é verdadeiro se e somente se o argumento não for nulo e for um objeto Date que representa o mesmo ponto no tempo, em milissegundos, que esse objeto.

3 comparado a()

Compara duas datas para fazer o pedido.

4 para sequenciar()

Converte este objeto Date em uma String

5 antes()

Testa se esta data é anterior à data especificada.

6 consiga tempo()

Retorna o número de milissegundos desde 1º de janeiro de 1970, 00:00:00 GMT representado por este objeto Date.

7 definir tempo()

Define este objeto Date para representar um ponto no tempo que é milissegundos após 1 de janeiro de 1970 00:00:00 GMT.

Uma expressão regular é um padrão usado para localizar substrings no texto. Groovy suporta expressões regulares nativamente usando a expressão ~ ”regex”. O texto entre aspas representa a expressão para comparação.

Por exemplo, podemos criar um objeto de expressão regular conforme mostrado abaixo -

def regex = ~'Groovy'

Quando o operador Groovy = ~ aparece como um predicado (expressão que retorna um booleano) em if e while(consulte o Capítulo 8), o operando String à esquerda é comparado ao operando de expressão regular à direita. Portanto, cada um dos itens a seguir fornece o valor verdadeiro.

Ao definir a expressão regular, os seguintes caracteres especiais podem ser usados ​​-

  • Existem dois caracteres posicionais especiais usados ​​para denotar o início e o fim de uma linha: circunflexo (∧) e cifrão ($).

  • As expressões regulares também podem incluir quantificadores. O sinal de mais (+) representa uma ou mais vezes, aplicado ao elemento anterior da expressão. O asterisco (*) é usado para representar zero ou mais ocorrências. O ponto de interrogação (?) Denota zero ou uma vez.

  • O metacaractere {e} é usado para corresponder a um número específico de instâncias do caractere anterior.

  • Em uma expressão regular, o símbolo de ponto (.) Pode representar qualquer caractere. Isso é descrito como o caractere curinga.

  • Uma expressão regular pode incluir classes de caracteres. Um conjunto de caracteres pode ser dado como uma sequência simples de caracteres entre os metacaracteres [e] como em [aeiou]. Para intervalos de letras ou números, você pode usar um separador de traço como em [a – z] ou [a – mA – M]. O complemento de uma classe de caractere é denotado por um circunflexo inicial dentro das raquetes quadradas como em [∧a – z] e representa todos os caracteres além dos especificados. Alguns exemplos de expressões regulares são fornecidos abaixo

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

O tratamento de exceções é necessário em qualquer linguagem de programação para tratar os erros de tempo de execução de modo que o fluxo normal do aplicativo possa ser mantido.

A exceção normalmente interrompe o fluxo normal do aplicativo, razão pela qual precisamos usar o tratamento de exceções em nosso aplicativo.

As exceções são amplamente classificadas nas seguintes categorias -

  • Checked Exception - As classes que estendem a classe Throwable, exceto RuntimeException e Error, são conhecidas como exceções verificadas, por exemplo ,IOException, SQLException etc. As exceções verificadas são verificadas em tempo de compilação.

Um caso clássico é FileNotFoundException. Suponha que você tenha o seguinte código em seu aplicativo que lê de um arquivo na unidade E.

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

se o arquivo (file.txt) não estiver na unidade E, a seguinte exceção será gerada.

Capturado: java.io.FileNotFoundException: E: \ file.txt (O sistema não pode encontrar o arquivo especificado).

java.io.FileNotFoundException: E: \ file.txt (O sistema não pode localizar o arquivo especificado).

  • Unchecked Exception - As classes que estendem RuntimeException são conhecidas como exceções não verificadas, por exemplo, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc. As exceções não verificadas não são verificadas em tempo de compilação, em vez disso, são verificadas em tempo de execução.

Um caso clássico é a ArrayIndexOutOfBoundsException que acontece quando você tenta acessar um índice de uma matriz que é maior que o comprimento da matriz. A seguir está um exemplo típico desse tipo de erro.

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

Quando o código acima é executado, a seguinte exceção será levantada.

Pego: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - O erro é irrecuperável, por exemplo, OutOfMemoryError, VirtualMachineError, AssertionError etc.

Esses são erros dos quais o programa nunca pode se recuperar e que farão com que o programa trave.

O diagrama a seguir mostra como a hierarquia de exceções no Groovy é organizada. Tudo é baseado na hierarquia definida em Java.

Captura de exceções

Um método captura uma exceção usando uma combinação de try e catchpalavras-chave. Um bloco try / catch é colocado em torno do código que pode gerar uma exceção.

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

Todo o seu código que poderia gerar uma exceção é colocado no bloco de código protegido.

No bloco catch, você pode escrever um código personalizado para manipular sua exceção para que o aplicativo possa se recuperar da exceção.

Vejamos um exemplo do código semelhante que vimos acima para acessar um array com um valor de índice maior que o tamanho do array. Mas desta vez, vamos envolver nosso código em um bloco 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 executamos o programa acima, obteremos o seguinte resultado -

Catching the exception 
Let's move on after the exception

A partir do código acima, encerramos o código defeituoso no bloco try. No bloco catch, estamos apenas capturando nossa exceção e enviando uma mensagem de que ocorreu uma exceção.

Vários blocos de captura

Pode-se ter vários blocos catch para lidar com vários tipos de exceções. Para cada bloco catch, dependendo do tipo de exceção levantada, você escreveria o código para tratá-la de acordo.

Vamos modificar nosso código acima para capturar a ArrayIndexOutOfBoundsException especificamente. A seguir está o trecho de código.

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 executamos o programa acima, obteremos o seguinte resultado -

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

No código acima, você pode ver que o bloco catch ArrayIndexOutOfBoundsException é capturado primeiro porque significa os critérios da exceção.

Finalmente Bloco

o finallybloco segue um bloco try ou um bloco catch. Um bloco final de código sempre é executado, independentemente da ocorrência de uma Exceção.

Usar um bloco finally permite que você execute quaisquer instruções do tipo de limpeza que deseja executar, não importa o que aconteça no código protegido. A sintaxe para este bloco é fornecida abaixo.

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

Vamos modificar nosso código acima e adicionar o bloco finally de código. A seguir está o trecho de código.

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 executamos o programa acima, obteremos o seguinte resultado -

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

A seguir estão os métodos de exceção disponíveis no Groovy -

public String getMessage ()

Retorna uma mensagem detalhada sobre a exceção que ocorreu. Esta mensagem é inicializada no construtor Throwable.

public Throwable getCause ()

Retorna a causa da exceção conforme representado por um objeto Throwable.

public String toString ()

Retorna o nome da classe concatenada com o resultado de getMessage ()

public void printStackTrace ()

Imprime o resultado de toString () junto com o rastreamento de pilha em System.err, o fluxo de saída de erro.

public StackTraceElement [] getStackTrace ()

Retorna uma matriz contendo cada elemento no rastreamento da pilha. O elemento no índice 0 representa o topo da pilha de chamadas e o último elemento na matriz representa o método na parte inferior da pilha.

public Throwable fillInStackTrace ()

Preenche o rastreamento de pilha deste objeto Throwable com o rastreamento de pilha atual, adicionando a qualquer informação anterior no rastreamento de pilha.

Exemplo

A seguir está o exemplo de código usando alguns dos métodos fornecidos acima -

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 executamos o programa acima, obteremos o seguinte resultado -

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

No Groovy, como em qualquer outra linguagem Orientada a Objetos, existe o conceito de classes e objetos para representar a natureza orientada a objetos da linguagem de programação. Uma classe Groovy é uma coleção de dados e os métodos que operam nesses dados. Juntos, os dados e métodos de uma classe são usados ​​para representar algum objeto do mundo real do domínio do problema.

Uma classe no Groovy declara o estado (dados) e o comportamento dos objetos definidos por essa classe. Portanto, uma classe Groovy descreve os campos de instância e os métodos dessa classe.

A seguir está um exemplo de uma classe em Groovy. O nome da turma é Aluno, que possui dois campos -StudentID e StudentName. Na função principal, estamos criando um objeto desta classe e atribuindo valores para oStudentID e StudentName do objeto.

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

Métodos getter e setter

Em qualquer linguagem de programação, é sempre uma prática ocultar os membros da instância com a palavra-chave privada e, em vez disso, fornecer os métodos getter e setter para definir e obter os valores das variáveis ​​da instância de acordo. O exemplo a seguir mostra como isso pode ser feito.

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 executamos o programa acima, obteremos o seguinte resultado -

1 
Joe

Observe os seguintes pontos-chave sobre o programa acima -

  • Na classe, o studentID e o studentName são marcados como privados, o que significa que não podem ser acessados ​​de fora da classe.

  • Cada membro da instância tem seu próprio método getter e setter. O método getter retorna o valor da variável de instância, por exemplo, o método int getStudentID () e o método setter define o valor do ID da instância, por exemplo, o método - void setStudentName (String pName)

Métodos de Instância

Normalmente é natural incluir mais métodos dentro da classe, o que realmente faz algum tipo de funcionalidade para a classe. Em nosso exemplo do aluno, vamos adicionar membros de instância de Marks1, Marks2 e Marks3 para denotar as marcas do aluno em 3 disciplinas. Em seguida, adicionaremos um novo método de instância que calculará as notas totais do aluno. A seguir está a aparência do código.

No exemplo a seguir, o método Total é um método de instância adicional que possui alguma lógica incorporada.

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 executamos o programa acima, obteremos o seguinte resultado -

60

Criação de vários objetos

Também se pode criar vários objetos de uma classe. A seguir está o exemplo de como isso pode ser alcançado. Aqui, estamos criando 3 objetos (st, st1 e st2) e chamando seus membros de instância e métodos de instância de acordo.

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 executamos o programa acima, obteremos o seguinte resultado -

60 
70 
80

Herança

A herança pode ser definida como o processo em que uma classe adquire as propriedades (métodos e campos) de outra. Com o uso de herança, as informações são gerenciáveis ​​em uma ordem hierárquica.

A classe que herda as propriedades de outra é conhecida como subclasse (classe derivada, classe filha) e a classe cujas propriedades são herdadas é conhecida como superclasse (classe base, classe pai).

Estende

extendsé a palavra-chave usada para herdar as propriedades de uma classe. A seguir está a sintaxe da palavra-chave extends. No exemplo a seguir, estamos fazendo o seguinte -

  • Criando uma classe chamada Person. Esta classe possui um membro de instância chamado nome.

  • Criando uma classe chamada Aluno que se estende da classe Pessoa. Observe que o membro da instância de nome que é definido na classe Person é herdado na classe Student.

  • No construtor da classe Student, estamos chamando o construtor da classe base.

  • Em nossa classe Student, estamos adicionando 2 membros de instância adicionais de 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 executamos o programa acima, obteremos o seguinte resultado -

Joe

Classes internas

As classes internas são definidas em outras classes. A classe envolvente pode usar a classe interna normalmente. Por outro lado, uma classe interna pode acessar membros de sua classe envolvente, mesmo se eles forem privados. Classes diferentes da classe envolvente não têm permissão para acessar classes internas.

A seguir está um exemplo de uma classe externa e interna. No exemplo a seguir, estamos fazendo o seguinte -

  • Criando uma classe chamada Outer que será nossa classe externa.
  • Definindo uma string chamada name em nossa classe Outer.
  • Criando uma classe interna ou aninhada dentro de nossa classe externa.
  • Observe que na classe interna podemos acessar o membro da instância de nome definido na classe externa.
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 executamos o programa acima, obteremos o seguinte resultado -

Joe

Classes abstratas

As classes abstratas representam conceitos genéricos, portanto, não podem ser instanciadas, sendo criadas para serem subclasses. Seus membros incluem campos / propriedades e métodos abstratos ou concretos. Métodos abstratos não têm implementação e devem ser implementados por subclasses concretas. As classes abstratas devem ser declaradas com a palavra-chave abstract. Os métodos abstratos também devem ser declarados com a palavra-chave abstract.

No exemplo a seguir, observe que a classe Person agora é transformada em uma classe abstrata e não pode ser instanciada. Observe também que há um método abstrato chamado DisplayMarks na classe abstrata que não possui detalhes de implementação. Na classe do aluno é obrigatório adicionar os detalhes de implementação.

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 executamos o programa acima, obteremos o seguinte resultado -

Joe 
10 
null

Interfaces

Uma interface define um contrato ao qual uma classe precisa estar em conformidade. Uma interface apenas define uma lista de métodos que precisam ser implementados, mas não define a implementação dos métodos. Uma interface precisa ser declarada usando a palavra-chave interface. Uma interface apenas define assinaturas de método. Os métodos de uma interface são semprepublic. É um erro usar métodos protegidos ou privados em interfaces.

A seguir está um exemplo de uma interface no groovy. No exemplo a seguir, estamos fazendo o seguinte -

  • Criação de uma interface chamada Marks e criação de um método de interface chamado DisplayMarks.

  • Na definição da classe, estamos usando a palavra-chave implements para implementar a interface.

  • Como estamos implementando a interface, temos que fornecer a implementação para o método 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 executamos o programa acima, obteremos o seguinte resultado -

10
null

Os genéricos permitem que os tipos (classes e interfaces) sejam parâmetros ao definir classes, interfaces e métodos. Muito parecido com os parâmetros formais mais familiares usados ​​em declarações de método, os parâmetros de tipo fornecem uma maneira de reutilizar o mesmo código com entradas diferentes. A diferença é que as entradas para parâmetros formais são valores, enquanto as entradas para digitar parâmetros são tipos.

Genérico para coleções

As classes de coleções, como a classe List, podem ser generalizadas de forma que apenas coleções desse tipo sejam aceitas no aplicativo. Um exemplo de ArrayList generalizado é mostrado abaixo. O que a instrução a seguir faz é que ela só aceita itens de lista que são do tipo string -

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

No exemplo de código a seguir, estamos fazendo o seguinte -

  • Criando uma coleção ArrayList generalizada que conterá apenas Strings.
  • Adicione 3 strings à lista.
  • Para cada item da lista, imprimindo o valor das strings.
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);
      }
   } 
}

A saída do programa acima seria -

First String 
Second String 
Third String

Classes Generalizadas

A classe inteira também pode ser generalizada. Isso torna a classe mais flexível em aceitar quaisquer tipos e trabalhar de acordo com esses tipos. Vejamos um exemplo de como podemos fazer isso.

No programa a seguir, estamos realizando as seguintes etapas -

  • Estamos criando uma classe chamada ListType. Observe as palavras-chave <T> colocadas na frente da definição da classe. Isso informa ao compilador que essa classe pode aceitar qualquer tipo. Então, quando declaramos um objeto desta classe, podemos especificar um tipo durante a declaração e esse tipo seria substituído no espaço reservado <T>

  • A classe genérica tem métodos getter e setter simples para trabalhar com a variável de membro definida na classe.

  • No programa principal, observe que podemos declarar objetos da classe ListType, mas de tipos diferentes. O primeiro é do tipo Integer e o segundo é do 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;
   } 
}

A saída do programa acima seria -

First String 
1

Traços são uma construção estrutural da linguagem que permite -

  • Composição de comportamentos.
  • Implementação de interfaces em tempo de execução.
  • Compatibilidade com verificação / compilação de tipo estático

Eles podem ser vistos como interfaces que transportam implementações e estados padrão. Um trait é definido usando a palavra-chave trait.

Um exemplo de um traço é dado abaixo -

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

Pode-se então usar a palavra-chave implementar para implementar o traço de maneira semelhante às interfaces.

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;
}

Implementando Interfaces

Traits podem implementar interfaces, caso em que as interfaces são declaradas usando a palavra-chave implements.

Um exemplo de uma característica que implementa uma interface é fornecido abaixo. No exemplo a seguir, os seguintes pontos-chave podem ser observados.

  • Uma interface Total é definida com o método DisplayTotal.

  • O traço Marks implementa a interface Total e, portanto, precisa fornecer uma implementação para o método 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;  
}

A saída do programa acima seria -

Display Marks 
Display Total

Propriedades

Um traço pode definir propriedades. Um exemplo de um traço com uma propriedade é dado abaixo.

No exemplo a seguir, o Marks1 do tipo inteiro é uma propriedade.

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 
   }
}

A saída do programa acima seria -

10 
Display Total

Composição de Comportamentos

As características podem ser usadas para implementar herança múltipla de forma controlada, evitando o problema do diamante. No exemplo de código a seguir, definimos duas características -Marks e Total. Nossa classe de aluno implementa ambos os traços. Uma vez que a classe do aluno estende ambas as características, ela é capaz de acessar os dois métodos -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 
}

A saída do programa acima seria -

Total 
Marks1

Traços de Extensão

Características podem estender outra característica, caso em que você deve usar o extendspalavra-chave. No exemplo de código a seguir, estamos estendendo o traço Total com o traço 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 
}

A saída do programa acima seria -

Total

Um encerramento é um pequeno bloco anônimo de código. Normalmente, ele abrange apenas algumas linhas de código. Um método pode até mesmo tomar o bloco de código como parâmetro. Eles são anônimos por natureza.

A seguir está um exemplo de um fechamento simples e sua aparência.

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

No exemplo acima, a linha de código - {println "Hello World"} é conhecida como closure. O bloco de código referenciado por este identificador pode ser executado com a instrução de chamada.

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World

Parâmetros formais em fechamentos

Os fechamentos também podem conter parâmetros formais para torná-los mais úteis, assim como os métodos do Groovy.

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

No exemplo de código acima, observe o uso de $ {param} que faz com que o fechamento receba um parâmetro. Ao chamar o encerramento por meio da instrução clos.call, agora temos a opção de passar um parâmetro para o encerramento.

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World

A próxima ilustração repete o exemplo anterior e produz o mesmo resultado, mas mostra que um único parâmetro implícito referido como pode ser usado. Aqui, 'it' é uma palavra-chave no Groovy.

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

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World

Fechamentos e variáveis

Mais formalmente, os fechamentos podem se referir a variáveis ​​no momento em que o fechamento é definido. A seguir está um exemplo de como isso pode ser alcançado.

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");
   } 
}

No exemplo acima, além de passar um parâmetro para o fechamento, também estamos definindo uma variável chamada str1. O fechamento também assume a variável junto com o parâmetro.

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World 
Welcome World

Usando fechamentos em métodos

Os fechamentos também podem ser usados ​​como parâmetros para métodos. No Groovy, muitos dos métodos embutidos para tipos de dados, como listas e coleções, têm fechamentos como tipo de parâmetro.

O exemplo a seguir mostra como um encerramento pode ser enviado a um método como um parâmetro.

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);
   } 
}

No exemplo acima,

  • Estamos definindo um método estático chamado Display, que tem um fechamento como argumento.

  • Estamos, então, definindo um fechamento em nosso método principal e passando-o para nosso método Display como um parâmetro.

Quando executamos o programa acima, obteremos o seguinte resultado -

Hello World 
Welcome World 
Welcome Inner

Fechamentos em coleções e string

Vários métodos List, Map e String aceitam um encerramento como argumento. Vejamos um exemplo de como os fechamentos podem ser usados ​​nesses tipos de dados.

Usando fechamentos com listas

O exemplo a seguir mostra como os fechamentos podem ser usados ​​com Listas. No exemplo a seguir, estamos primeiro definindo uma lista simples de valores. O tipo de coleção de lista então define uma função chamada.each. Esta função assume um fechamento como parâmetro e aplica o fechamento a cada elemento da lista.

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

Quando executamos o programa acima, obteremos o seguinte resultado -

11 
12 
13 
14

Usando fechamentos com mapas

O exemplo a seguir mostra como as interdições podem ser usadas com o Maps. No exemplo a seguir, estamos primeiro definindo um mapa simples de itens de valor-chave. O tipo de coleção de mapas então define uma função chamada .each. Esta função assume um fechamento como parâmetro e aplica o fechamento a cada par de valores-chave do mapa.

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 executamos o programa acima, obteremos o seguinte resultado -

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

Freqüentemente, podemos desejar iterar entre os membros de uma coleção e aplicar alguma lógica apenas quando o elemento atender a algum critério. Isso é prontamente tratado com uma instrução condicional no encerramento.

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}
   } 
}

O exemplo acima mostra a expressão condicional if (num% 2 == 0) sendo usada no encerramento, que é usada para verificar se cada item na lista é divisível por 2.

Quando executamos o programa acima, obteremos o seguinte resultado -

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

Métodos usados ​​com fechamentos

Os próprios fechos fornecem alguns métodos.

Sr. Não. Métodos e Descrição
1 encontrar()

O método find encontra o primeiro valor em uma coleção que corresponde a algum critério.

2 encontrar tudo()

Ele encontra todos os valores no objeto receptor que correspondem à condição de fechamento.

3 qualquer () e cada ()

O método any itera por meio de cada elemento de uma coleção, verificando se um predicado booleano é válido para pelo menos um elemento.

4 coletar ()

O método collect itera por meio de uma coleção, convertendo cada elemento em um novo valor usando o fechamento como o transformador.

As anotações são uma forma de metadados em que fornecem dados sobre um programa que não faz parte do próprio programa. As anotações não têm efeito direto na operação do código que anotam.

As anotações são usadas principalmente pelos seguintes motivos -

  • Information for the compiler - As anotações podem ser usadas pelo compilador para detectar erros ou suprimir avisos.

  • Compile-time and deployment-time processing - As ferramentas de software podem processar informações de anotação para gerar código, arquivos XML e assim por diante.

  • Runtime processing - Algumas anotações estão disponíveis para serem examinadas em tempo de execução.

No Groovy, uma anotação básica é a seguinte -

@interface - O caractere de arroba (@) indica ao compilador que o que se segue é uma anotação.

Uma anotação pode definir membros em the form de métodos sem corpos e um valor padrão opcional.

As anotações podem ser aplicadas aos seguintes tipos -

Tipo de corda

Um exemplo de uma anotação para uma string é fornecido abaixo -

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

Tipo Enum

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

Tipo de aula

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

Valores de membro de anotação

Quando uma anotação é usada, é necessário definir pelo menos todos os membros que não possuem um valor padrão. Um exemplo é dado abaixo. Quando a anotação Exemplo é usada após ser definida, ela precisa ter um valor atribuído a ela.

@interface Example {
   int status() 
}

@Example(status = 1)

Parâmetros de anotação de fechamento

Um bom recurso das anotações no Groovy é que você também pode usar um encerramento como um valor de anotação. Portanto, as anotações podem ser usadas com uma ampla variedade de expressões.

Um exemplo é dado a seguir. A anotação Onlyif é criada com base em um valor de classe. Em seguida, a anotação é aplicada a dois métodos que enviam mensagens diferentes para a variável de resultado com base no valor da variável de número.

@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 Anotações

Este é um recurso bastante útil de anotações no groovy. Pode haver momentos em que você pode ter várias anotações para um método como o mostrado abaixo. Às vezes, pode ser complicado ter várias anotações.

@Procedure 
@Master class 
MyMasterProcedure {}

Nesse caso, você pode definir uma meta-anotação que agrupa várias anotações e aplicar a meta-anotação ao método. Portanto, para o exemplo acima, você pode primeiro definir a coleção de anotações usando o AnnotationCollector.

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

Depois de fazer isso, você pode aplicar o seguinte meta-anotador ao método -

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

XML é uma linguagem de código aberto portátil que permite aos programadores desenvolver aplicativos que podem ser lidos por outros aplicativos, independentemente do sistema operacional e / ou linguagem de desenvolvimento. Esta é uma das linguagens mais comuns usadas para trocar dados entre aplicativos.

O que é XML?

A Extensible Markup Language XML é uma linguagem de marcação muito parecida com HTML ou SGML. Isso é recomendado pelo World Wide Web Consortium e está disponível como um padrão aberto. XML é extremamente útil para manter o controle de pequenas e médias quantidades de dados sem exigir um backbone baseado em SQL.

Suporte XML em Groovy

A linguagem Groovy também fornece um suporte avançado da linguagem XML. As duas classes XML mais básicas usadas são -

  • XML Markup Builder- Groovy suporta um gerador de marcação baseado em árvore, BuilderSupport, que pode ser subclasse para fazer uma variedade de representações de objetos estruturados em árvore. Normalmente, esses construtores são usados ​​para representar marcação XML, marcação HTML. O gerador de marcação do Groovy captura chamadas para pseudométodos e os converte em elementos ou nós de uma estrutura de árvore. Os parâmetros para esses pseudométodos são tratados como atributos dos nós. Fechamentos como parte da chamada do método são considerados como subconteúdo aninhado para o nó da árvore resultante.

  • XML Parser- A classe Groovy XmlParser emprega um modelo simples para analisar um documento XML em uma árvore de instâncias de Node. Cada nó possui o nome do elemento XML, os atributos do elemento e referências a qualquer nó filho. Este modelo é suficiente para o processamento XML mais simples.

Para todos os nossos exemplos de código XML, vamos usar o seguinte arquivo XML simples movies.xml para construção do arquivo XML e leitura do arquivo subsequentemente.

<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>

Construtor de marcação XML

Sintaxe

public MarkupBuilder()

O MarkupBuilder é usado para construir todo o documento XML. O documento XML é criado criando primeiro um objeto da classe de documento XML. Depois que o objeto é criado, um pseudométodo pode ser chamado para criar os vários elementos do documento XML.

Vejamos um exemplo de como criar um bloco, ou seja, um elemento de filme do documento XML acima -

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') 
      }
   } 
}

No exemplo acima, as seguintes coisas precisam ser observadas -

  • mB.collection() - Este é um gerador de marcação que cria a tag XML principal de <collection> </collection>

  • movie(title : 'Enemy Behind')- Esses pseudométodos criam as tags filhas com este método, criando a tag com o valor. Ao especificar um valor denominado título, isso realmente indica que um atributo precisa ser criado para o elemento.

  • Um encerramento é fornecido ao pseudométodo para criar os elementos restantes do documento XML.

  • O construtor padrão para a classe MarkupBuilder é inicializado para que o XML gerado seja emitido para o fluxo de saída padrão

Quando executamos o programa acima, obteremos o seguinte resultado -

<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>

Para criar o documento XML inteiro, as seguintes coisas precisam ser feitas.

  • Uma entrada de mapa precisa ser criada para armazenar os diferentes valores dos elementos.
  • Para cada elemento do mapa, estamos atribuindo o valor a cada 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 executamos o programa acima, obteremos o seguinte resultado -

<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>

Análise XML

A classe Groovy XmlParser emprega um modelo simples para analisar um documento XML em uma árvore de instâncias de Node. Cada nó possui o nome do elemento XML, os atributos do elemento e referências a qualquer nó filho. Este modelo é suficiente para o processamento XML mais simples.

Sintaxe

public XmlParser() 
   throws ParserConfigurationException, 
      SAXException

O código a seguir mostra um exemplo de como o analisador XML pode ser usado para ler um documento XML.

Vamos supor que temos o mesmo documento denominado Movies.xml e queremos analisar o documento XML e exibir uma saída adequada para o usuário. O código a seguir é um trecho de como podemos percorrer todo o conteúdo do documento XML e exibir uma resposta adequada ao usuário.

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 executamos o programa acima, obteremos o seguinte resultado -

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

As coisas importantes a serem observadas sobre o código acima.

  • Um objeto da classe XmlParser está sendo formado para que possa ser usado para analisar o documento XML.

  • O analisador recebe a localização do arquivo XML.

  • Para cada elemento do filme, estamos usando um encerramento para navegar por cada nó filho e exibir as informações relevantes.

Para o próprio elemento de filme, estamos usando o símbolo @ para exibir o atributo de título anexado ao elemento de filme.

JMX é o padrão de fato usado para monitorar todos os aplicativos que têm alguma relação com o ambiente virtual Java. Dado que o Groovy está diretamente acima do Java, o Groovy pode aproveitar a enorme quantidade de trabalho já feito para JMX com Java.

Monitorando o JVM

Pode-se usar as classes padrão disponíveis em java.lang.management para realizar o monitoramento da JVM. O exemplo de código a seguir mostra como isso pode ser feito.

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 o código é executado, a saída irá variar dependendo do sistema no qual o código é executado. Uma amostra da saída é fornecida abaixo.

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]

Monitorando Tomcat

Para monitorar o tomcat, o seguinte parâmetro deve ser definido quando o tomcat é iniciado -

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

O código a seguir usa JMX para descobrir os MBeans disponíveis no Tomcat em execução, determinar quais são os módulos da web e extrair o tempo de processamento para cada módulo da 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 
}

Este capítulo aborda como podemos usar a linguagem Groovy para analisar e produzir objetos JSON.

Funções JSON

Sr. Não Função e bibliotecas
1

JsonSlurper

JsonSlurper é uma classe que analisa o texto JSON ou o conteúdo do leitor em dados Groovy

Estruturas como mapas, listas e tipos primitivos como Integer, Double, Boolean e String.

2

JsonOutput

Este método é responsável por serializar objetos Groovy em strings JSON.

Análise de dados usando JsonSlurper

JsonSlurper é uma classe que analisa texto JSON ou conteúdo de leitor em estruturas de dados Groovy, como mapas, listas e tipos primitivos como Integer, Double, Boolean e String.

Sintaxe

def slurper = new JsonSlurper()

Slurper JSON analisa texto ou conteúdo do leitor em uma estrutura de dados de listas e mapas.

A classe JsonSlurper vem com algumas variantes para implementações de analisador. Às vezes, você pode ter requisitos diferentes quando se trata de analisar certas strings. Vamos dar um exemplo em que é necessário ler o JSON que é retornado da resposta de um servidor web. Nesse caso, é benéfico usar a variante do analisador JsonParserLax. Este analisador permite comentários no texto JSON, bem como nenhuma string de aspas, etc. Para especificar este tipo de analisador, você precisa usar o tipo de analisador JsonParserType.LAX ao definir um objeto do JsonSlurper.

Vamos ver um exemplo disso a seguir. O exemplo é para obter dados JSON de um servidor web usando o módulo http. Para esse tipo de travessia, a melhor opção é ter o tipo de analisador definido para a 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)
   }
}

Da mesma forma, os seguintes tipos de analisador adicionais estão disponíveis no Groovy -

  • O analisador JsonParserCharArray basicamente pega uma string JSON e opera na matriz de caracteres subjacente. Durante a conversão de valor, ele copia submatrizes de caracteres (um mecanismo conhecido como "corte") e opera sobre eles individualmente.

  • O JsonFastParser é uma variante especial do JsonParserCharArray e é o analisador mais rápido. JsonFastParser também é conhecido como analisador de sobreposição de índice. Durante a análise da String JSON fornecida, ele tenta ao máximo evitar a criação de novas matrizes de caracteres ou instâncias de String. Ele apenas mantém os ponteiros para a matriz de caracteres original subjacente apenas. Além disso, ele adia a criação do objeto o mais tarde possível.

  • O JsonParserUsingCharacterSource é um analisador especial para arquivos muito grandes. Ele usa uma técnica chamada "janela de caracteres" para analisar grandes arquivos JSON (grandes significam arquivos com mais de 2 MB neste caso) com características de desempenho constantes.

Parsing Text

Vamos dar uma olhada em alguns exemplos de como podemos usar a 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);
   } 
}

No exemplo acima, nós somos -

  • Primeiro criando uma instância da classe JsonSlurper

  • Então, estamos usando a função parseText da classe JsonSlurper para analisar algum texto JSON.

  • Quando obtemos o objeto, você pode ver que podemos realmente acessar os valores na string JSON por meio da chave.

O resultado do programa acima é dado abaixo -

John 
1

Lista de análise de inteiros

Vamos dar uma olhada em outro exemplo do método de análise JsonSlurper. No exemplo a seguir, estamos passando uma lista de inteiros. Você notará no código a seguir que podemos usar o método List de cada um e passar um encerramento para ele.

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 }
   } 
}

O resultado do programa acima é dado abaixo -

List=[2, 3, 4, 5]

Lista de análise de tipos de dados primitivos

O analisador JSON também suporta os tipos de dados primitivos de string, número, objeto, verdadeiro, falso e nulo. A classe JsonSlurper converte esses tipos JSON em tipos Groovy correspondentes.

O exemplo a seguir mostra como usar o JsonSlurper para analisar uma string JSON. E aqui você pode ver que o JsonSlurper é capaz de analisar os itens individuais em seus respectivos tipos primitivos.

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); 
   } 
}

O resultado do programa acima é dado abaixo -

12 
12.55 
1.2E+14

JsonOutput

Agora vamos falar sobre como imprimir a saída em Json. Isso pode ser feito pelo método JsonOutput. Este método é responsável por serializar objetos Groovy em strings JSON.

Sintaxe

Static string JsonOutput.toJson(datatype obj)

Parameters - Os parâmetros podem ser um objeto de um tipo de dados - Número, Booleano, caractere, String, Data, Mapa, fechamento etc.

Return type - O tipo de retorno é uma string json.

Exemplo

A seguir está um exemplo simples de como isso pode ser alcançado.

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

O resultado do programa acima é dado abaixo -

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

O JsonOutput também pode ser usado para objetos normais e antigos. No exemplo a seguir, você pode ver que, na verdade, estamos passando objetos do tipo Student para o método 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; 
}

O resultado do programa acima é dado abaixo -

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

Groovy permite omitir parênteses em torno dos argumentos de uma chamada de método para instruções de nível superior. Isso é conhecido como o recurso de "cadeia de comando". Esta extensão funciona permitindo que se encadeie tais chamadas de método sem parênteses, não exigindo parênteses em torno dos argumentos, nem pontos entre as chamadas encadeadas.

Se uma chamada for executada como a b c d, isso será equivalente a a(b).c(d).

DSL ou linguagem específica de domínio tem como objetivo simplificar o código escrito em Groovy de forma que se torne facilmente compreensível para o usuário comum. O exemplo a seguir mostra o que exatamente significa ter um idioma específico de domínio.

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

O código acima mostra uma lista de números impressos no console usando a instrução println. Em uma linguagem específica de domínio, os comandos seriam como -

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

Portanto, o exemplo acima mostra a transformação da linguagem de programação para atender às necessidades de uma linguagem de domínio específico.

Vejamos um exemplo simples de como podemos implementar DSLs no 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 executamos o programa acima, obteremos o seguinte resultado -

How are things? We are doing well. Take care

O seguinte deve ser observado sobre a implementação do código acima -

  • É usado um método estático que aceita um fechamento. Esta é principalmente uma maneira descomplicada de implementar uma DSL.

  • No exemplo do email, a classe EmailDsl possui um método make. Ele cria uma instância e delega todas as chamadas no encerramento para a instância. Este é o mecanismo onde as seções "para" e "de" acabam executando métodos dentro da classe EmailDsl.

  • Depois que o método to () é chamado, armazenamos o texto na instância para formatação posterior.

  • Agora podemos chamar o método EmailDSL com uma linguagem fácil de entender para os usuários finais.

O módulo groovy-sql do Groovy fornece uma abstração de alto nível sobre a tecnologia JDBC do Java atual. A API Groovy sql suporta uma grande variedade de bancos de dados, alguns dos quais são mostrados abaixo.

  • HSQLDB
  • Oracle
  • servidor SQL
  • MySQL
  • MongoDB

Em nosso exemplo, usaremos o banco de dados MySQL como exemplo. Para usar o MySQL com Groovy, a primeira coisa a fazer é baixar o arquivo jar jdbc do MySQL do site mysql.The format do MySQL será mostrado abaixo.

mysql-connector-java-5.1.38-bin

Em seguida, certifique-se de adicionar o arquivo jar acima ao classpath em sua estação de trabalho.

Conexão de banco de dados

Antes de se conectar a um banco de dados MySQL, certifique-se do seguinte -

  • Você criou um banco de dados TESTDB.
  • Você criou uma tabela EMPLOYEE em TESTDB.
  • Esta tabela contém os campos FIRST_NAME, LAST_NAME, AGE, SEX e INCOME.
  • O ID do usuário "testuser" e a senha "test123" são definidos para acessar o TESTDB.
  • Certifique-se de ter baixado o arquivo jar mysql e adicionado o arquivo ao seu classpath.
  • Você passou pelo tutorial do MySQL para entender os fundamentos do MySQL

O exemplo a seguir mostra como se conectar ao banco de dados 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()  
   } 
}

Ao executar este script, ele está produzindo o seguinte resultado -

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

Criando Tabela de Banco de Dados

A próxima etapa após conectar-se ao banco de dados é criar as tabelas em nosso banco de dados. O exemplo a seguir mostra como criar uma tabela no banco de dados usando Groovy. O método execute da classe Sql é usado para executar instruções no banco de dados.

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() 
   } 
}

Operação de inserção

É necessário quando você deseja criar seus registros em uma tabela de banco de dados.

Exemplo

O exemplo a seguir irá inserir um registro na tabela de funcionários. O código é colocado em um bloco try catch para que, se o registro for executado com sucesso, a transação seja confirmada no banco de dados. Se a transação falhar, um rollback é feito.

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()
   } 
}

Suponha que você queira apenas selecionar certas linhas com base em um critério. O código a seguir mostra como você pode adicionar um marcador de posição de parâmetro para pesquisar valores. O exemplo acima também pode ser escrito para receber parâmetros conforme mostrado no código a seguir. O símbolo $ é usado para definir um parâmetro que pode ser substituído por valores quando a instrução sql é executada.

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()
   }
}

Operação READ

Operação READ em qualquer banco de dados significa buscar algumas informações úteis do banco de dados. Assim que nossa conexão de banco de dados for estabelecida, você estará pronto para fazer uma consulta a este banco de dados.

A operação de leitura é executada usando o método eachRow da classe sql.

Sintaxe

eachRow(GString gstring, Closure closure)

Executa a consulta SQL fornecida chamando o Closure fornecido com cada linha do conjunto de resultados.

Parameters

  • Gstring - A instrução sql que precisa ser executada.

  • Closure- A instrução de fechamento para processar as linhas recuperadas da operação de leitura. Executa a consulta SQL fornecida chamando o Closure fornecido com cada linha do conjunto de resultados.

O exemplo de código a seguir mostra como buscar todos os registros da tabela de funcionários.

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()
   } 
}

A saída do programa acima seria -

[Mac, Mohan, 20, M, 2000.0]

Operação de atualização

ATUALIZAR Operação em qualquer banco de dados significa atualizar um ou mais registros, que já estão disponíveis no banco de dados. O procedimento a seguir atualiza todos os registros que têm SEXO como 'M'. Aqui, aumentamos a IDADE de todos os homens em um ano.

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()
   } 
}

Operação DELETE

A operação DELETE é necessária quando você deseja excluir alguns registros de seu banco de dados. A seguir está o procedimento para excluir todos os registros de EMPLOYEE onde AGE é maior que 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()
   } 
}

Realizando transações

As transações são um mecanismo que garante a consistência dos dados. As transações têm as seguintes quatro propriedades -

  • Atomicity - Ou uma transação é concluída ou nada acontece.

  • Consistency - Uma transação deve começar em um estado consistente e deixar o sistema em um estado consistente.

  • Isolation - Os resultados intermediários de uma transação não são visíveis fora da transação atual.

  • Durability - Depois que uma transação foi confirmada, os efeitos são persistentes, mesmo após uma falha do sistema.

Aqui está um exemplo simples de como implementar transações. Já vimos este exemplo de nosso tópico anterior da operação 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()

Confirmar operação

A operação de confirmação é o que diz ao banco de dados para prosseguir com a operação e finalizar todas as alterações no banco de dados.

Em nosso exemplo acima, isso é conseguido pela seguinte declaração -

sql.commit()

Operação de reversão

Se você não estiver satisfeito com uma ou mais das alterações e quiser reverter essas alterações completamente, use o método de reversão. Em nosso exemplo acima, isso é conseguido pela seguinte declaração -

sql.rollback()

Desconectando bancos de dados

Para desconectar a conexão do banco de dados, use o método close.

sql.close()

Durante o processo de desenvolvimento de software, às vezes os desenvolvedores gastam muito tempo criando estruturas de dados, classes de domínio, XML, layouts de GUI, fluxos de saída, etc. E às vezes o código usado para criar esses requisitos específicos resulta na repetição do mesmo trecho de código em muitos lugares. É aqui que entram os construtores Groovy. O Groovy tem construtores que podem ser usados ​​para criar objetos e estruturas padrão. Esses construtores economizam tempo, pois o desenvolvedor não precisa escrever seu próprio código para criá-los. No início deste capítulo, veremos os diferentes construtores disponíveis no groovy.

Construtor de Swing

No groovy também é possível criar interfaces gráficas com o usuário usando os construtores de swing disponíveis no groovy. A classe principal para desenvolver componentes de swing é a classe SwingBuilder. Esta classe tem muitos métodos para criar componentes gráficos, como -

  • JFrame - Isso é para criar o elemento de quadro.

  • JTextField - Isso é usado para criar o componente de campo de texto.

Vejamos um exemplo simples de como criar um aplicativo Swing usando a classe SwingBuilder. No exemplo a seguir, você pode ver os seguintes pontos -

  • Você precisa importar as classes groovy.swing.SwingBuilder e javax.swing. *.

  • Todos os componentes exibidos no aplicativo Swing fazem parte da classe SwingBuilder.

  • Para o próprio quadro, você pode especificar a localização inicial e o tamanho do quadro. Você também pode especificar o título do quadro.

  • Você precisa definir a propriedade Visibility como true para que o quadro seja mostrado.

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)

O resultado do programa acima é fornecido abaixo. A saída a seguir mostra um JFrame junto com um JLabel com um texto de Hello World.

Vejamos nosso próximo exemplo de criação de uma tela de entrada com caixas de texto. No exemplo a seguir, queremos criar um formulário com caixas de texto para o nome do aluno, disciplina e nome da escola. No exemplo a seguir, você pode ver os seguintes pontos-chave -

  • Estamos definindo um layout para nossos controles na tela. Neste caso, estamos usando o Layout de grade.
  • Estamos usando uma propriedade de alinhamento para nossos rótulos.
  • Estamos usando o método textField para exibir caixas de texto na tela.
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)

O resultado do programa acima é dado abaixo -

Manipuladores de eventos

Agora, vamos examinar os manipuladores de eventos. Os manipuladores de eventos são usados ​​para o botão realizar algum tipo de processamento quando um botão é pressionado. Cada chamada de pseudométodo de botão inclui o parâmetro actionPerformed. Isso representa um bloco de código apresentado como um encerramento.

Vejamos nosso próximo exemplo de criação de uma tela com 2 botões. Quando qualquer botão é pressionado, uma mensagem correspondente é enviada para a tela do console. No exemplo a seguir, você pode ver os seguintes pontos-chave -

  • Para cada botão definido, estamos usando o método actionPerformed e definindo um fechamento para enviar alguma saída ao console quando o botão é clicado.

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)

O resultado do programa acima é fornecido abaixo. Ao clicar em um dos botões, a mensagem necessária é enviada para a tela de registro do console.

Outra variação do exemplo acima é definir métodos que podem atuar como manipuladores. No exemplo a seguir, estamos definindo 2 manipuladores de 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)

A saída do programa acima permaneceria igual ao exemplo anterior.

DOM Builder

O construtor DOM pode ser usado para analisar HTML, XHTML e XML e convertê-lo em uma árvore DOM W3C.

O exemplo a seguir mostra como o construtor DOM pode ser usado.

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

O JsonBuilder é usado para criar objetos do tipo json.

O exemplo a seguir mostra como o construtor Json pode ser usado.

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());

O resultado do programa acima é fornecido abaixo. A saída clearlt mostra que o Jsonbuilder foi capaz de construir o objeto json a partir de um conjunto estruturado de nós.

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

O jsonbuilder também pode pegar uma lista e convertê-la em um objeto json. O exemplo a seguir mostra como isso pode ser feito.

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

O resultado do programa acima é fornecido abaixo.

[1,2,3]

O jsonBuilder também pode ser usado para classes. O exemplo a seguir mostra como os objetos de uma classe podem se tornar entradas para o construtor 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)

O resultado do programa acima é fornecido abaixo.

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

NodeBuilder

NodeBuilder é usado para criar árvores aninhadas de objetos Node para lidar com dados arbitrários. Um exemplo de uso de um Nodebuilder é mostrado abaixo.

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 é um construtor para gerar uma estrutura de diretório de arquivos a partir de uma especificação. A seguir está um exemplo de como o FileTreeBuilder pode ser usado.

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

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

A partir da execução do código acima, será criado um arquivo denominado sample.txt na pasta main / submain / Tutorial. E o arquivo sample.txt terá o texto “Hello World”.

O shell Groovy conhecido como groovysh pode ser facilmente usado para avaliar expressões groovy, definir classes e executar programas simples. O shell da linha de comando é instalado quando o Groovy é instalado.

A seguir estão as opções de linha de comando disponíveis no Groovy -

Parâmetro de linha de comando Nome completo Detalhes
-C --color [= FLAG] Ativar ou desativar o uso de cores ANSI
-D --define = NOME = VALOR Defina uma propriedade do sistema
-T --terminal = TYPE Especifique o TIPO de terminal a ser usado
-V --versão Mostra a versão
-classpath Especifique onde encontrar os arquivos de classe - deve ser o primeiro argumento
-cp --classpath Aliases para '-classpath'
-d --depurar --debug Habilita saída de depuração
-e --evaluate = arg Avalie a opção punho ao iniciar a sessão interativa
-h --Socorro Exibir esta mensagem de ajuda
-q --quieto Suprimir saída supérflua
-v --verbose Ativar saída detalhada

O instantâneo a seguir mostra um exemplo simples de uma expressão sendo executada no shell do Groovy. No exemplo a seguir, estamos apenas imprimindo “Hello World” no shell moderno.

Classes e funções

É muito fácil definir uma classe no prompt de comando, criar um novo objeto e invocar um método na classe. O exemplo a seguir mostra como isso pode ser implementado. No exemplo a seguir, estamos criando uma classe simples de Aluno com um método simples. No próprio prompt de comando, estamos criando um objeto da classe e chamando o método Display.

É muito fácil definir um método no prompt de comando e invocar o método. Observe que o método é definido usando o tipo def. Observe também que incluímos um parâmetro chamado nome que é substituído pelo valor real quando o método Display é chamado. O exemplo a seguir mostra como isso pode ser implementado.

Comandos

O shell possui vários comandos diferentes, que fornecem acesso avançado ao ambiente do shell. A seguir está a lista deles e o que fazem.

Sr. Não Comando & smp; Descrição do Comando
1

:help

(: h) Exibir esta mensagem de ajuda

2

?

(:?) Alias ​​para:: help

3

:exit

(: x) Saia do shell

4

:quit

(: q) Alias ​​para:: sair

5

import

(: i) Importar uma classe para o namespace

6

:display

(: d) Exibir o buffer atual

7

:clear

(: c) Limpe o buffer e reinicie o contador de prompt

8

:show

(: S) Mostrar variáveis, classes ou importações

9

:inspect

(: n) Inspecione uma variável ou o último resultado com o navegador de objetos GUI

10

:purge

(: p) Limpe variáveis, classes, importações ou preferências

11

:edit

(: e) Editar o buffer atual

12

:load

(: l) Carregar um arquivo ou URL no buffer

13

.

(:.) Alias ​​para:: carregar

14

.save

(: s) Salve o buffer atual em um arquivo

15

.record

(: r) Grave a sessão atual em um arquivo

16

:alias

(: a) Crie um alias

17

:set

(: =) Definir (ou listar) preferências

18

:register

(: rc) Registra um novo comando com o shell

19

:doc

(: D) Abre uma janela do navegador exibindo o documento para o argumento

20

:history

(: H) Exibir, gerenciar e recuperar o histórico da linha de edição

A unidade fundamental de um sistema orientado a objetos é a classe. Portanto, o teste de unidade consiste em testar dentro de uma classe. A abordagem adotada é criar um objeto da classe em teste e usá-lo para verificar se os métodos selecionados são executados conforme o esperado. Nem todos os métodos podem ser testados, pois nem sempre é prático testar cada coisa. Mas o teste de unidade deve ser conduzido para métodos essenciais e críticos.

JUnit é uma estrutura de teste de código aberto que é o padrão de mercado aceito para o teste de unidade automatizado de código Java. Felizmente, a estrutura JUnit pode ser facilmente usada para testar classes Groovy. Tudo o que é necessário é estender a classe GroovyTestCase que faz parte do ambiente Groovy padrão. A classe de caso de teste Groovy é baseada no caso de teste Junit.

Escrevendo um Caso de Teste Simples Junit

Vamos supor que temos a seguinte classe definida em um arquivo de classe de aplicativo -

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;
   }  
}

O resultado do programa acima é fornecido abaixo.

Joe1

E agora suponha que quiséssemos escrever um caso de teste para a classe Aluno. Um caso de teste típico seria parecido com o abaixo. Os seguintes pontos precisam ser observados sobre o código a seguir -

  • A classe de caso de teste estende a classe GroovyTestCase
  • Estamos usando a instrução assert para garantir que o método Display retorne a string correta.
class StudentTest extends GroovyTestCase {
   void testDisplay() {
      def stud = new Student(name : 'Joe', ID : '1')
      def expected = 'Joe1'
      assertToString(stud.Display(), expected)
   }
}

The Groovy Test Suite

Normalmente, à medida que o número de testes de unidade aumenta, fica difícil continuar executando todos os casos de teste um por um. Portanto, o Groovy fornece um recurso para criar um conjunto de testes que pode encapsular todos os casos de teste em uma unidade lógica. O seguinte codesnippet mostra como isso pode ser alcançado. As seguintes coisas devem ser observadas sobre o código -

  • O GroovyTestSuite é usado para encapsular todos os casos de teste em um.

  • No exemplo a seguir, estamos assumindo que temos dois arquivos de caso de teste, um chamado StudentTest e o outro é EmployeeTest que contém todos os testes necessários.

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())

O mecanismo de modelo do Groovy opera como uma mala direta (a adição automática de nomes e endereços de um banco de dados a cartas e envelopes para facilitar o envio de correspondência, especialmente publicidade, para muitos endereços), mas é muito mais geral.

Modelagem Simples em Strings

Se você pegar o exemplo simples abaixo, primeiro estamos definindo uma variável de nome para conter a string “Groovy”. Na instrução println, estamos usando $ symbol para definir um parâmetro ou modelo onde um valor pode ser inserido.

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

Se o código acima for executado no groovy, a seguinte saída será mostrada. A saída mostra claramente que o $ name foi substituído pelo valor que foi atribuído pela instrução def.

Motor de modelo simples

A seguir está um exemplo de SimpleTemplateEngine que permite usar scriptlets semelhantes a JSP e expressões EL em seu modelo para gerar texto parametrizado. O mecanismo de modelagem permite vincular uma lista de parâmetros e seus valores para que possam ser substituídos na string que possui os espaços reservados definidos.

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 o código acima for executado no groovy, a seguinte saída será mostrada.

Vamos agora usar o recurso de modelagem para um arquivo XML. Como primeira etapa, vamos adicionar o código a seguir a um arquivo chamado Student.template. No arquivo a seguir, você notará que não adicionamos os valores reais para os elementos, mas os marcadores. Então $ name,$is and $assunto são colocados como espaços reservados que precisarão ser substituídos em tempo de execução.

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

Agora vamos adicionar nosso código de script Groovy para adicionar a funcionalidade que pode ser usada para substituir o modelo acima por valores reais. As seguintes coisas devem ser observadas sobre o código a seguir.

  • O mapeamento dos marcadores de posição para valores reais é feito por meio de um binding e um SimpleTemplateEngine. A ligação é um mapa com os marcadores de posição como chaves e as substituições como os valores.

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 o código acima for executado no groovy, a seguinte saída será mostrada. Na saída, pode-se ver que os valores foram substituídos com êxito nos marcadores de posição relevantes.

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

StreamingTemplateEngine

O mecanismo StreamingTemplateEngine é outro mecanismo de modelos disponível no Groovy. Isso é equivalente ao SimpleTemplateEngine, mas cria o modelo usando fechamentos graváveis, tornando-o mais escalonável para modelos grandes. Especificamente, este mecanismo de modelo pode lidar com strings maiores que 64k.

A seguir está um exemplo de como StreamingTemplateEngine são usados ​​-

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 o código acima for executado no groovy, a seguinte saída será mostrada.

This Tutorial is Groovy The Topic name is Templates

XMLTemplateEngine

O XmlTemplateEngine é usado em cenários de modelos em que tanto a origem do modelo quanto a saída esperada devem ser XML. Os modelos usam o normal${expression} and $notações de variáveis ​​para inserir uma expressão arbitrária no modelo.

A seguir está um exemplo de como XMLTemplateEngine é usado.

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 o código acima for executado no groovy, a seguinte saída será mostrada

Joe
    
    
   1
    
    
   Physics

A programação de metaobjetos ou MOP pode ser usada para invocar métodos dinamicamente e também criar classes e métodos dinamicamente.

Então o que isso quer dizer? Vamos considerar uma classe chamada Student, que é uma classe vazia sem variáveis ​​de membro ou métodos. Suponha que você tenha que invocar as seguintes instruções nesta classe.

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

Agora, na programação de metaobjetos, mesmo que a classe não tenha a variável de membro Name ou o método Display (), o código acima ainda funcionará.

Como isso pode funcionar? Bem, para que isso funcione, é necessário implementar a interface GroovyInterceptable para se conectar ao processo de execução do Groovy. A seguir estão os métodos disponíveis para esta interface.

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) 
}

Portanto, na descrição da interface acima, suponha que se você tivesse que implementar invokeMethod (), ele seria chamado para cada método que existe ou não existe.

Propriedades ausentes

Então, vamos dar uma olhada em um exemplo de como podemos implementar a programação de metaobjetos para propriedades ausentes. As seguintes coisas chaves devem ser observadas sobre o código a seguir.

  • A classe Student não possui nenhuma variável de membro chamada Nome ou ID definida.

  • A classe Student implementa a interface GroovyInterceptable.

  • Existe um parâmetro chamado dynamicProps que será usado para manter o valor das variáveis ​​de membro que são criadas instantaneamente.

  • Os métodos getproperty e setproperty foram implementados para obter e definir os valores das propriedades da classe em tempo de execução.

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]
   } 
}

A saída do código a seguir seria -

Joe 
1

Métodos ausentes

Então, vamos dar uma olhada em um exemplo de como podemos implementar a programação de metaobjetos para propriedades ausentes. As seguintes coisas importantes devem ser observadas sobre o código a seguir -

  • A classe Student agora implementa o método invokeMethod, que é chamado independentemente de o método existir ou não.

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"
   }
}

A saída do código a seguir deve ser mostrada abaixo. Observe que não há erro de exceção de método ausente, embora o método Display não exista.

Joe 
1

Metaclasse

Esta funcionalidade está relacionada à implementação MetaClass. Na implementação padrão, você pode acessar campos sem invocar seus getters e setters. O exemplo a seguir mostra como, usando a função metaClass, podemos alterar o valor das variáveis ​​privadas na 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;
   } 
}

A saída do código a seguir seria -

Joe 
Mark

Método ausente

Groovy apóia o conceito de methodMissing. Este método difere de invokeMethod porque só é invocado em caso de falha no envio do método, quando nenhum método pode ser encontrado para o nome e / ou os argumentos fornecidos. O exemplo a seguir mostra como o métodoMissing pode ser usado.

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"
   }  
}

A saída do código a seguir seria -

Joe 
1 
Missing method