Pq private static final e não apenas private final?

39 respostas
D

Bom dia a todos!

Sempre tive uma dúvida em relação aos modificadores private + static, ja procurei respostas mas não achei nada por enquanto.

Em muitos lugares vejo declaração de constantes privadas.
O que não entendo é, ja que é privada, porque declarar como static?

Obrigado!

39 Respostas

marcelo.bellissimo

http://www.guj.com.br/article.show.logic?id=121

D

Obrigado pelo link, mas continuo com a mesma dúvida.
Eu sei o que é static, sei que é compartilhado por todos e não necessita instanciar a classe para usá-lo.

Mas porque ter uma variável private + static ?? Somente a classe que possui essa variável pode acessá-la, então porque p static?

marcelo.bellissimo

O Static na variável garante que o valor dela seja sempre o mesmo/único para todas as instâncias da classe.

O Private modifica a visibilidade, se for Private apenas a própria classe poderá acessar a variável.

São propósitos diferentes… não é necessário uma pra usar a outra…

Balena

Private = apenas as instancias da classe podem vizualizá-la.
Static = seu valor será único, ou seja sempre o mesmo.
Final = depois de incializada o seu valor não poderá mais ser modificado.

pelo que sei é pra isso que serve, mas como foi dito anteriormente, uma utilização independe da outra.

D

Oi Marcelo, obrigado pela resposta, mas vc não me entendeu.

Eu sei o que faz o private e o que faz o static.

O que não entendo é porque declarar uma variável privada e estática ao mesmo tempo.
Uma variável estática é única e pode ser acessada de qualquer classe desde que ela seja public .
Sendo private somente a classe que a possui pode acessá-la, sendo assim, porque ser estática se ninguém mais tem acesso a esta variável?

D

Balena, obrigado!

Só uma coisa, com static o valor não será único, o valor pode ser alterado, o que é únicp é o membro, que independe de instâncias.

Mais uma vez, minha dúvida é qual é o sentido de utiliza a combinção de private + static, sendo que apenas a classe que possui o membro private pode acessá-lo.

diego_qmota

O sentido é ter uma varíavel (ou objeto) com seu valor compartilhado por todos os objetos dessa classe. Sem que seja possível acessar essa varíavel de outras classes.

Essa abordagem é utilizada quando você quer ter uma varíavel static onde não é interessante que fique sendo pública também. Assim você oculta detalhes da implementação da classe à outras classes.

D

Pq eu quero uma variável que é única pra quem quer que queira obter o seu valor, se apenas a classe que a declara é quem tem acesso a mesma?

Será que melhorei a pergunta agora?

D

Diego, mas para isso eu a declaro apenas como private, não é necessário o static.

marcelo.bellissimo

danilocsf:
Pq eu quero uma variável que é única pra quem quer que queira obter o seu valor, se apenas a classe que a declara é quem tem acesso a mesma?

Será que melhorei a pergunta agora?

Eu entendi a pergunta, mas você não entendeu as “possibilidades” do uso do static…

A variável static será única para todas as instâncias dessa classe, ou seja, se eu criar 200 instâncias de uma determinada classe, o valor será o mesmo para as 200.
Se eu alterar, vai “alterar” nas 200 instâncias…

Não consigo pensar num exemplo pra isso agora, mas é isso aí… agora, não tem nada a ver mas só pra complementarn se você quer uma variável que não mude de valor nunca, aí usamos o final

Entendeu?
Private, só acessível pela própria classe…
Static, valor único para a classe (e suas ‘n’ instâncias)…
Final, valor imutável…

Balena

danilocsf:
Balena, obrigado!

Só uma coisa, com static o valor não será único, o valor pode ser alterado, o que é únicp é o membro, que independe de instâncias.

Mais uma vez, minha dúvida é qual é o sentido de utiliza a combinção de private + static, sendo que apenas a classe que possui o membro private pode acessá-lo.

Eu não disse que o valor dela não pode ser alterado, e sim o valor é único, porque todas as instâncias da classe tem o mesmo valor.

O private está sendo usado para que ninguém consiga ver de fora, e o static para garantir que todas as instancias da classe vejam a mesma coisa, quando olharem para essa variável.

