Como funcionam os inicializadores em Java?
Neste post, iremos aprender o que é a inicialização implícita de variável de instância ou de classe, bloco inicializador de instância e bloco inicializador estático.
Caso você não saiba o que é uma variável de classe e de instância, veja este post aqui antes.
Inicialização implícita de variável de instância ou de classe
Veja a variável de classe i
e a variável de instância d
no código abaixo:
public class Inicializadores { static int i; double d; public static void main(String[] args) { Inicializadores i = new Inicializadores(); System.out.println(Inicializadores.i); System.out.println(i.d); } }
A saída desse programa é: 0 0.0
Repare que em momento algum o valor 0 é atribuido para a variável de classe i
nem o valor 0.0 é atribuído para a variável de instância d
.
Quando uma variável primitiva de instância ou de classe não é inicializada explicitamente pelo programador, ela assume um valor padrão implicitamente. No caso do tipo int, esse valor é 0. E no caso do tipo double, esse valor é 0.0.
Os valores padrão de cada um dos tipos primitivos da linguagem Java são os seguintes:
-
byte: 0
-
short: 0
-
int: 0
-
long: 0
-
float: 0.0
-
double: 0.0
-
boolean: false
-
char: ‘\0’
O valor padrão para o tipo char é o unicode 0: ‘\0’.
E o que acontece com os tipos de referência? São todos inicializados com null. Observe o código abaixo:
public class Inicializadores { static String s; Pessoa p; public static void main(String[] args) { Inicializadores i = new Inicializadores(); System.out.println(Inicializadores.s); System.out.println(i.p); } }
A saída desse programa é: null null
É muito importante observar que o comportamento da inicialização com valores padrão para os membros de uma classe, nesse caso variáveis de instância e variáveis de classe, não ocorre com variáveis locais como as variáveis declaradas dentro de um método.
O programa abaixo não compila:
public class Inicializadores { public static void main(String[] args) { int x; System.out.println(x); } }
Ocorre um erro cuja descrição avisa que a variável local x
não foi inicializada.
Bloco inicializador de instância
Normalmente, você colocaria o código para inicializar as variáveis de instância dentro de um construtor. Esse de bloco é um bloco normal que se inicia com ‘{‘ e termina com ‘}’. Ele tem a seguinte aparência:
{ temperaturaAtual = obterTemperaturaAtual(); publicarTemperatura(temperaturaAtual); }
E fica posicionado dentro do corpo da classe. Desta forma:
public class Inicializadores { double temperaturaAtual; private double obterTemperaturaAtual() { // Código válido que busca a temperatura atual de um servidor. } private static void publicarTemperatura(double temperatura) { // Código válido que publica a temperatura para os observadores. } { temperaturaAtual = obterTemperaturaAtual(); publicarTemperatura(temperaturaAtual); } public static void main(String[] args) { Inicializadores i = new Inicializadores(); System.out.println(i.temperaturaAtual); } }
A saída desse programa é o retorno do método obterTemperaturaAtual().
A vantagem de usar um bloco inicializador de instância as dá pela razão de que o compilador Java copia o código dentro do bloco e o adiciona em todos os construtores da sua classe. Assim, você não precisa repetir o mesmo código em todos seus construtores.
Bloco inicializador estático
O bloco inicializador estático tem a mesma aparência do bloco inicializador de instância com a exceção de que ele se inicia com a palavra reservada static e assim como um método estático, só pode manipular variáveis e métodos de classe.
static { temperaturaAtual = 26.8; publicarTemperatura(temperaturaAtual); }
Ele também fica dentro do corpo da classe da mesma forma do bloco inicializador de instância:
public class Inicializadores { static double temperaturaAtual; private static void publicarTemperatura(double temperatura) { // Código válido que publica a temperatura para os observadores. } static { temperaturaAtual = 26.8; publicarTemperatura(temperaturaAtual); } public static void main(String[] args) { System.out.println(Inicializadores.temperaturaAtual); } }
Ordem dos inicializadores
Dentro das nossas classes é muito comum termos mais de um bloco inicializador estático, bloco inicializador de instância, variáveis de classe e variáveis de instância. Qual é a ordem de execução desses componentes?
A regra da inicialização é muito simples:
- Execute todos os componentes estáticos na ordem em que eles aparecem.
- Execute todos os componentes de instância na ordem em que eles aparecem.
- Execute o construtor.
Qual é a saída do programa abaixo?
public class Inicializadores { static { s1 = metodo1("a"); } public Inicializadores() { s1 = metodo1("g"); } static String s1 = metodo1("b"); String s3 = metodo1("d"); { s1 = metodo1("e"); } static String s2 = metodo1("c"); String s4 = metodo1("f"); private static String metodo1(String s) { System.out.println(s); return s; } public static void main(String args[]) { Inicializadores it = new Inicializadores(); } }
A saída é: a b c d e f g
De acordo com as regras, devemos procurar pelos componentes estáticos e executá-los na ordem em que aparecem. Os componentes estáticos em ordem são os seguintes:
static { s1 = metodo1("a"); } static String s1 = metodo1("b"); static String s2 = metodo1("c");
A execução dessas instruções resulta em: a b c.
Agora devemos procurar pelos componentes de classe. Ele são os seguintes em ordem:
String s3 = metodo1("d"); { s1 = metodo1("e"); } String s4 = metodo1("f");
A execução dessas instruções resulta em: d e f.
O último componente a ser executado é o construtor:
public Inicializadores() { s1 = metodo1("g"); }
O que resulta em: g.
Comments
1 Comment
[…] http://high5devs.com/2014/12/como-funcionam-os-inicializadores-em-java/ […]
Leave a Comment