0% acharam este documento útil (0 voto)
15 visualizações6 páginas

Blocos Estáticos

Enviado por

Danib12
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
15 visualizações6 páginas

Blocos Estáticos

Enviado por

Danib12
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 6

Fundamentos de JAVA

Escrevendo Blocos Estáticos em JAVA


Autor: Carlos Santiago – Certificado JAVA 1.4 (SCJP)
e-mail: [email protected]

Introdução
Uma aspecto importante da programação JAVA é a inicialização apropriada de
variáveis.
As variáveis de instância em JAVA (variáveis globais), se não forem
inicializadas recebem valores default. Os tipos primitivos recebem valores zero
e os objetos são inicializados com null.
Já as variáveis locais não são inicializadas automaticamente e você deve
inicializá-las.
Mas, às vezes, ocorrem situações onde uma variável requer uma inicialização mais
complexa ou as variáveis devem ser inicializadas antes mesmo da classe ser
instânciada. Um exemplo seria o caso em que você precisaria setar alguns
parâmentros de sistema como a data e hora locais.

TimeZone tz = TimeZone.getTimeZone("AGT");
tz.setID("GMT-04:00");
TimeZone.setDefault(tz);

Neste código TimeZone deve ser setado com os parâmetros convenientes antes que
qualquer ação seja realizada pela classe a ser instânciada. Mas porque não setar
estes parâmentros no construtor da classe ? Pois isso garantiria que as
configurações seriam estabelecidas assim que o objeto fosse criado pelo
construtor. Mas se sua classe possuir métodos estáticos e vc acessá-los sem
fazer uma instância da classe ? Isso ocorre com classes que possuam métodos
estáticos e não-estáticos, neste caso os parâmtros que vc precisa que sejam
configurados para o funcionamento correto da classe não o serão.
É nessa hora que você deve fazer uso de blocos estáticos de inicialização.

O que são blocos estáticos ?


Existem 3 coisas que você pode colocar dentro de uma classe que não precisa
estar dentro de método: variáveis de instância, classes internas e blocos
estáticos.
As variáveis de instância você já conhece, classes internas são classes dentro
de classes (ver nosso artigo "Escrevendo Classes Internas com JAVA") e os blocos
estáticos ?
Analisemos o seguinte trecho de código:

static
{
for(int i = 0; i < var2; i++)
{
var3 += var1;
}
System.out.println("Este é um bloco estático.");
}

Um bloco estático em JAVA começa com palavra chave static e todo o código
colocado entre as chaves é considerado um bloco de inicialização estático.
Um bloco estático pode estar em qualquer lugar dentro da classe e pode conter
código tão complexo quanto se queria. Também podemos ter mais de um bloco
estático dentro de uma classe.
Os blocos estáticos são executados antes mesmo do construtor da classe, isso
permite que se inicialize variáveis estáticas ou trechos de código antes do
objeto existir.
As variáveis que são declaradas dentro de um bloco estático pertencem ao escopo
do bloco estático, então o trecho de código a seguir é perfeitamente legal:

class Teste
{
static
{
int x;
}

int x =0;
}

Aqui a variável x é declarada dentro do bloco estático e não foi inicializada,


então ela terá o valor default zero. E na mesma classe temos a mesma variável x
sendo utilizada novamente e desta vez sendo inicializada com zero - em se
tratando de uma variável de instância ela não precisaria, necessariamente, ter
sido inicializada.
O próximo código ilustra bem o uso de variáveis de instância, local e de bloco
de inicialização estático:

public class Teste


{
public Teste()
{
int x = 0;
System.out.println(x);
}
static
{
int x = 2;
System.out.println(x);
}

private int x = 1;

public void teste()


{
int x = 1;
System.out.println(x);
}

public static void main(String[] args)


{
Teste t = new Teste();
t.teste();
}
}

Qual a saída deste código ?


Se você imaginou que seria 0,1 e 2, se enganou.A saída deste código é 2, 0 e 1.
Explicaremos por que.
Como afirmamos antes, um bloco estático dentro de uma classe é sempre executado
antes do próprio construtor da classe. Então, a variável x no bloco estático é
inicializada e impressa antes da variável x que se encontra dentro do construtor
da classe.
Difícil de acreditar ? OK, vamos montar uma classe que possa "marcar" os
momentos em que cada variável é inicializada.
O código de exemplo a seguir possui duas classes.
A classe ExemploBlocoEstatico possue um método main() que possue duas flags que
envolvem a instrução Class aClass = Fix.class; Isso nos proporciona saber em que
hora começou a leitura da classe Fix e em que hora esta leitura terminou. Depois
a classe ExemploBlocoEstatico põe a Thread da classe para dormir durante 5
segundos para somente depois fazer uma instância da classe Fix e invocar o
método showData().
A classe Fix é a classe que mais nos interessa aqui. Na classe Fix encontraremos
dois blocos de inicialiazação estáticos que por sua vez são separados por algum
código.
Não há grande mistério na classe Fix a não ser a seguinte questão: numa classe
com UM bloco estático ele será executado antes do construtor da classe. Mas, e
se a classe possuir dois blocos de inicialização estáticos, qual será executado
primeiro ?
A resposta é que o compilador inicializa as variáveis estáticas e todos os
blocos estáticos a medida em que eles vão aparecendo no código.
Na minha máquina a saída para o nosso código de exemplo foi:

1.Iniciou a leitura da classe Fix em: Tue Dec 16 16:50:36 GMT-03:00 2003

2.Primeiro bloco estático finalizado em : Tue Dec 16 16:50:36 GMT-03:00 2003