O duro é que todos os exemplos que penso para vc utilizar isso e enxergar as diferenças entre o static e o non-static, envolvem o singleton, que permite apenas uma instância de classe.

Mas é mais ou menos como fazer uma implementação de uma classe de conexão toda errada, quando eu quiser eu altero o valor da String de conexão e meu banco de dados para de funcionar sem mais nem menos.

D

Marcelo, agora vc disse algo que começou a fazer mais sentido.
Seria uma utilização ao se utilizar threads… se em algum momento uma instancia da thread alterar o valor, todas as outras passam a utilizar o novo valor.

Mas aí vem outra pergunta, e porque constantes privadas então? (private static final)
Essas não podem ter outro valor.

Vejo isso muito, tanto durante o dia a dia na empresa, quanto em materiais de exemplos.
por ex.:
private static final String VALOR_DE_UM_PROPERTIE=“key.properties”;

aí essa constante é utilizada para ler um valor de um propertie…
No meu ponto de vista , esse tipo de declaração está apenas aumentando o consumo de memória, pq não apenas :
private final String VALOR_DE_UM_PROPERTIE=“key.properties”;

Balena

danilocsf:
Marcelo, agora vc disse algo que começou a fazer mais sentido.
Seria uma utilização ao se utilizar threads… se em algum momento uma instancia da thread alterar o valor, todas as outras passam a utilizar o novo valor.

Mas aí vem outra pergunta, e porque constantes privadas então? (private static final)
Essas não podem ter outro valor.

Vejo isso muito, tanto durante o dia a dia na empresa, quanto em materiais de exemplos.
por ex.:
private static final String VALOR_DE_UM_PROPERTIE=“key.properties”;

aí essa constante é utilizada para ler um valor de um propertie…
No meu ponto de vista , esse tipo de declaração está apenas aumentando o consumo de memória, pq não apenas :
private final String VALOR_DE_UM_PROPERTIE=“key.properties”;

O final é imutável, e eu posso querer alterar o valor da variável static.

D

Exatamente … e pq ter uma variavel private final e static , se é imutavel? Não seria apenas uma coisa a mais na memória ao carregar a aplicação?

D

danilocsf:
Balena:

O final é imutável, e eu posso querer alterar o valor da variável static.

Exatamente … e pq ter uma variavel private final e static , se é imutavel? Não seria apenas uma coisa a mais na memória ao carregar a aplicação?

É nesse ponto que estou querendo chegar, pois até hoje eu só adotei como ‘padrão’ mas nunca entendi o porque…
Em que situação se deve utilizar a combinação private static final e qual situação se deve utilizar private final , sendo que o valor é imutável ?
Isso não acarreta apenas um maior consumo de memória? Imagine centenas de classes que possuem dezenas de variáveis private static final, será que não poderia ser apenas private final?

É exatamente isso que não entrou na minha cabeça ainda.
Pode haver 1000 instância de uma classe, mas pq uma constante estática declarada nessa classe?

diego_qmota

danilocsf:
Pq eu quero uma variável que é única pra quem quer que queira obter o seu valor, se apenas a classe que a declara é quem tem acesso a mesma?

Será que melhorei a pergunta agora?

Eu uso o private quando quero isso mesmo… quando a classe que declara a varíavel é a única que pode manipulá-la/enxergá-la…

D

diego_qmota:
danilocsf:
Pq eu quero uma variável que é única pra quem quer que queira obter o seu valor, se apenas a classe que a declara é quem tem acesso a mesma?

Será que melhorei a pergunta agora?

Eu uso o private quando quero isso mesmo… quando a classe que declara a varíavel é a única que pode manipulá-la/enxergá-la…

Então Diego, a questão não é só o private … da uma lida no que escrevi logo antes de vc responder pra vc entender onde quero chegar.
Valeu a atenção!

diego_qmota

danilocsf:
danilocsf:
Balena:

O final é imutável, e eu posso querer alterar o valor da variável static.

Exatamente … e pq ter uma variavel private final e static , se é imutavel? Não seria apenas uma coisa a mais na memória ao carregar a aplicação?

