Função após construtor

36 respostas
tabocu

Como posso executar uma ação depois da chamada de um construtor?

public class Classe{

    public Classe(){

    }

    private void acao(){

    }

}

Quando eu chamar o construtor da classe depois do construtor seja automaticamente executado outra função

36 Respostas

T

Beleza ?

Se você colocar a chamada da ação no construtor, não resolve ?

drigo.angelo
public class  Classe{  
      
        public Classe(){  
        //...
        acao();
        }  
      
        private void acao(){  
      
        }  
     
   }
:?: Se fizer assim:
public class  Classe{  
      
        public Classe(){  
        
        }  
      
         //Ação:
        {  
          ... 
        }  
     
   }
Acho que ele executa antes.
opa_roa

O que voce que fazer de ação!?
Não entendi muito bem, voce faz o construtor e depois cria outros metodos?!

tabocu

tentei
nao deu certo =/

L

O que exatamente vc quer amigo??

tabocu

Que quando eu chamar o construtor da classe depois do construtor seja automaticamente executado outra função

L

Existem duas maneiras de fazer isso…

uma delas eh chamando a funçao que vc quer logo depois de criar a instancia da classe:

exemplo:

//Chama o construtor automaticamente
Classe objeto = new Classe();
//chama o metodo que vc ker
objeto.metodo();

ou entrao vc pode chamar a funçao dentro do proprio construtor, como citou nosso amigo la em cima:

public class Classe{
       public Classe(){
             metodo();
      }
      public void metodo(){
      }
}

se nao funcionou é pq vc esta fazendo algo errado…
poste o codigo modificado…

tabocu

A primeira forma não é valida pois isso não seria automaticamente e a segunda não é depois, é durante

L

intaum, boa sorte!

tabocu

Obrigado lucas =)

L

So por curiosidade man…

Qual é exatamente o enunciado da questao??

Se é que isso é uma questao…

tabocu

se tem alguma forma de que uma função seja executada automaticamente depois que o objeto acabr de ser construido

L

particulamente, nunca vi alguem fazendo isso…

ou o porque disso…

o.O

mas enfim…

R

tirando o jeito que o lucas colocou ae, pode até ter mas dae ja não é algo muito viável ( e útil ) de se fazer…

vc pode colocar um boolean global como false e no contrutor setando ele como true… dae numa outra thread vc ficaria lendo esse boolean e qndo fosse true esse thread iria iniciar o metodo q vc queria

Felagund
drigo.angelo:
public class  Classe{  
      
        public Classe(){  
        //...
        acao();
        }  
      
        private void acao(){  
      
        }  
     
   }
se isso não funcionou, vc está fazendo algo muito errado, posta seus codigos ai.
kenneth

Fala brow,

Eu acho que a chamada ao metodo no final do construtor resolve…
Se nao me engano, quando voce instancia uma classe, o construtor dela chama primeiro os construtores de suas
superclasses, depois disso executa o seu proprio codigo do construtor…

Entao, se voce fizer…

public class Teste1 {
   public Teste1 (){
     // automaticamente chama os construtores das super classes...

    // Agora, executa o proprio construtor
    // Imprime algo...;
    System.out.println("bla bla bla");
    // Instancia algo...
    String str = new String("bla!");

    // aqui, ja acabou o "papel" do construtor, e chama o metodo...
    metodo1();    
   }

   public void metodo1(){
      System.out.println("Oooopa...");
   }
}

… o metodo metodo1 sera chamado automaticamente e apos o termino do trabalho do construtor…

Abraco!

tabocu

Vou mostrar o motivo:

public class Malha extends Group <SDEE,SDEE,Regiao>{

	public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
		super.parent.malha.addGroup(this);
	}
	
}

O método addGroup acessa os atributos para cadastrar o objeto. Como o objeto nao acabou de ser construido a excessão null pointer exception é levantada

tabocu

Claro que se tiver outra forma de contornar esse problema serviria tambem

drigo.angelo

Agooora que fui entender seu problema...

Já testou assim:
public  class Malha extends Group <SDEE,SDEE,Regiao>{  
   
     public Malha(SDEE root, String idExterno) {  
         super(root, idExterno);  
         doIt();
     }  
     
     private void doIt(){
          super.parent.malha.addGroup(this);  
     }
       
 }
Fiz uns testes aqui assim, não sei se retrata seu problema 100% mas funcionou aqui, olha: Pai.java:
public class Pai{
	private Pai[] listaDePais;
	private int count;
	private final int MAX_PAIS = 5;
	
	private String nome;
	private int qtdFilhos;
	