3.Segundo bloco estático finalizado em: Tue Dec 16 16:50:41 GMT-03:00 2003

4.Finalizou a leitura da classe Fix em: Tue Dec 16 16:50:41 GMT-03:00 2003

5.var3 inicializada em: Tue Dec 16 16:50:36 GMT-03:00 2003

6.var3 é igual a 50

7.var4 inicializada em : Tue Dec 16 16:50:41 GMT-03:00 2003

8.var4 = 4998 milisegundos

9.Classe Fix foi instanciada em: Tue Dec 16 16:50:46 GMT-03:00 2003

Analisemos cada linha deste resultado. A linha 1 apenas nos diz que começamos a
leitura da classe Fix às 16:50:36.
A linha 2 já mostra o resultado da leitura do primeiro método estático da classe
Fix. Repare que apenas chamamos a classe Fix (através de Class aClass =
Fix.class;), mas não criamos o objeto Fix (ainda).
O primeiro bloco estático de Fix foi executado às 16:50:36, ou seja, no mesmo
momento em que a classe foi lida.
A linha 3 nos mostra a hora de finalização do segundo bloco estático: 16
16:50:41. Aqui existe um lapso de 5 segundos entre o final da execução do
primeiro bloco para com o segundo, isso se deve ao fato de que o segundo bloco
põe a classe Fix para dormir 5 segundos.
A linha 4 diz que o final da leitura da classe Fix coincide com o final da
execução do segundo bloco estático: 16 16:50:41.
A linha 5 nos mostra o momento em que a variável var3 foi inicializada e isso
coincide com o tempo de finalização do primeiro bloco estático.
A linha 6 apenas nos mostra o valor de var3 depois do laço for.
A linha 7 mostra o instante em que var4 foi inicializada, que por sua vez
coincide com o momento de finalização do segundo bloco estático.
A linha 8 atribui a var4 a diferença de tempo entre os momentos de
inicialiazação do primeiro bloco estático e o segundo bloco estático (em
milisegundos) que nós dá aproximadamente 5 segundos.
E finalmente a linha 9 nos mostra o momento em que a classe Fix foi instânciada,
chamando o seu construtor e atribuindo um valor para data3. Ou seja, o objeto
Fix foi construído extamente 10 segundos depois dos dois blocos estáticos terem
sido executados. São 10 segundos porque o segundo bloco estático põe a classe
Fix para dormir 5 segundos e depois a classe ExemploBlocoEstatico dorme mais 5
segundos antes de fazer a instância da classe Fix.
Com isso demostramos que os blocos estáticos são sempre executados antes do
construtor de uma classe.

import java.util.Date;

public class ExemploBlocoEstatico


{
public static void main(String[] args)
{
//Mostra o início da leitura da classe
System.out.println("Iniciou a leitura da classe Fix em: " + new Date());

//Chama a classe Fix usando a classe literal Class


Class aClass = Fix.class;

//Mostra o final da leitura da classe


System.out.println("Finalizou a leitura da classe Fix em: " + new Date());

//Põe a classe para dormir 5 segundos


try
{
Thread.currentThread().sleep(5000);
}
catch(InterruptedException ex)
{
ex.printStackTrace();;
}
//Instancia a classe A e chama o método showData()
new Fix().showData();
}
}

class Fix
{
static int var1 = 5;
static int var2 = 10;
static int var3;
static long var4;

static Date data1;


static Date data2;

Date data3;

static
{
//primeiro bloco estático
//inicializa a variável data1 com a hora da inicialização
//e atribui valor a var3.
data1 = new Date();
for(int i = 0; i < var2; i++)
{
var3 += var1;
}
System.out.println("Primeiro bloco estático finalizado em : " + new Date());
}

//construtor
Fix()
{
//Instancia a variável data3 com a hora da inicialização
data3 = new Date();
}

//este método mostra os tempos das variáveis


void showData()
{
System.out.println("var3 inicializada em: " + data1);
System.out.println("var3 é igual a " + var3);
System.out.println("var4 inicializada em : " + data2);
System.out.println("var4 = " + var4 + " milisegundos");
System.out.println("Classe Fix foi instanciada em: " + data3);
}

//segundo bloco estático


static
{
try
{
//Dorme 5 segundos
Thread.currentThread().sleep(5000);
}
catch(InterruptedException ex)
{
ex.printStackTrace();;
}

data2 = new Date();


//faz a diferença entre o tempo de um bloco estático e o outro (em
milisegundos)
var4 = data2.getTime() - data1.getTime();
System.out.println("Segundo bloco estático finalizado em: " + new Date());
}
}
Conclusão
Vimos que inicialização de variáveis é um ponto importante da programação JAVA.
Os blocos estáticos são necessários quando se precisa fazer a inicialização de
variáveis ou a execução de algum código antes mesmo do objeto ser criado, ou
melhor, independnete dele ser criado ou não, só o fato de usar tal classe já
causa a inicialização imediata de suas veriáveis e/ou executa um bloco estático.
Também observamos que uma classe pode ter quantos blocos estáticos forem
necessários e que estes blocos serão executados na ordem em que forem aparecendo
no código.
Uma última observação a fazer é que estes blocos serão executados apenas uma
única vez (característica do static) não importa quantas vezes a classe seja
instânciada ou apenas lida (em se tratando de uma classe com métodos estáticos e
não-estáticos).

Referência
The Essence of OOP using JAVA, Static Initializer Blocks by Richard G. Baldwin
in http://www.developer.com/java/other/article.php/2238491

Você também pode gostar