Pegar a instancia de uma classe

Tem como pegar a instancia de uma classe que já está rodando?
Por que no meu aplicativo eu só posso inicializa uma classe uma única vez e queria saber também se tem como “matar” esta instancia que esta rodando?

Vc pode passar null para todas as referências daquele objeto e esperar o garbage collector.

Entretanto acho q no seu caso tem alguma coisa mal explicada…

Ola,

Dê uma olhada no padrão singleton… dae fica facil matar ela.

Hã? É justamente o contrário!

O Singleton não funciona bem em Java. É difícil garantir que o objeto seja realmente singleton.
E, graças ao Garbage Collector, é praticamente impossível matar um Singleton em Java.

Concordo ficou meio confuso…
O aplicativo funciona desta maneira, o usuário pode inicializar um processo, que no meu caso é esta classe que só pode ser inicializada uma única vez, esta classe fica rodando direto, não para, se o usuário fechar o browser e abrir novamente o aplicativo tem que indicar que a classe ainda está rodando.
O usuário também tem a possibilidade de parar o processo, por isso eu preciso pegar a instância da classe.

Hã? É justamente o contrário!

O Singleton não funciona bem em Java. É difícil garantir que o objeto seja realmente singleton.
E, graças ao Garbage Collector, é praticamente impossível matar um Singleton em Java.[/quote]

Haaa… concordo não…

public class Exemplo{
  private static Exemplo instance;
  private String nome;

  public static Exemplo getInstance(){
    if(instance == null){
      instance = new Exemplo();
    }
    return instance;
   }

   public static void killMyself(){
     instance = null;
   }

   public void setNome(String nome){
     this.nome = nome;
   }

   public String getNome(){
    return nome;
   }

Se vc usar um analisador de memoria vera que esta classe saira quando se chamar o killMyself dela. e depois do GC…

[quote=Jedi_FeniX]Concordo ficou meio confuso…
O aplicativo funciona desta maneira, o usuário pode inicializar um processo, que no meu caso é esta classe que só pode ser inicializada uma única vez, esta classe fica rodando direto, não para, se o usuário fechar o browser e abrir novamente o aplicativo tem que indicar que a classe ainda está rodando.
O usuário também tem a possibilidade de parar o processo, por isso eu preciso pegar a instância da classe.[/quote]

Pois é, pra min se isto não é um singleton…

Dá uma olhada no que é este singleton: http://pt.wikipedia.org/wiki/Singleton

Este seu aplicativo seria o que exatamente? Uma thread? Um aplicativo desktop stand-alone? Um aplicativo desktop cliente-servidor?

Você fala dessa classe como se ela fosse algo dissociado do seu aplicativo. Porque diz “quando fechar” e “quando iniciar o aplicativo”, e em seguida diz que independente de fechar ou reiniciar o aplicativo a classe deve ficar “rodando”…

Daria pra resolver relativamente fácil adotando a arquitetura cliente-servidor, mas não sei exatamente qual é a natureza da aplicação…

Abraço…

Singleton em Java é um pepino porque pode sempre ser burlado usando reflection…

Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.

O usuário pode fazer:

//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();

//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.

Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".

Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...

E assim por diante…

Se você levar reflection em conta, tudo pode ser burlado. Não existem padrões.

Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.

O usuário pode fazer:

//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();

//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.

Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".

Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...

E assim por diante…[/quote]

Faz sentido…

[quote=ViniGodoy]

[quote=eclipso]Singleton em Java é um pepino porque pode sempre ser burlado usando reflection...[/quote]

Se você levar reflection em conta, tudo pode ser burlado. Não existem padrões.[/quote]

Tb faz sentido… reflection é uma quebra de padrões terrível… mas as vezes necessário.

Parece que a pergunta foi esquecida…:slight_smile:

Mas retomando, pelo que entendi o que voce que é guardar algum objeto scopo “application”, nao seria isso?

[]´s

Humberto

Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.

O usuário pode fazer:

//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();

//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.

Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".

Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...

E assim por diante…[/quote]

Blz entao apague o metodo killMySelf, que resolve o problema.

Sim, e não se apaga mais o Singleton…
como eu falei desde o início.

Você só consegue apagar o Singleton usando a classe WeakReference. Assim você consegue garantir que não há referências fortes externamente, como a que eu fiz ali.
Mas ainda assim, com Singleton ou sem Singleton, é praticamente impossível “matar” uma instância.

[quote=Jedi_FeniX]Tem como pegar a instancia de uma classe que já está rodando?
Por que no meu aplicativo eu só posso inicializa uma classe uma única vez e queria saber também se tem como “matar” esta instancia que esta rodando?[/quote]

Você pode usar o padrão descrito no .net, chamado “disposable”. O Java usa isso em algumas classes.

Simplesmente, crie um método “close”, “dispose”, “kill” na sua classe.
Após a invocação desse método, marque alguma propriedade “isDisposed” para true e passe a lançar uma exceção de “ObjectDisposedException”, “UnsupportedOperationException” ou “IllegalStateException” sempre que alguém chamar qualquer método.

Não é exatamente a melhor das políticas… mas é uma alternativa interessante em muitos casos.

Sim, e não se apaga mais o Singleton…
como eu falei desde o início.

Você só consegue apagar o Singleton usando a classe WeakReference. Assim você consegue garantir que não há referências fortes externamente, como a que eu fiz ali.
Mas ainda assim, com Singleton ou sem Singleton, é praticamente impossível “matar” uma instância.[/quote]

Nao se apaga?? e que tal:

exemplo = null;

Você está acompanhando toda discussão, ou só respondendo por impulso a última coisa que lê?

Se retirar o método killMySelf, você terá sempre a referência da variável estática, dentro da classe do Singleton.
Como demonstrado, você não pode simplesmente apagar aquela variável estática, sob o risco de quebrar o padrão Singleton.

Portanto, um objeto singleton não será apagado facilmente. Você até pode manter o killMySelf e usar o padrão disposable que descrevi ali em cima. Isso forçaria que quem capturou uma referência externa tenha que libera-la, já que usa-la dispararia exceção.

De qualquer forma, é menos elegante do que manter a instância do singleton ativa para sempre.
Afinal, uma única instância dificilmente ocupa uma quantidade significativa de memória.

[quote=ViniGodoy]Você está acompanhando toda discussão, ou só respondendo por impulso a última coisa que lê?

Se retirar o método killMySelf, você terá sempre a referência da variável estática, dentro da classe do Singleton.
Como demonstrado, você não pode simplesmente apagar aquela variável estática, sob o risco de quebrar o padrão Singleton.

Portanto, um objeto singleton não será apagado facilmente. Você até pode manter o killMySelf e usar o padrão disposable que descrevi ali em cima. Isso forçaria que quem capturou uma referência externa tenha que libera-la, já que usa-la dispararia exceção.

De qualquer forma, é menos elegante do que manter a instância do singleton ativa para sempre.
Afinal, uma única instância dificilmente ocupa uma quantidade significativa de memória.
[/quote]

Eu estou lendo, agora, voce esta lendo o que estou escrevendo, eu estou escrevendo sobre o que vc escreveu de “Voila” quebrar o singleton e ter 2 variaveis apontando para objetos diferentes.
Leu onde escrevi “exemplo = null”??

Bom ou nao estou te entedendo ou vc é que nao esta me entendendo.

Bom meditemos o seguinte codigo pra ver o que acontece.

Exemplo exemplo = Exemplo.getInstance();
        
