Uso de metodos public e static

16 respostas
renatomattos2912

Boa tarde,

Tenho uma duvida quanto ao uso de métodos referente ao instanciamento deles. Por exemplo:

Ao criar uma classe e dentro dela criar um método public, qual seria a melhor forma de usar este método em outras classes??
Eu sei q sera necessário instanciar a classe porem digamos q eu queira usar este método dentro de um outro método de outra classe, seria melhor eu instanciar a classe dentro ou fora do método?? Segue abaixo alguns exemplos de código para se identificar a melhor forma e melhor entender a minha duvida:

Tenho a Classe CodA e nela um método soma.

Public Class CodA {
    public int soma (int a, int b){
       return (a+b);
    }
}

DUVIDA: A melhor forma de se usar o método “soma” da classe CodA em outra classe seria qual dos métodos abaixo?

Método 1:

Public Class CodB {

    public void imprime (){
       CodA coda = new CodA();
       System.out.print(coda.soma(1,2));
    }

}

ou

Metodo 2:

Public Class CodB {
    
    CodA coda = new CodA();

    public void imprime (){
       System.out.print(coda.soma(1,2));
    }

}

Minha pergunta é apenas para níveis de boas praticas de programação e gerenciamento dos recursos de forma a poupar memoria e etc, se alguém tiver alguma dica relacionada a métodos static favor postar aqui tmb.

Obrigado

16 Respostas

rmendes08

Em termos de uso de memória, é sempre melhor criar objetos locais, pois assim que o método termina de executar o objeto é coletado pelo GC.

Porém, no caso que você mostrou, seria até mais adequado declarar o método soma() como static, pois assim nem de uma instância da classe você precisa. Apenas tome cuidade para não programar “procedural” em Java.

ElesisLink

rmendes08:
Em termos de uso de memória, é sempre melhor criar objetos locais, pois assim que o método termina de executar o objeto é coletado pelo GC.

Porém, no caso que você mostrou, seria até mais adequado declarar o método soma() como static, pois assim nem de uma instância da classe você precisa. Apenas tome cuidade para não programar “procedural” em Java.

Eu tenho uma pergunta:

Em um sistema, onde 90% das validações são realizadas em uma classe de Validação, seria mais viável criar instâncias da classe Validacao ou

declarar os métodos desta classe como static ?

rmendes08

ElesisLink:
rmendes08:
Em termos de uso de memória, é sempre melhor criar objetos locais, pois assim que o método termina de executar o objeto é coletado pelo GC.

Porém, no caso que você mostrou, seria até mais adequado declarar o método soma() como static, pois assim nem de uma instância da classe você precisa. Apenas tome cuidade para não programar “procedural” em Java.

Eu tenho uma pergunta:

Em um sistema, onde 90% das validações são realizadas em uma classe de Validação, seria mais viável criar instâncias da classe Validacao ou

declarar os métodos desta classe como static ?

Depende. Se cada um dos métodos utiliza somente variáveis locais, então os métodos podem ser todos estáticos, e aí não tem sentido criar instâncias de uma classe que não precisa armazenar estado.

Agora, se os métodos precisam usar variáveis de instância então é interessante criar um objeto para cada chamada de método, pois em um ambiente multi-thread você pode obter inconsistência e/ou gargalo no processamento de informações.

lina

ElesisLink:
rmendes08:
Em termos de uso de memória, é sempre melhor criar objetos locais, pois assim que o método termina de executar o objeto é coletado pelo GC.

Porém, no caso que você mostrou, seria até mais adequado declarar o método soma() como static, pois assim nem de uma instância da classe você precisa. Apenas tome cuidade para não programar “procedural” em Java.

Eu tenho uma pergunta:

Em um sistema, onde 90% das validações são realizadas em uma classe de Validação, seria mais viável criar instâncias da classe Validacao ou

declarar os métodos desta classe como static ?

Oi,

Todo método chamado dentro de um método estático deve ser estático. Assim como toda a variável não local utilizada dentro deste método também deve ser estática. Isso pode se tornar um tanto quanto complicado quando lidamos com processos em paralelo, utilizando Thread.

Para este caso, criar uma instância da classe Validacao seria o mais adequado. (Minha opinião)

Tchauzin!

jsanchesleao

Evite estáticos sempre que possível. No caso onde 90% das validações são feitas a partir de uma classe só, crie uma instância única desta classe e passe uma referência a esta instância sempre que necessário. Fica até mais fácil para testar as classes que usam validações.