	public Pai(String nome, int qtdFilhos){
		listaDePais = new Pai[MAX_PAIS];
		count = 0;
		this.nome = nome;
		this.qtdFilhos = qtdFilhos;
	}
	
	protected boolean addPai(Pai p){
		if(count <= MAX_PAIS){
			listaDePais[count++] = p;
			System.out.println("Pai adicionado com sucesso");
			System.out.println();
			return true;
		}
		System.out.println("Pai nao foi adicionado com sucesso");
		return false;
	}
	
	public void imprimeLista(){
		for(Pai p : listaDePais){
			System.out.println(p);
		}
	}
	
	public String getNome(){
		return nome;
	}
	
	public int getQtdFilhos(){
		return qtdFilhos;
	}
	
	public String toString(){
		return "{Nome - "+ getNome() + ", Quant Filhos - " + getQtdFilhos()+"}";
	}
}
classe filha- PaiSub.java:
public class PaiSub extends Pai{
	private String mulher;
	
	public PaiSub(String nome, int qtdFilhos, String nomeMulher){
		super(nome, qtdFilhos);
		System.out.println("Finalizou construtor da classe Pai... Iniciando operacoes do construtor de PaiSub...");
		System.out.println();
		mulher = nomeMulher;
		
		System.out.println("Finalizou inicializacao de PaiSub. Chamando metodo que ira adiciona-lo...");
		System.out.println();
		runAfterInicialization();
	}
	
	private void runAfterInicialization(){
		System.out.println("Chamando metodo da classe Pai...");
		System.out.println();
		addPai(this);
	}
	
	public static void main(String... args){
		PaiSub ps = new PaiSub("Mauro da Silva", 3, "Maria Joana Rosa");
		System.out.println();
		ps.imprimeLista();
		System.out.println(ps);
		System.out.println("Fim da execucao!! ");
	}
	
	public String getMulher(){
		return mulher;
	}
	
	public String toString(){
		return "{Nome - "+ getNome() + ", Quant Filhos - " + getQtdFilhos()+ ", Nome da Mulher - "+getMulher()+"}";
	}
}
Saída:
Finalizou construtor da classe Pai... Iniciando operacoes do construtor de PaiSub...

Finalizou inicializacao de PaiSub. Chamando metodo que ira adiciona-lo...

Chamando metodo da classe Pai...

Pai adicionado com sucesso

{Nome - Mauro da Silva, Quant Filhos - 3, Nome da Mulher - Maria Joana Rosa}
null
null
null
null
{Nome - Mauro da Silva, Quant Filhos - 3, Nome da Mulher - Maria Joana Rosa}
Fim da execucao!!
nel

Champ, se quer algo "automatico", use o annotation @PostConstruct
Assim:

public class Classe {
    public Classe {

    }

    @PostConstruct
    public void sayAnything() {
       System.out.println("Olá, chamada "automatica" após o construtor");
   }
}

Resolve seu caso? :)
Abraços.

drigo.angelo

Que estranho… não funcionou aqui :frowning:

Não conhecia essa anotação, fui testar mas dá o erro: “cannot find symbol
symbol : class PostConstruct
location: class PaiSub”

Update (Adicionando): [size=18]<[/size]Antes de eu testar, pesquisei essa annotation, e encontrei na documentação da API d java, no pacote javax.annotations http://download.oracle.com/javaee/5/api/javax/annotation/package-summary.html mas aqui não está encontrando nem mesmo o pacote… precisa de algum framework?? na documentação faz muita referência ao EJB[size=18]>[/size]

nel

É porque trabalha com injenção e há casos particulares para se aplicar esse annotation.
O retorno do método deve ser void e não pode ter parametros, com exceção do EJB.

Ele cita o EJB pois também utiliza de annotation para a injeção da classe.
E não acha o pacote? Tens J2EE na sua máquina? :slight_smile:

rodrigousp

Em geral não é uma boa prática deixar a referência do objeto vazar no construtor.

Seria melhor fazer isso num Factory Method.

tabocu

Boa tarde Nel,

tentei utilizar sua idéia porem, como o drigo.angelo disse, não funcionou e deu o mesmo erro

Veja abaixo o código:

public class Malha extends Group <SDEE,SDEE,Regiao>{

	public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
	}
	
	@PostConstruct  
	public void add(){
		root.malha.addGroup(this);
	}
	
}

Caro rodrigousp,

Poderia me explicar do que se trata este Factory Method?

tabocu

Caro nel,

Descobri que para encontrar o símbolo voce deve importar “import javax.annotation.PostConstruct;”