É nesse ponto que estou querendo chegar, pois até hoje eu só adotei como ‘padrão’ mas nunca entendi o porque…
Em que situação se deve utilizar a combinação private static final e qual situação se deve utilizar private final , sendo que o valor é imutável ?
Isso não acarreta apenas um maior consumo de memória? Imagine centenas de classes que possuem dezenas de variáveis private static final, será que não poderia ser apenas private final?

É exatamente isso que não entrou na minha cabeça ainda.
Pode haver 1000 instância de uma classe, mas pq uma constante estática declarada nessa classe?

Porquê se você usar private final, o consumo de memória será = 1000 X variavel.
Usando private static final, o consumo de memória será = variavel.

Vou dar alguns exemplos para ilustrar:

Você possui a classe Padeiro, onde o sindicato deles é igual para todos os objetos.
Aí você pode usar public static final… beleza? O sindicato é uma informação que pode ser visualizada em outras partes da aplicação e pode ser necessária na impressão de fichas de cadastro, etc…

Você têm a classe RemuneracaoPadeiro
Nela, você têm uma varíavel de base salarial que seja igual para todos os funcionários.

Mas para você não é interessante que a base salarial seja visível no resto do programa. Para que deixar isso visível se o programa só quer obter o cálculo do salário do cara e pronto. A forma que esse cálculo vai ser feito pouco importa para o resto da aplicação… A aplicação é cliente dessa classe, como cliente só importa a obtenção do resultado (sem que seja visível detalhes da implantação)…
E se eu usar private final para essa varíavel, se houverem 1000 objetos RemuneracaoPadeiro ele vai consumir 1000 vezes mais memória para essa varíavel (vão ter 1000 cópias dela na memória).

É o mesmo que você ser cliente de uma empresa e ao comprar um produto, ela te informar na nota: o centro de distribuição, quanto foi pago de imposto na fonte, qual foi a transportadora que fez a entrega, o horário que o produto foi entregue na loja, quanto foi o preço de atacado que a loja pagou, quanto custou a embalagem do produto, etc etc… O private é usado para ocultar de quem faz uso da classe, todos os detalhes da implementação.

O escopo que você vai usar para a variável segue a definição do uso da varíavel:

  • Essa varíavel deve ser enxergada fora do contexto da classe? É necessário para o resto da aplicação conhecer essa variável??
    Sim - Uso public
    Não - Uso private
  • A variável deve ser a mesma para todos os objetos da mesma classe?
    Sim - Uso static
    Não - Não uso static
  • A variável é imutável (ou só é mudada sazonalmente via alteração no código fonte)?
    Sim - Uso final
    Não - Não uso final
diego_qmota

Você vai fazer uso só se for necessário que somente aquela classe tenha acesso a mesma e somente ela possa manipular/acessar a varíavel

D

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?

diego_qmota

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.

D

diego_qmota:
Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.

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…

marcelo.bellissimo

danilocsf:
diego_qmota:
Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.

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…

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…

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.

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.

marcelo.bellissimo

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.

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í?

esmiralha

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

D

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.

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.

diego_qmota

danilocsf:
diego_qmota:
Acredito que usar ou não private em uma variável static não impacte em desempenho na aplicação.

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…

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).

adriano_si

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…

esmiralha

Leia o thread e vc vai descobrir…

esmiralha

wellington.nogueira:
esmiralha:
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)…

Leia o thread e vc vai descobrir…


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.

O objeto fica no heap e as referências para ele ficam no String Literal Pool.

adriano_si

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.

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 []

esmiralha

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”.

A

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.

adriano_si

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.

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 []

Balena

pelo simples fato de que eu posso não querer que essa variável possa ser modificada, após ser inicializada…

WellingtonRamos
danilocsf:
...? Como vc disse , a variável static é criada ao iniciar a aplicação, sendo assim ela está na memória desde o início, ....
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 {
	// pode receber atribuição de valores uma única vez.
	private final DadosUnicos dados;
	public Pessoa(DadosUnicos dados) {
		this.dados = dados;
	}
	// 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:
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";
}

Obs.: Existem algumas "otimizações" de memória a se utilizar final, mas não lembro agora como funciona...

WellingtonRamos

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.

WellingtonRamos

esmiralha:
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)…

Leia o thread e vc vai descobrir…


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.

Criado 13 de dezembro de 2010
Ultima resposta 13 de dez. de 2010
Respostas 39
Participantes 8