Cuidado, para fazer isso seu objeto não pode armazenar estado.

Dê uma olhada no padrão Singleton sobre como implementar isso.

renatomattos2912

rmendes08: Obrigado pela resposta, o codigo citado como exemplo por mim é apenas uma demonstração bem basica, no meu caso estou utilizando metodos e classes mais complexos.

rmendes08

jsanchesleao:
Evite estáticos sempre que possível. No caso onde 90% das validações são feitas a partir de uma classe só, crie uma instância única desta classe e passe uma referência a esta instância sempre que necessário. Fica até mais fácil para testar as classes que usam validações.

Cuidado, para fazer isso seu objeto não pode armazenar estado.

Dê uma olhada no padrão Singleton sobre como implementar isso.

Não entendi … se o objeto não vai armazenar estado, por que criá-lo ?

renatomattos2912

jsanchesleao: entendi, é acho q fiz isso em uma aplicação utilizando hibernate. obrigado.

E

Uma sutilezazinha que vou indicar aqui. Como já me queimei com isso, vou indicar que isso pode até ocorrer (e infelizmente sem aviso).

Digamos que você tenha uma classe utilitária (com todos os métodos estáticos) usada, por exemplo, para formatação de números.

Acontece que por algum motivo obscuro, algumas classes têm métodos que não são thread-safe (como é o caso de java.text.DecimalFormat e java.text.SimpleDateFormat). Ou seja, você não pode criar objetos estáticos dessa classe para poderem ser acessados por métodos estáticos se esses métodos estáticos estiverem sendo chamados de várias threads. Felizmente esse problema costuma ser raro.

O remédio para esses casos normalmente é o uso de ThreadLocal. Aqui vai um exemplo de ThreadLocal sendo usado em Java 1.4,

E aqui vai outro exemplo de ThreadLocal sendo usado em Java 5 ou posterior.

public class TLDateFormat extends ThreadLocal<DateFormat> {
    /**
     * Construtor
     * 
     * @param pattern A descrição do formato. Veja: {@link java.text.DecimalFormat#DecimalFormat(java.lang.String)
     *        Construtor de DecimalFormat.}
     */
    public TLDateFormat(final String pattern) {
        this.pattern = pattern;
    }

    public TLDateFormat(final String pattern, final DateFormatSymbols formatSymbols) {
        this.pattern = pattern;
        this.formatSymbols = formatSymbols;
    }

    public TLDateFormat(final String pattern, final Locale locale) {
        this.pattern = pattern;
        this.locale = locale;
    }
    
