VidaGeek.net

Linux, Open-source, Programação e Produtividade

Author Archive

INC - Bloco Estático

Em Java, existe um bloco de código que é executado no momento em que o ClassLoader pega a sua classe e carrega ela. Isso ocorre antes de existir uma instância da sua classe.


public class Teste {
	public static void main(String []args){
		System.out.println("Antes de criar a variável");
		A a;
		System.out.println("Depois de criar a variável");
		//Vamos criar 10 instâncias de A
		for (int i = 0; i < 10; i++)
			a = new A();
		System.out.println("Depois de criar a instância");
	}
}

class A {

	static {
		System.out.println("Bloco Estático");
	}

	A(){
		System.out.println("Construtor");
	}
}

se você rodar esse código, a saída será:


Antes de criar a variável
Depois de criar a variável
Bloco Estático
Construtor
Construtor
Construtor
Construtor
Construtor
Construtor
Construtor
Construtor
Construtor
Construtor
Depois de criar a instância

Notem que o ClassLoader coloca a sua classe na memória apenas uma vez, independente de quantas classes você instancia (ok. Eu já ouvi histórias de magos que conseguem fazer a VM executar o bloco estático várias vezes sem trocar o ClassLoader, mas não faço idéia de como fazer isso.).

E Antes que os mais rigorosos gritem comigo, nada garante que a variável vai ser alocada entre as duas primeiras chamadas ao println. A VM pode simplesmente criar a variável antes das chamadas.

Posts Relacionados:

  • INC - Pré construtores
  • Dia C - Pilha do C
  • Combatendo Spammers
  • ACM ICPC - Brasil na maratona de programação 2008
  • Dia C - Tuning
  • Guia Latex - Parte II: O Básico
  • Dia C - Ponteiros e Aritmética de Ponteiros.
  • Acompanhe-nos por RSS, por Email ou via Twitter.

  • 0 Comments
  • Filed under: Dicas, Java, Programacao
  • INC - Long Switch?

    Uma peculiaridade estranha do switch do java é que ele não funciona para o tipo long.

    O switch funciona apenas para byte, short, char e int.

    
    public class Teste {
    	public static void main(String []args){
    		long l = 10;
    		switch (l){
    			case 10: System.out.println("Isso não compila");
    		}
    	}
    }
    

    O código acima não compila. Isso acontece porque o switch espera um int (porque isso acontece já é outra história) e um long não pode ser convertido para int sem um cast, por causa da possível perda de precisão (afinal cabe muito mais coisa dentro de um long do que dentro de um int).

    Todos os outros tipos podem ser promovidos para int sem nenhum problema (pois no int cabe mais do que em um byte, short ou char).

    Em Java, T caber em O significa min(O) < min(T) e max(O) > max(T). Isso também vale para float e double, o que nos leva a montar a seguinte sequência de promoção automática:

    char -> int
    byte -> short -> int -> long -> float -> double

    O que parece estranho é o long usar 64 bits enquanto que o float usa só 32. Mas como obedecem à regra acima, a promoção é feita do mesmo jeito.

    Posts Relacionados:

  • YACP - Variáveis e Tipos Primitivos
  • Benchmark TreeSet x HashSet
  • Linguagens de programação - Smalltalk
  • Dia C - Modificadores e extensões GNUC
  • Acompanhe-nos por RSS, por Email ou via Twitter.

  • 2 Comments
  • Filed under: Dicas, Java, Programacao
  • INC - Pré construtores

    Java possui um bloco de código que é executado antes dos contrutores da sua classe, mas depois que sua classe já está carregada para a memória.

    
    public class Teste {
    	public static void main(String []args){
    		A a;
    		//Vamos criar 3 instâncias de A
    		for (int i = 0; i < 3; i++)
    			a = new A();
    		System.out.println("Depois de criar a instância");
    	}
    }
    
    class A {
    
    	static {
    		System.out.println("Bloco Estático");
    	}
    
    	{
    		System.out.println("Pré Contrutor");
    	}
    
    	A(){
    		this(0);
    		System.out.println("Construtor sem parâmetro");
    	}
    
    	A(int i){
    		System.out.println("construtor com parâmetros");
    	}
    }
    

    Rodando esse código estranho, a saída é a seguinte:

    
    Bloco Estático
    Pré Contrutor
    construtor com parâmetros
    Construtor sem parâmetro
    Pré Contrutor
    construtor com parâmetros
    Construtor sem parâmetro
    Pré Contrutor
    construtor com parâmetros
    Construtor sem parâmetro
    Depois de criar a instância
    

    Notem que o pré construtor só é executado uma vez para cada instância que você cria, independente se você chama vários construtores.

    Mas a parte mais assustadora é que você pode ter vários pré construtores, e eles são executados na ordem em que aparecem na sua classe (quero ver alguém falar bem de Java agora ;) )

    
    public class Teste {
    	public static void main(String []args){
    		A a = new A();
    	}
    }
    
    class A {
    
    	{
    		System.out.println("Pré Construtor de Cima");
    	}
    
    	A(){
    		System.out.println("Construtor");
    	}
    
    	{
    		System.out.println("Pré Contrutor de Baixo");
    	}
    }
    

    A saída é:

    
    Pré Construtor de Cima
    Pré Contrutor de Baixo
    Construtor
    

    Bem feio, não?

    Posts Relacionados:

  • INC - Pilha de Construtores
  • INC - Colisão de Nomes de Métodos
  • UTF-8 no Latex
  • INC - Pequeno + Pequeno == Grande?
  • INC - Bloco Estático
  • INC - Labelled Loops
  • Mirror DSL
  • Acompanhe-nos por RSS, por Email ou via Twitter.

  • 4 Comments
  • Filed under: Dicas, Java, Programacao
  • INC - Colisão de Nomes de Métodos

    O que acontece quando uma classe sua implementa duas interfaces que tem um método com o mesmo nome? Compila!

    
    interface A {
    	void x();
    }
    
    interface B {
    	void x();
    }
    
    class C implements A, B {
    	public void x() {
    	}
    }
    

    E quando sua classe herda um método que tem o mesmo nome do método de uma interface que ela implementa? Também compila!

    
    class A {
    	void x(){
    	}
    }
    
    interface B {
    	void x();
    }
    
    class C extends A implements B {
    	public void x() {
    	}
    }
    

    Notem que A não precisa implementar B.

    E quando você faz herança múltipla de interfaces? Mais uma que compila.

    
    interface A {
    	void x();
    }
    
    interface B {
    	void x();
    }
    
    interface C extends A,B {
    
    }
    

    Essas aqui eu só acreditei na hora em que o compilador simplesmente não reclamou. Se um dia antes de eu fazer esses testes me perguntassem o que acontecia, eu falaria sem medo nenhum que não compilava. Mas compila.

    Posts Relacionados:

  • YACP - Variáveis e Tipos Primitivos
  • INC - Labelled Loops
  • SNL - Guerra e Paz
  • Yahoo Hack Day 2008
  • Linguagens de programação - Prolog
  • FISL 8.0: Entrevista com Guilherme Silveira, um dos ganhadores da Arena
  • Acompanhe-nos por RSS, por Email ou via Twitter.

  • 6 Comments
  • Filed under: Dicas, Java, Programacao

  • Publicidade