[RESOLVIDO] Dúvida em Bloco Static e Bloco de Instância

4 respostas
emmanuelrock

Olá a todos… Neste tópico http://www.guj.com.br/posts/list/39369.java um amigo disse que o bloco static é executado antes do construtor, baseado nisso posso afirmar que o bloco static é executado antes do bloco de instância?

Vejam neste código que representa uma carteada de baralho:

Classe Card:

package teste;

import java.util.ArrayList;
import java.util.List; 

public class Card {
	public enum Rank { AS, DOIS, TRES, QUATRO, CINCO, SEIS,
	                 SETE, OITO, NOVE, DEZ, VALETE, DAMA, REI}

    public enum Suit { PAUS, OURO, COPAS, ESPADAS }

    private  final Rank rank;
    private  final Suit suit;
    
    private Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    {
        System.out.println("Instância!");	    	
    }
    
    public Rank getRank() { 
    	return rank; 
    }
    
    public Suit getSuit() { 
    	return suit; 
    }
    
    public String toString() { 
    	return rank + " de " + suit + "\n";
    }

    private static final List<Card> protoDeck = new ArrayList<Card>();
    
    // Initialize prototype deck
    static {
        for (Suit suit : Suit.values())
            for (Rank rank : Rank.values())
                protoDeck.add(new Card(rank, suit));
        System.out.println("Classe!");
    }

    public static ArrayList<Card> newDeck() {
    	// Return copy of prototype deck
        return new ArrayList<Card>(protoDeck); 
    }
    
   
}

Classe Deal:

package teste;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Deal {
	
	public static void main(String args[]) {
        int numHands = Integer.parseInt("1");
        int cardsPerHand = Integer.parseInt("5");
        List<Card> deck  = Card.newDeck();
        Collections.shuffle(deck);
        for (int i=0; i < numHands; i++)
            System.out.println(deal(deck, cardsPerHand));
    }

    public static ArrayList<Card> deal(List<Card> deck, int n) {
         int deckSize = deck.size();
         List<Card> handView = deck.subList(deckSize-n, deckSize);
         ArrayList<Card> hand = new ArrayList<Card>(handView);
         handView.clear();
         return hand;
     }

}

O resultado em ordem de impressão é:

  • 52 saídas de strings “Instância”;
  • 1 saída de string “Classe”;
  • 5 strings representado a “mão” do jogo;

Observando o resultado nota-se que o bloco de instância foi executado primeiro ou pelo menos sua saída foi feita antes do bloco static, é isso mesmo, o bloco static é executado depois?

Abraço…

4 Respostas

emmanuelrock

Já descobri o porquê:

static {  
         for (Suit suit : Suit.values())  
             for (Rank rank : Rank.values())  
                 protoDeck.add(new Card(rank, suit));  
         System.out.println("Classe!");  
 }

É que os 52 objetos são instanciados no bloco static, antes da impressão da string “Classe”. Mas pelo menos fica um bom exemplo do que se pode fazer com Enums.

Que loucura, eu mesmo pergunto eu mesmo respondo kkkkk…

B

emmanuelrock:
Já descobri o porquê:

static {  
         for (Suit suit : Suit.values())  
             for (Rank rank : Rank.values())  
                 protoDeck.add(new Card(rank, suit));  
         System.out.println("Classe!");  
 }

É que os 52 objetos são instanciados no bloco static, antes da impressão da string “Classe”. Mas pelo menos fica um bom exemplo do que se pode fazer com Enums.

Que loucura, eu mesmo pergunto eu mesmo respondo kkkkk…

Outra coisa que dá pra ver disso é que o bloco static foi executado somente uma vez. Se você colocasse essa inicialização na instância ou no contrutor, provavelmente chegaria a um StackOverflow ou OutOfMemory errors.

ViniGodoy

Os blocos estáticos são executados assim que a classe é carregada na memória. Ou seja, antes mesmo da primeira instância ser criada. Um exemplo está em classes onde existe um atributo estático público, como essa aqui:

public class Exemplo {
   public static final List<String> usuarios;

   static {
        List<String> usuarioList = new ArrayList<String>();
        usuarioList.add("Vinicius");
        usuarioList.add("Emmanuel");       
        usuarios = Collections.unmodifiableList(usuarioList);
    }

    //Parte não estática da classe aqui
}
Esse é um exemplo de como fazer uma constante que é também uma lista. Note que podemos acessa-la diretamente, sem mesmo criar uma instância:
System.out.println(Exemplo.usuarios);

E nesse caso o bloco estático será executado.

Os blocos não estáticos rodam antes do construtor, logo depois da inicialização dos atributos feita de forma "direta". Na verdade, esses blocos foram criados para fazer inicializações complexas (ou "substituir" o construtor em inner classes), e por isso rodam dessa forma. O que é bizarro é que você pode ter mais de um bloco desses e, nesse caso, rodam na ordem que aparecem, sempre antes do construtor.

Finalmente, é executado o construtor.

Spool

A sequencia é:

Blocos estáticos;

Blocos de instância;

Construtores;
Criado 14 de agosto de 2009
Ultima resposta 14 de ago. de 2009
Respostas 4
Participantes 4