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