Mais uma resposta que agora faz sentido, era nisso que queria chegar. E não o que faz cada modificador. A questão era consumo de memória e utilização… quando utilizar e não utilizar…
Então vc não acha que deveria haver mais critério ao utilizar uma constante privada? Como vc disse , a variável static é criada ao iniciar a aplicação, sendo assim ela está na memória desde o início, mas acredito que não é sempre que uma classe será instanciada centenas de vezes, ainda mais se for uma aplicação não distribuída.
Será que não deveria haver um outro critério pra essa combinação? Será que não é feito muito mal uso dessa combinação de modificadores?
Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.
Você define os critérios de acordo com a visibilidade que você quer atribuir.
E também priorizando o encapsulamento:
Encapsulamento vem de encapsular, que em programação orientada a objetos significa separar o programa em partes, o mais isoladas possível. A idéia é tornar o software mais flexível, fácil de modificar e de criar novas implementações. - Wikipedia
Todas as partes do software devem ser acessíveis apenas o necessário.
Por que atribuir esses critérios? Em um primeiro momento, pode parecer não ter importância… mas com o crescimento do programa, escopos incorretos podem afetar o programa… Hoje você pode não usar muitos objetos daquela classe, mas amanhã… Por isso que é bom definir uma arquitetura adequada desde o início…
Ah…e é claro… muitas vezes os escopos escolhidos são errados para a abordagem que se está usado… Por ex: declarar um monte de variáveis “globais” sem necessidade, ou atributos que deveriam ser static e usa-los em milhares de objetos.
[quote=diego_qmota]Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.
[/quote]
Na verdade eu quis dizer ao contrário…
eu quis dizer quando usar static em uma variavel private … será que sempre é viável…
Não estou entrando em questões de encapsulamento e essas coisas…
[quote=danilocsf][quote=diego_qmota]Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.
[/quote]
Na verdade eu quis dizer ao contrário…
eu quis dizer quando usar static em uma variavel private … será que sempre é viável…
Não estou entrando em questões de encapsulamento e essas coisas…
[/quote]
Tudo depende da aplicação, de como ela foi estruturada, enfim, vários fatores… não existe uma regra que diz onde “sempre” devemos usar essa combinação, isso depende de você, da sua visão das regras de negócio…
O Static, pelo menos pra mim, serve mais como maneira de poupar memória quando existe uma variável que precisar ser lida por uma classe e a mesma terá muitas instâncias…
Danilo,
me parece que você fez uma pergunta para a qual já tinha uma resposta e deseja apenas que outras pessoas cheguem à mesma conclusão. Se não for o caso, ignore.
Use variáveis private static, quando desejar manter um estado comum a todas as instâncias de uma classe, mas que não deva ser acessado/alterado por objetos de outra classe.
Não recomendo o uso de contexto static com o intuito de economizar memória, exceto se o ganho for notável e previamente evidenciado.
private static String xxx = “teste” ou private String xxx= “teste” vai economizar zero de memória, se não estou enganado.
Não sou um expert em escovação de bit da JVM, mas tenho a impressão de que Strings são armazenadas de forma especial garantindo que, quando sejam idênticas, compartilhem o mesmo espaço de memória.
[quote=esmiralha]private static String xxx = “teste” ou private String xxx= “teste” vai economizar zero de memória, se não estou enganado.
Não sou um expert em escovação de bit da JVM, mas tenho a impressão de que Strings são armazenadas de forma especial garantindo que, quando sejam idênticas, compartilhem o mesmo espaço de memória.[/quote]
Isso é algo que me deixa em dúvida também, mas pelo que eu sei é isso mesmo… alguém confirma/corrige ou dá uma explicação mais detalhada sobre isso aí?
Referências a Strings são armazenadas em uma estrutura chamada Literal Pool, que é uma tabela de lookup, mantida pela classe String. Dá uma lida no método intern() da classe String.
http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html
[quote=esmiralha]Danilo,
me parece que você fez uma pergunta para a qual já tinha uma resposta e deseja apenas que outras pessoas cheguem à mesma conclusão. Se não for o caso, ignore.
Use variáveis private static, quando desejar manter um estado comum a todas as instâncias de uma classe, mas que não deva ser acessado/alterado por objetos de outra classe.
[/quote]
Não quero que as pessoas concordem com meu ponto de vista, sendo que não tinha um ponto de vista até a pouco.
Contestei diversas respostas pois não estavam respondendo o que eu havia perguntando, (a maioria tentou me explicar a utilização dos modificadores) sendo que o que eu queria entender é pq o uso da combinação dos modificadores private static final.
Sempre que vejo uma variável privada cujo valor não pode ser alterado, esta é declarada como static e final. Oras, pq não apenas private final? Quando utilizo apenas private final então?
Vi aplicações que deveriam ter milhares de variáveis private static final só para properties (internacionalização e daos).
Uma declaração não faz diferença mesmo, mas e milhares?
Então houveram duas respostas que fizeram sentido com o que perguntei.
Agora tenho uma visão melhor a respeito. mas na minha opinião agora, há muito uso que poderia ser evitado de constantes privadas.
[quote=danilocsf][quote=diego_qmota]Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.
[/quote]
Na verdade eu quis dizer ao contrário…
eu quis dizer quando usar static em uma variavel private … será que sempre é viável…
Não estou entrando em questões de encapsulamento e essas coisas…
[/quote]
Bom, na verdade esta questão diz respeito a encapsulamento sim… Você está decidindo o domínio de um atributo de classe.
Se o domínio deve ser público ou privado, se deve ser o mesmo atributo para todos os objetos (static) … estas questões seguem o princípio do encapsulamento (mas não só dele).
A escolha se é viável usar static ou não, respeita se um atributo só seja igual a todos os objetos da mesma classe e visíveis somente por ela (encapsulado dentro dela). Só e somente se for necessário exibir esse atributo de classe a outras classes, é que se libera o acesso (utilizando public).
Achei a discursão interessante e nunca havia parado pra pensar a fundo sobre o tema…
Quando cheguei no trampo o padrão já existia, mas aqui todos os nossos DAOs possuem o HQL guardados com variáveis
private static final String HQL_ALGUMA_COISA = "";
Nunca pensei em contestar esse uso até ler esse tópico… Vamos pensar…
Quando carrego meu DAO para o Classloader ele vai lá e cria para aquela classe uma variável HQL_ALGUMA_COISA um valor X e guarda esse valor X no Pool…
Quando uma outra parte da aplicação precisar desse DAO o valor X será recuperado pelo motivo de HQL_ALGUMA_COISA ser static, logo “tenho 2 Objetos no Heap, com uma variável referenciando uma única String IMUTÁVEL que sempre me retornará o mesmo valor, por enquanto assumindo que é pelo motivo de ser static”
Alterando o código acima pra private final String HQL_ALGUMA_COISA = "";
Passo a ter o mesmo efeito já que “nos meus (2) Objetos ainda terei 1 variável do tipo String que será acessado unicamente pela minha classe que ainda continuará pegando somente um valor imutável de X que é único por causa do recurso da JVM de sempre recuperar um mesmo Valor no Pool de Strings ao invés de criar uma String nova caso a mesma já exista” é isso ???
Logo a idéia seria que para tipos String essas combinações são indiferentes surtindo o mesmo efeito tanto de negócio como de memória ??? tenho impressão que algo está nos escapando… vou pensar melhor sobre o assunto, depois volto aqui… só não podia deixar o raciocínio voar da mente volátil do trampo… Se alguém quiser e puder completar…
Abs []
[EDIT] …
Acho que achei a diferença… e está justamente onde uma variável Static é criada, que é na área de geração permanente, existindo 1 e sempre 1 por classe… Logo, pelo que creio que acontece, todo e qualquer Objeto no Heap recebe somente 1 variável física guardada nop PermGen…
Quando é uma não estática, cada Objeto terá uma nova referência, mesmo que o atributo aponte para a mesma String, ainda assim o atributo será criado no Objeto…
Acertei ou passei longe ??? ainda estou procurando informações sobre…
Leia o thread e vc vai descobrir…
[quote=wellington.nogueira][quote=esmiralha][quote=wellington.nogueira]
Pelo exemplo tratar-se de String e pelo fato de você estar declarando a mesma explicitamente (String entre aspas e não com new String()) você está parcialmente certo pois estará utilizando a “pool” de Strings (só não lembro onde são criadas na memória, se no PermGen ou na Heap)…
[/quote]
Leia o thread e vc vai descobrir…[/quote]
Vi que você tinha respondido que é na “Literal Pool”, só não tinha entrado link que você passou. Depois de ler, meu entendimento é que ela fica na Heap.[/quote]
O objeto fica no heap e as referências para ele ficam no String Literal Pool.
Pelo exemplo tratar-se de String e pelo fato de você estar declarando a mesma explicitamente (String entre aspas e não com new String()) você está parcialmente certo pois estará utilizando a “pool” de Strings (só não lembro onde são criadas na memória, se no PermGen ou na Heap)…
Entretanto, isso não é válido para qualquer objeto. Se você criar um objeto de negócio, o comportamento não será o mesmo pois não haverá um pool.
Nesse caso, usar private static final e private final gerarão resultados bem diferentes.[/quote]
Bom, até onde sei o Pool reside na PermGen, não no Heap…
Porque um Objeto de negócio não captura Strings do Pool (desculpa se não foi isso que quiseste dizer) ???
Também acho que gerarão resultados diferentes, porém acho que o que tem que ser entendido é justamente o porque dessa diferença… e acho que a diferença é justamente onde residem as variáveis de referência nesse caso… Quando STATIC eu creio que será uma única na Pilha, quando de atributo de classe uma para cada Objeto, no Heap junto com o Objeto… Não sei se estou certo, mas por enquanto to enxergando assim… vou continuar pesquisando quando eu chegar em casa, porque terei minha literatura pra me ajudar… rsrsrsrsrsrsrs
Abs []
Você tem razão, na JDK da Oracle/Sun/Demônio, o objeto fica armazenado no perm gen e a referência fica no “pool”.
Não sou um especialista em como a VM armazena os objetos em memória, mas ainda assim gostaria de dar minha opinião sobre o assunto.
Para mim, a princípio, o uso de memória de acordo com cada modificador simplesmente não importa.
O motivo para você escolher qual modificador usar, deve ser o que faz mais sentido para aquele atributo.
O consumo de memória e questões de performance são melhorados a cada versão. A não ser que tenha um problema real de performance, deveria desconsiderar isto.
Acredito então, que os usos seriam:
private - o valor só interessa, ou pode ser acessado, pela própria classe
final - o valor será definido uma vez e não será alterado em tempo de execução (tipicamente uma constante).
static - o valor será compartilhado por todas instâncias OU (principalmente, na minha opinião) o valor não depende de uma instância
Imagino que o static seja o único que precise de uma argumentação mais profunda.
Supondo, de forma bem simplista, uma classe Pessoa, que serviria de base pra cálculos de INSS e aposentadoria.
Queremos atributos para representar a expectativa de vida de uma pessoa e seu provável ano de falecimento (com base nessa expectativa).
Teríamos um código assim:
public class Pessoa {
private final static int EXPECTATIVA_VIDA = 70;
private final int provavelAnoFalecimento;
private String nome;
private Date dataNascimento;
public Pessoa(String nome, Date dataNascimento) {
this.nome = nome;
this.dataNascimento = dataNascimento;
provavelAnoFalecimento = calculaAnoFalecimento(); //omitido por simplicidade
}
}
Nesse caso, EXPECTATIVA_VIDA é static por ser o mesmo para todas pessoas e provavelAnoFalecimento apenas final pois depende de cada instância.
Estou postando minha opinião, pois vi que penderam mais para o lado técnico (consumo de memória, performance) e deixaram de lado a questão de organização do código, legibilidade, expressar intenções.
[quote=AbelBueno]Não sou um especialista em como a VM armazena os objetos em memória, mas ainda assim gostaria de dar minha opinião sobre o assunto.
Para mim, a princípio, o uso de memória de acordo com cada modificador simplesmente não importa.
O motivo para você escolher qual modificador usar, deve ser o que faz mais sentido para aquele atributo.
O consumo de memória e questões de performance são melhorados a cada versão. A não ser que tenha um problema real de performance, deveria desconsiderar isto.
Acredito então, que os usos seriam:
private - o valor só interessa, ou pode ser acessado, pela própria classe
final - o valor será definido uma vez e não será alterado em tempo de execução (tipicamente uma constante).
static - o valor será compartilhado por todas instâncias OU (principalmente, na minha opinião) o valor não depende de uma instância
Imagino que o static seja o único que precise de uma argumentação mais profunda.
Supondo, de forma bem simplista, uma classe Pessoa, que serviria de base pra cálculos de INSS e aposentadoria.
Queremos atributos para representar a expectativa de vida de uma pessoa e seu provável ano de falecimento (com base nessa expectativa).
Teríamos um código assim:
public class Pessoa {
private final static int EXPECTATIVA_VIDA = 70;
private final int provavelAnoFalecimento;
private String nome;
private Date dataNascimento;
public Pessoa(String nome, Date dataNascimento) {
this.nome = nome;
this.dataNascimento = dataNascimento;
provavelAnoFalecimento = calculaAnoFalecimento(); //omitido por simplicidade
}
}
Nesse caso, EXPECTATIVA_VIDA é static por ser o mesmo para todas pessoas e provavelAnoFalecimento apenas final pois depende de cada instância.
Estou postando minha opinião, pois vi que penderam mais para o lado técnico (consumo de memória, performance) e deixaram de lado a questão de organização do código, legibilidade, expressar intenções.
[/quote]
Perfeito Abel… a conversa pendeu pra esse lado porque foi intrigante mesmo a questão técnica envolvida… ainda nem sei se resolveu, mas sua colocação foi perfeita, principalmente que isso é uma regra “SEMPRE QUE POSSìVEL EVITE USAR STATIC”…
Abs []
pelo simples fato de que eu posso não querer que essa variável possa ser modificada, após ser inicializada…
Ela só estará presente quando a classe for adicionada ao ClassLoader, não necessariamente no início da aplicação.
O uso de private static final está mais associado a questões de leitura de código que necessariamente algo realmente válido. Você cria uma constante que represente algo e usa essa constante em diversos pontos da mesma classe mas em outras classes, sua representação não é “válida” mesmo que seu valor seja.
O uso de private final, eu associaria mais a um valor que não possa ser alterado para um determinado objeto. Exemplo:
class Pessoa {
//só pode receber atribuição de valores uma única vez.
private final DadosUnicos dados;
public Pessoa(DadosUnicos dados) {
this.dados = dados;
}
//Só pode ser lido
public DadosUnicos getDados() {
return dados;
}
}
class DadosUnicos {
private final String nome;
private final Date dataNascimento;
public DadosUnicos(String nome, Date dataNascimento) {
this.nome=nome;
this.dataNascimento=dataNascimento;
}
public String getNome() {
return nome;
}
public Date getDataNascimento() {
return dataNascimento;
}
}
DadosUnicos não poderá mais ser alterado, apenas lido.
O problema é que, normalmente os exemplos utilizados são com String que, ao meu ver, é uma classe especializada. Entretanto:
private final String teste não é igual a private static final String teste pois, apesar de referenciarem um mesmo local na memória, seus usos são diferentes:
[code]class TesteString {
public static void main(String[] args) {
//imprime true, mas eu tive que criar um objeto Teste02
System.out.println(Teste01.teste == new Teste02().teste);
}
}
class Teste01 {
static final String teste = “TESTE”;
}
class Teste02 {
final String teste = “TESTE”;
}[/code]
Obs.: Existem algumas “otimizações” de memória a se utilizar final, mas não lembro agora como funciona…
Pelo exemplo tratar-se de String e pelo fato de você estar declarando a mesma explicitamente (String entre aspas e não com new String()) você está parcialmente certo pois estará utilizando a “pool” de Strings (só não lembro onde são criadas na memória, se no PermGen ou na Heap)…
Entretanto, isso não é válido para qualquer objeto. Se você criar um objeto de negócio, o comportamento não será o mesmo pois não haverá um pool.
Nesse caso, usar private static final e private final gerarão resultados bem diferentes.
[quote=esmiralha][quote=wellington.nogueira]
Pelo exemplo tratar-se de String e pelo fato de você estar declarando a mesma explicitamente (String entre aspas e não com new String()) você está parcialmente certo pois estará utilizando a “pool” de Strings (só não lembro onde são criadas na memória, se no PermGen ou na Heap)…
[/quote]
Leia o thread e vc vai descobrir…[/quote]
Vi que você tinha respondido que é na “Literal Pool”, só não tinha entrado link que você passou. Depois de ler, meu entendimento é que ela fica na Heap.