Press enter to see results or esc to cancel.

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:

  1. Execute todos os componentes estáticos na ordem em que eles aparecem.
  2. Execute todos os componentes de instância na ordem em que eles aparecem.
  3. 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.
Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone
Comments

Leave a Comment