        System.out.println(exemplo);
        
        exemplo = null;  //matando o singleton, com isso a referencia "instance" da classe Exemplo recebe null, ou seja o mesmo que o antigo metodo killMySelf
        
        System.out.println(exemplo);  //imprimi null ou seja onde esta a referencia do singleton que vc fala.
        
        Exemplo exemplo2 = Exemplo.getInstance();  //cria novo singleton
        System.out.println(exemplo2);
        
        System.out.println(exemplo == exemplo2);  //false, claro exemplo é null
        
        System.out.println(exemplo); //  continua imprimindo null, ou seja quantas referencias para o singleton eu tenho???
        //1, o que tenho sao 2 "variaveis" porem uma é nula e nao aponta pra lugar algum, entao nao pode ser usada, ao menos que
        
        exemplo = Exemplo.getInstance();
        
        System.out.println(exemplo == exemplo2);  //agora true, ou seja apenas um objeto

Claro que pra acabar com o objeto tem que se digitar exemplo = null, porem deixando assim, evitamos ter 2 objetos diferentes da classe Exemplo, ou seja temos sim um singleton.

Ok, mas fazer:

Exemplo exemplo = Exemplo.getInstance();
exemplo = null;

Não mata o singleton. Mata uma referência ao Singleton, mas o objeto Singleton ainda existe, conforme demonstra o resto do seu exemplo.
Ainda existe uma variável estática (que está dentro da classe Exemplo), guardando a referência do Singleton. E o que o autor do tópico perguntou e se há um jeito de eliminar a existência de um objeto, em definitivo. No caso do Singleton, estou tentando demonstrar que não há. Ou melhor até há, mais é muito mais difícil do que com um objeto comum.

Era essa variável que o método killMySelf() tentava apagar exatamente a referência estática, interna e na classe, que mantém o Singleton vivo. E por isso causava a duplicação do Singleton.