para de dar erro porem não faz efeito algum

import javax.annotation.PostConstruct;

public class Malha extends Group <SDEE,SDEE,Regiao>{

	public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
	}
	
	@PostConstruct  
	public void add(){
		System.out.print("haaaaaaaaaa");
		root.malha.addGroup(this);
		
	}
	
}
drigo.angelo

Um factory method seria uma boa idéia mesmo ^^

Algo do tipo:
public class  Malha extends Group <SDEE,SDEE,Regiao>{  
     
       private Malha(SDEE root, String idExterno) {   //Repare que é private !
           super(root, idExterno);  
       }  
         
          
       public void add(){  
           root.malha.addGroup(this);  
      }

      public static Malha createInstance(SDEE root, String idExterno){
          Malha m = new Malha(SDEE root, String idExterno);
          root.malha.addGroup(m);
          return m;
      }
      
   }
Assim, qualquer um que quiser uma instância de Malha tem que chamar o createInstance que chama o método que você quer... agora isso só não é 100% seguro para o caso que sua classe Malha seja extendida...
tabocu

Quanto a essa segurança era só declarar o método como final. Porem será que não existe alguma outra forma?

tabocu

Alguma outra forma? Pelo menos de garantir que não vá ocorrer NullPointerException

tabocu

Me deram a idéia de usar Thread pra resolver este problema. A ideia que uma thread separada verificaria se o objeto já está construido más não ta funcionando

Vejam:

public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
		System.out.print(this == null);
		root.malha.addGroup(this);
	}

Imprime no terminal que this não é null mas levanta a exceção NullPointer exception

RafaFloripa

cara o this não pode ser null no construtor

vc tá me falando que eu não posso fazer
um this.atributo no construtor?

tabocu

Eu sei mas pq então levanta null pointer exception?

RafaFloripa

manda o stacktrace ae do nullpointer
e a implementação( se for tua) do addGroup e da classe

tabocu
public class HashID <Type extends Identification> {
	
	private final int next;
	
	private final Hashtable <Integer,Type> id;
	private final Hashtable <String,Type> idExterno;
	
	public HashID(){
		id = new Hashtable<Integer,Type>();
		idExterno = new Hashtable<String,Type>();
		next = 1;
	}
	
	public void addGroup(Type group){
		id.put(new Integer(next), group);
		idExterno.put(group.getIdExterno(), group);
		group.setId(next);
		next++;
	}
	
	public void removeIdentifier(Type identificable){
		this.id.remove(new Integer(identificable.getId()));
		this.idExterno.remove(identificable.getIdExterno());
	}
	
	public Type getIdentificable(String idExterno){
		return this.idExterno.get(idExterno);
	}
	
	public Type getIdentificable(int id){
		return this.id.get(new Integer(id));
	}
}
public class Malha extends Group <SDEE,SDEE,Regiao>{
	
	
	
	public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
		
		root.malha.addGroup(this);
	}
}

A excessão é nullPointerexception e o erro ocorre ná hora de tentar adicionar o objeto na hash table

RafaFloripa

um primitivo final, nao inicializado nem sabia que dava pra fazer isso

se o problema tá na hora de inserir no hashtable
tem que ver se tu realmente deu new nessa classe malha, deve ter dado pois senao nem entraria no metodo
ou entao aquele metodo getIdExterno tá alguma coisa errada

era mais facil ver qual linha dava o erro de null pointer

rodrigousp

A solução do drigo.angelo tá certa e é 100% segura uma vez que não será possível estender a classe Malha (porque o construtor é privado).

[]'s
Rodrigo

nel
tabocu:
Caro nel,

Descobri que para encontrar o símbolo voce deve importar "import javax.annotation.PostConstruct;"

para de dar erro porem não faz efeito algum

import javax.annotation.PostConstruct;

public class Malha extends Group <SDEE,SDEE,Regiao>{

	public Malha(SDEE root, String idExterno) {
		super(root, idExterno);
	}
	
	@PostConstruct  
	public void add(){
		System.out.print("haaaaaaaaaa");
		root.malha.addGroup(this);
		
	}
	
}

O provavél motivo é que não está ocorrendo injeção em sua classe.
Já tive a necessidade de utilizar o annotation @PostConstruct e não obtive problemas.

Creio que deva estar em um contexto diferente do qual está sua classe, como um container.
Leia com atenção pois já postaram soluções interessantes pra você.

Abraços.

Criado 29 de março de 2011
Ultima resposta 31 de mar. de 2011
Respostas 36
Participantes 11