    public TLDateFormat(final String pattern, final TimeZone tz) {
        this.pattern = pattern;
        this.tz = tz;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected DateFormat initialValue() {
        DateFormat df;
        if (formatSymbols != null)
            df = new SimpleDateFormat(pattern, formatSymbols);
        else if (locale != null)
            df = new SimpleDateFormat(pattern, locale);
        else
            df = new SimpleDateFormat(pattern);
        if (tz != null)
            df.setTimeZone(tz);
        return df;
    }

    /** O formato a ser usado. */
    private String pattern;
    /** Os símbolos para formatação de datas */
    private DateFormatSymbols formatSymbols;
    /** O locale a ser usado */
    private Locale locale;
    /** O timezone a ser usado */
    private TimeZone tz;
}
jsanchesleao

rmendes08:
jsanchesleao:
Evite estáticos sempre que possível. No caso onde 90% das validações são feitas a partir de uma classe só, crie uma instância única desta classe e passe uma referência a esta instância sempre que necessário. Fica até mais fácil para testar as classes que usam validações.

Cuidado, para fazer isso seu objeto não pode armazenar estado.

Dê uma olhada no padrão Singleton sobre como implementar isso.

Não entendi … se o objeto não vai armazenar estado, por que criá-lo ?

por diversos motivos, mas todos se resumem a a evitar estáticos, normalmente o espaço estático da JVM é mais limitado, mas principalmente porque uma chamada estática nunca pode ser substituída sem alterar o código original, o que é ruim pra testes e pra reuso do código.

rmendes08

jsanchesleao:
rmendes08:
jsanchesleao:
Evite estáticos sempre que possível. No caso onde 90% das validações são feitas a partir de uma classe só, crie uma instância única desta classe e passe uma referência a esta instância sempre que necessário. Fica até mais fácil para testar as classes que usam validações.

Cuidado, para fazer isso seu objeto não pode armazenar estado.

Dê uma olhada no padrão Singleton sobre como implementar isso.

Não entendi … se o objeto não vai armazenar estado, por que criá-lo ?

por diversos motivos, mas todos se resumem a a evitar estáticos, normalmente o espaço estático da JVM é mais limitado, mas principalmente porque uma chamada estática nunca pode ser substituída sem alterar o código original, o que é ruim pra testes e pra reuso do código.

Continuo sem entender:

Os bytecodes de métodos estáticos e não estáticos são alocados na mesma área de memória. Portanto, em termos de desempenho ou uso de memória, isso não faz diferença nenhuma.

O mesmo vale para qualquer método público. Se a interface de um objeto não for bem desenhada, as dificuldades para reusar o código também são grandes.

Entenda que de forma alguma ou quero incentivar o uso indiscriminado de métodos estáticos. Se uma classe está abusando de métodos estáticos isso é sinal de que o programador está programando Java procedural. Por outro lado, eu acho que a criação de um objeto deve fazer sentido. Por definição, objetos devem combinar estado + comportamento. Se o seu objeto não armazena estado, não faz sentido ele existir.

jsanchesleao

Entendo. Nesse contexto realmente métodos estáticos solucionam o problema numa boa. Somente complementando:

quanto aos testes, é muito mais simples mockar o comportamento de um método público não estático, desde que este não seja final (nem sua classe)

De fato, me enganei com isso. Realmente com métodos não faz a menor diferença.

Na verdade, embora não no caso em questão, faz sentido sim criar objetos sem armazenamento de estado. Vários padrões como Flyweight e Strategy se beneficiam disto. Objetos deveriam ser usados para encapsular conceitos, não meramente estado, uma vez que ele em si pode ser parte do estado de outro contexto.

G

eu creio q o q deve ser evitado é a fobia:
Não colocar static simplesmente por medo de parecer procedural.

será q o pessoal da Sun tinha esse pânico?

veja a classe:

java.util.Arrays;
http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html

java.util.Collections;
http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html

isso não pare mt procedural?

o fato de ser static não prejudica o reaproveitamento e às vezes até o possibilita.
no exemplo do “sum” supra citado. se ele for static ele poderá ser reutilizado por outra classe mt facimente.

ViniGodoy

GilsonNunes:
eu creio q o q deve ser evitado é a fobia:
Não colocar static simplesmente por medo de parecer procedural.

Não, você também deve evitar static porque:

  • Não é possível fazer polimorfismo com static;
  • É péssimo para sincronização multi-threads;
  • Variáveis static são causadoras de memory leaks;
  • Provavelmente você está errando e há um design melhor sem o static;

Além, é claro, de forçarem um design procedural.

será q o pessoal da Sun tinha esse pânico?

veja a classe:

java.util.Arrays;
http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html

java.util.Collections;
http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html

isso não pare mt procedural?

Isso é procedural. Entretanto, note que o pessoal da Sun foi cuidadoso o suficiente para criar métodos estáticos em classes que não guardam estado (como todas que você citou).
Ou método estáticos que não dependem de estado (como métodos fábrica).

Não é proibido usar static, mas usa-lo corretamente exige uma série de cuidados.

Essa é afirmação que significa o seguinte:
“Existe algumas poucas situações que static possibilita reaproveitamento de código, se usado com os devidos cuidados.”

Não faça parecer que tomar a decisão de criar o método estático é algo casual, que deveríamos tomar com a mesma preocupação que criamos um método não estático.
Você está num fórum de Java Básico, deixe claro para usuários aqui o que geralmente é uma má decisão de design.

Caso contrário, não reclame do sistema de ensino quando o jr. na sua empresa sair usando static em tudo.

G

Vini, obrigado pelas observações.

mas eu quis chamar a atenção pra o risco de o “cuidado” se tornar “fobia”.
o problemas de statics, a meu ver, se concentra nas vars e não nos métodos.
e o termo “procedural”, usado de forma pejorativa, se refere ao tal.

no exemplo q foi objeto da discursão mesmo.

public int Soma(int a, int b){ return a + b; }

ou

static public int Soma(int a, int b){ return a + b; }

??

sendo ele static, quais possíveis problemas poderiam surgir em um contexto multi-threads?

ViniGodoy

Com certeza.

Os problemas com threads aparecem quando há variáveis estáticas, nesno que private.

No caso do soma, isso não ocorre.

Criado 19 de julho de 2012
Ultima resposta 28 de jul. de 2012
Respostas 16
Participantes 8