static final privado -> crie essa variável apenas uma vez. final privado -> crie essa variável para cada objeto. Primeiro você economiza memória, vá em frente.
User1923551
4
final staticsignifica que essa variável é uma constante e só se associa à própria classe, ou seja, "uma variável constante por classe", enquanto finalsignifica "uma variável constante por instância". Como resultado, você não pode colocar uma final staticvariável no construtor da classe, pois o construtor envolve uma nova instância . (Você pode experimentar por si mesmo e receberá um erro)
LittleLittleQ
1
Por "não pode colocar uma variável estática final no construtor da classe" Quero dizer, não se pode inicializar uma final staticvariável no construtor, a única maneira é usar um inicializador estático :)
LittleLittleQ
2
@ user1923551 O efeito é invertido para coisas necessárias apenas por um período limitado de tempo em grandes aplicativos, em aplicativos com pouca memória ou ao usar um singleton. Ter coisas estáticas em todas as classes reservará um (enorme) pedaço de memória para coisas que não são necessárias. Também pode ser um vazamento de memória para declarar objetos finais estáticos ou coleções.
que você
Respostas:
309
Em geral, staticsignifica "associado ao próprio tipo , em vez de uma instância do tipo".
Isso significa que você pode fazer referência a uma variável estática sem nunca ter criado uma instância do tipo, e qualquer código referente à variável está se referindo exatamente aos mesmos dados. Compare isso com uma variável de instância: nesse caso, há uma versão independente da variável por instância da classe. Então, por exemplo:
Test x =newTest();Test y =newTest();
x.instanceVariable =10;
y.instanceVariable =20;System.out.println(x.instanceVariable);
imprime 10: y.instanceVariablee x.instanceVariablesão separados, porque xe yse referem a diferentes objetos.
Você pode consultar membros estáticos por meio de referências, embora seja uma má idéia fazer isso. Se nós fizemos:
Test x =newTest();Test y =newTest();
x.staticVariable =10;
y.staticVariable =20;System.out.println(x.staticVariable);
então isso imprimiria 20 - há apenas uma variável, não uma por instância. Teria sido mais claro escrever isso como:
Test x =newTest();Test y =newTest();Test.staticVariable =10;Test.staticVariable =20;System.out.println(Test.staticVariable);
Isso torna o comportamento muito mais óbvio. Os IDEs modernos geralmente sugerem mudar a segunda lista para a terceira.
Não há razão para ter uma declaração embutida inicializando o valor da seguinte maneira, pois cada instância terá seu próprio, NUMBERmas sempre com o mesmo valor (é imutável e inicializado com um literal). É o mesmo que ter apenas uma final staticvariável para todas as instâncias.
privatefinalint NUMBER =10;
Portanto, se não puder mudar, não há sentido em ter uma cópia por instância.
Mas, faz sentido se for inicializado em um construtor como este:
// No initialization when is declaredprivatefinalint number;publicMyClass(int n){// The variable can be assigned in the constructor, but then// not modified later.
number = n;}
Agora, para cada instância de MyClass, podemos ter um valor diferente, mas imutável de number.
Até que as enumerações estivessem disponíveis no Java 5, final estático era a maneira usual de declarar constantes.
Vineet Reynolds
22
@Vineet: finais estáticos ainda são a maneira de declarar constantes primitivas, a menos que você tem um número enumerado deles =)
Chii
@ Matthew: Potencialmente. Não para uma constante, mas para algum valor logicamente relacionado à instância. Não que eu goste de singletons de qualquer maneira.
Jon Skeet
1
Uma pergunta radical. Vale a pena usar private finalmais private static finalde espremer / recuperação que pouca memória da classe? Digamos que o calculatordispositivo com ram limitado, mas com muitos recursos de CPU.
precisa saber é o seguinte
1
@WinMyoHtet: Se você usa um campo estático, há apenas um no total. Se você usar um campo de instância, há um por instância. Usar um campo estático será melhor, a menos que você não tenha nenhuma instância; nesse caso, é inútil de qualquer maneira.
Jon Skeet
38
Para final , podem ser atribuídos diferentes valores em tempo de execução quando inicializados. Por exemplo
Assim, cada instância tem um valor diferente do campo a .
Para final estático , todas as instâncias compartilham o mesmo valor e não podem ser alteradas após a primeira inicialização.
ClassTestStatic{publicstaticfinalint a;}TestStatic t1 =newTestStatic();
t1.a =10;TestStatic t2 =newTestStatic();
t1.a =20;// ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION.
Isso não será compilado! Uma variável final deve ter um valor atribuído ou um valor atribuído em seus construtores. Esta resposta estaria correta se dois construtores fossem dados, cada um atribuindo 'a' a um valor diferente.
MattC
14
Confirmando, isso não será compilado. Conforme expresso acima, as variáveis de instância final devem ser instanciadas antes que o construtor termine e as variáveis de classe final devem ser instanciadas antes da criação da classe (você pode usar um bloco estático). Por que isso tem tantos votos positivos?
Rudi Kershaw
como MattC apontou, não é possível atribuir a uma variável final depois de criar esse objeto - na verdade, você não pode mesmo criar um objeto sem dar valores para suas variáveis finais ...
jamesdeath123
Apenas no caso de alguém tropeçar nisso, siga a resposta de MattC.
Faz
Isso é o que eu acho que o OP estava perguntando, eu tinha esquecido que as finais podem receber um valor na instanciação, se não tiver sido fornecido na declaração.
perfil completo de Salsero
34
Uma staticvariável permanece na memória durante toda a vida útil do aplicativo e é inicializada durante o carregamento da classe. Uma não staticvariável está sendo inicializada cada vez que você constrói um newobjeto. Geralmente é melhor usar:
privatestaticfinalint NUMBER =10;
Por quê? Isso reduz o consumo de memória por instância. Possivelmente também é favorável para ocorrências de cache. E isso faz sentido: staticdeve ser usado para coisas que são compartilhadas em todas as instâncias (também conhecidas como objetos) de um determinado tipo (também conhecidas como class).
uma variável estática também é criada em tempo de execução. Portanto, você pode usar a referida variável ou método antes que o objeto seja criado.
Bobby
13
Pela convenção de codificação Java, o nome de uma variável final estática deve estar em letras maiúsculas.
13139 starblue
@Martijn Courteaux, que tal uma situação em que uma classe será usada uma vez durante a vida útil do aplicativo! private final intserá removido da memória quando a instância for submetida a GC private static final inte permanecerá na memória durante toda a vida útil desse aplicativo. O que você sugere no cenário acima?
MANN
@ MANN: Isso é altamente teórico. Não há literalmente nenhum cenário de caso de uso útil para isso. Isso pode ser benéfico se você tiver como 50000 int vars em uma classe. Mesmo nesse caso, isso economizaria 200kb de memória. Como estamos falando de Java, isso parece totalmente irrelevante. No caso de dispositivos críticos para a memória, um compilador C ou C ++ decente incorporaria sempre esses valores inteiros, eliminando a necessidade de liberar completamente a memória.
Martijn Courteaux
17
estática significa "associado à classe"; sem ela, a variável é associada a cada instância da classe. Se for estático, significa que você terá apenas um na memória; caso contrário, você terá um para cada instância que criar. estático significa que a variável permanecerá na memória enquanto a classe estiver carregada; sem ela, a variável pode ser alterada quando sua instância é.
Variáveis de instância são obtidas quando todas as referências / objetos morrem, certo?
Ruchir Baronia
As instâncias são atribuídas a gc, mas as estáticas estão associadas a classes, não a instâncias. Enquanto a classe permanecer na memória, você poderá consultar suas instâncias e métodos estáticos públicos. Aqueles entram no perm gen (ou seja qual for o seu equivalente JDK 8) e não são controlados por gc.
Duffymo
Errado. Se você tiver uma referência a uma instância na memória, poderá acessar seus métodos e instâncias disponíveis. O resto está errado. Você não consegue entender a diferença entre uma classe e suas instâncias.
Duffymo
13
Lendo as respostas, não encontrei nenhum teste real realmente chegando ao ponto. Aqui estão os meus 2 centavos:
Como eu pensei que o java faz a diferença entre tipos primitivos e outros. Tipos primitivos em Java são sempre "armazenados em cache", o mesmo para literais de strings (não novos objetos String), portanto, não há diferença entre membros estáticos e não estáticos.
No entanto, há uma duplicação de memória para membros não estáticos se eles não forem instância de um tipo primitivo.
Alterar o valor de valueStatic para 10 vai ainda mais longe, pois o Java fornecerá os mesmos endereços para as duas variáveis int.
A autoboxing do 'int' -> Inteiro está causando confusão aqui. Você está vendo que a autoboxing de alguns valores (pequenos) int leva ao mesmo objeto Inteiro.
dkneller
@StackHola @dkneller De fato, o autoboxing é um detalhe muito importante que acontece aqui. A assinatura é ObjectUtils.identityToString(Object). (Além disso, Java não tem passagem por referência de qualquer maneira). Um teste realmente útil seria alocar dois objetos e alterar o valor de uma public final int FOO = 10variável usando reflexões Java de maneira forçada. Em seguida, verifique se o outro objeto também alterou seu valor.
Martijn Courteaux
11
Embora as outras respostas pareçam deixar bem claro que geralmente não há razão para usar constantes não estáticas, não encontrei ninguém apontando que é possível ter várias instâncias com valores diferentes em suas variáveis constantes.
Considere o seguinte exemplo:
publicclassTestClass{privatefinalstaticdouble NUMBER =Math.random();publicTestClass(){System.out.println(NUMBER);}}
Criar três instâncias do TestClass imprimiria o mesmo valor aleatório três vezes, uma vez que apenas um valor é gerado e armazenado na constante estática.
No entanto, ao tentar o seguinte exemplo:
publicclassTestClass{privatefinaldouble NUMBER =Math.random();publicTestClass(){System.out.println(NUMBER);}}
Criar três instâncias do TestClass agora imprimiria três valores aleatórios diferentes, porque cada instância tem seu próprio valor constante gerado aleatoriamente.
Não consigo pensar em nenhuma situação em que seria realmente útil ter valores constantes diferentes em diferentes instâncias, mas espero que isso ajude a ressaltar que há uma clara diferença entre finais estáticos e não estáticos.
publicclassStaticVariable{staticint noOfInstances;StaticVariable(){
noOfInstances++;}publicstaticvoid main(String[] args){StaticVariable sv1 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);StaticVariable sv2 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);System.out.println("No. of instances for st2 : "+ sv2.noOfInstances);StaticVariable sv3 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);System.out.println("No. of instances for sv2 : "+ sv2.noOfInstances);System.out.println("No. of instances for sv3 : "+ sv3.noOfInstances);}}
A saída do programa é dada abaixo:
Como podemos ver neste exemplo, cada objeto tem sua própria cópia da variável de classe.
C:\java>java StaticVariableNo. of instances for sv1 :1No. of instances for sv1 :2No. of instances for st2 :2No. of instances for sv1 :3No. of instances for sv2 :3No. of instances for sv3 :3
Dos testes que fiz, as variáveis finais estáticas não são as mesmas com as variáveis finais (não estáticas)! Variáveis finais (não estáticas) podem diferir de objeto para objeto !!! Mas isso é apenas se a inicialização for feita dentro do construtor! (Se não for inicializado pelo construtor, será apenas um desperdício de memória, pois cria variáveis finais para cada objeto criado que não pode ser alterado.)
Por exemplo:
class A
{finalint f;staticfinalint sf =5;
A(int num){this.f = num;}void show(){System.out.printf("About Object: %s\n Final: %d\n Static Final: %d\n\n",this.toString(),this.f, sf);}publicstaticvoid main(String[] args){
A ob1 =new A(14);
ob1.show();
A ob2 =new A(21);
ob2.show();}}
O que aparece na tela é:
Sobre o objeto: A @ addbf1 Final: 14 Final estático: 5
Sobre o objeto: A @ 530daa Final: 21 Final estático: 5
Além da resposta de Jon, se você usar final estático, ele se comportará como uma espécie de "definição". Depois de compilar a classe que a utiliza, ela estará no arquivo .class compilado gravado. Confira meu tópico aqui .
Para seu objetivo principal: Se você não usar o NÚMERO de maneira diferente nas diferentes instâncias da classe, aconselho o uso final e estático.
(Lembre-se de não copiar arquivos de classe compilados sem considerar possíveis problemas como o que meu estudo de caso descreve. Na maioria dos casos, isso não ocorre, não se preocupe :))
Para mostrar como usar valores diferentes nas instâncias, verifique este código:
Poderia, por favor, explicar o que é melhor e por quê?
Daniel
2
Apenas outro exemplo simples para entender o uso de variáveis estáticas, finais estáticas e finais. Os comentários do código têm a explicação adequada.
publicclassCity{// base price that is always same for all objects[For all cities].privatestaticdouble iphone_base_price =10000;// this is total price = iphone_base_price+iphone_diff;privatedouble iphone_citi_price;// extra price added to iphone_base_price. It is constant per city. Every// city has its own difference defined,privatefinaldouble iphone_diff;privateString cityName ="";// static final will be accessible everywhere within the class but cant be// changed once initialized.privatestaticfinalString countryName ="India";publicCity(String cityName,double iphone_diff){super();this.iphone_diff = iphone_diff;
iphone_citi_price = iphone_base_price + iphone_diff;this.cityName = cityName;}/**
* get phone price
*
* @return
*/privatedouble getPrice(){return iphone_citi_price;}/**
* Get city name
*
* @return
*/privateString getCityName(){return cityName;}publicstaticvoid main(String[] args){// 300 is theCity newyork =newCity("Newyork",300);System.out.println(newyork.getPrice()+" "+ newyork.getCityName());City california =newCity("California",800);System.out.println(california.getPrice()+" "+ california.getCityName());// We cant write below statement as a final variable can not be// reassigned// california.iphone_diff=1000; //************************// base price is defined for a class and not per instances.// For any number of object creation, static variable's value would be the same// for all instances until and unless changed.// Also it is accessible anywhere inside a class.
iphone_base_price =9000;City delhi =newCity("delhi",400);System.out.println(delhi.getPrice()+" "+ delhi.getCityName());City moscow =newCity("delhi",500);System.out.println(moscow.getPrice()+" "+ moscow.getCityName());// Here countryName is accessible as it is static but we can not change it as it is final as well. //Something are meant to be accessible with no permission to modify it. //Try un-commenting below statementsSystem.out.println(countryName);// countryName="INDIA";// System.out.println(countryName);}}
Não há muita diferença, pois ambas são constantes. Para a maioria dos objetos de dados da classe, estático significaria algo associado à própria classe, havendo apenas uma cópia, independentemente de quantos objetos foram criados com o novo.
Como é uma constante, ele pode não ser realmente armazenado na classe ou em uma instância, mas o compilador ainda não permitirá que você acesse objetos da instância a partir de um método estático, mesmo que saiba quais seriam. A existência da API de reflexão também pode exigir algum trabalho inútil se você não a tornar estática.
Como uma variável em uma classe é declarada como final AND inicializada no mesmo comando, não há absolutamente nenhuma razão para não declarar como estática, pois ela terá o mesmo valor, independentemente da instância. Portanto, todas as instâncias podem compartilhar o mesmo endereço de memória para um valor, economizando tempo de processamento, eliminando a necessidade de criar uma nova variável para cada instância e economizando memória compartilhando um endereço comum.
final estático privado será considerado constante e a constante pode ser acessada somente nesta classe. Como a palavra-chave estática está incluída, o valor será constante para todos os objetos da classe.
O valor da variável final privada será como constante por objeto.
Você pode consultar o java.lang.String ou procurar o exemplo abaixo.
O estático é o mesmo membro em todas as instâncias da classe e na própria classe.
O não estático é um para cada instância (objeto); portanto, no seu caso exato , é um desperdício de memória se você não colocar estática.
Se você marcar esta variável como estática, então, como você sabe, exigiria métodos estáticos para acessar novamente esses valores, isso será útil se você já pensa em usar essas variáveis apenas em métodos estáticos. Se é assim, então seria o melhor.
No entanto, você pode tornar a variável agora pública, já que ninguém pode modificá-la como "System.out", mas depende novamente de suas intenções e do que você deseja alcançar.
Métodos estáticos não seriam necessários para acessar variáveis estáticas - acho que você está pensando em "acessar variáveis de instância a partir de métodos estáticos" (não permitido).
ataulm
0
Digamos que, se a classe não tiver mais de uma instância, qual será a memória que mais terá:
ID final int estático privado = 250; ou ID final int privado = 250;
Eu entendi que estático se referirá ao tipo de classe com apenas uma cópia na memória e não estático estará em um novo local de memória para cada variável de instância. No entanto, internamente, se apenas compararmos uma instância da mesma classe (ou seja, mais de uma instância não seria criada), haverá alguma sobrecarga em termos de espaço usado por 1 variável final estática?
Por favor, não repita apenas o que outras respostas já abordaram.
desconhecido usuário
0
A variável estática pertence à classe (o que significa que todos os objetos compartilham essa variável). Variável não estática pertence a cada objeto.
publicclassExperimentFinal{privatefinalint a;privatestaticfinalint b =999;publicExperimentFinal(int a){super();this.a = a;}publicint getA(){return a;}publicint getB(){return b;}publicvoid print(int a,int b){System.out.println("final int: "+ a +" \nstatic final int: "+ b);}publicstaticvoid main(String[] args){ExperimentFinal test =newExperimentFinal(9);
test.print(test.getA(), test.getB());}}
Como você pode ver no exemplo acima, para "final int" podemos atribuir nossa variável para cada instância (objeto) da classe; no entanto, para "static final int", devemos atribuir uma variável na classe (a variável estática pertence à classe )
Final: uma vez que uma variável final é atribuída, ela sempre contém o mesmo valor. onde a variável é estática ou não estática: será apenas uma variável para todas as instâncias inicializadas uma vez na Memória
publicclassLengthDemo{publicstaticvoid main(String[] args){Rectangle box =newRectangle();System.out.println("Sending the value 10.0 "+"to the setLength method.");
box.setLength(10.0);System.out.println("Done.");}}
A palavra-chave "Static" cria a propriedade variável da classe em vez de instâncias individuais da classe. Haverá uma cópia dessa variável que é compartilhada entre todas as instâncias dessa classe. Qualquer alteração no estado da variável estática será refletida em todas as instâncias. Adicione final ao static e obteremos uma variável que foi inicializada de uma vez por todas no tempo de carregamento da classe e não pode ser alterada posteriormente por nenhuma instância da classe. Variáveis finais estáticas precisam ser inicializadas no momento da declaração; caso contrário, temos um erro de tempo de compilação. No que diz respeito ao campo de instância privada, ele se refere à propriedade / estado de um objeto / instância de uma classe. Cada instância / objeto da classe terá sua própria cópia da variável de instância. Quando a variável de instância é declarada final, significa que não podemos alterar seu valor para esta instância. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Se não for feito em nenhum deles, o erro de tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Se não for feito em nenhum deles, o erro de tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto.
final static
significa que essa variável é uma constante e só se associa à própria classe, ou seja, "uma variável constante por classe", enquantofinal
significa "uma variável constante por instância". Como resultado, você não pode colocar umafinal static
variável no construtor da classe, pois o construtor envolve uma nova instância . (Você pode experimentar por si mesmo e receberá um erro)final static
variável no construtor, a única maneira é usar um inicializador estático :)Respostas:
Em geral,
static
significa "associado ao próprio tipo , em vez de uma instância do tipo".Isso significa que você pode fazer referência a uma variável estática sem nunca ter criado uma instância do tipo, e qualquer código referente à variável está se referindo exatamente aos mesmos dados. Compare isso com uma variável de instância: nesse caso, há uma versão independente da variável por instância da classe. Então, por exemplo:
imprime 10:
y.instanceVariable
ex.instanceVariable
são separados, porquex
ey
se referem a diferentes objetos.Você pode consultar membros estáticos por meio de referências, embora seja uma má idéia fazer isso. Se nós fizemos:
então isso imprimiria 20 - há apenas uma variável, não uma por instância. Teria sido mais claro escrever isso como:
Isso torna o comportamento muito mais óbvio. Os IDEs modernos geralmente sugerem mudar a segunda lista para a terceira.
Não há razão para ter uma declaração embutida inicializando o valor da seguinte maneira, pois cada instância terá seu próprio,
NUMBER
mas sempre com o mesmo valor (é imutável e inicializado com um literal). É o mesmo que ter apenas umafinal static
variável para todas as instâncias.Portanto, se não puder mudar, não há sentido em ter uma cópia por instância.
Mas, faz sentido se for inicializado em um construtor como este:
Agora, para cada instância de
MyClass
, podemos ter um valor diferente, mas imutável denumber
.fonte
private final
maisprivate static final
de espremer / recuperação que pouca memória da classe? Digamos que ocalculator
dispositivo com ram limitado, mas com muitos recursos de CPU.Para final , podem ser atribuídos diferentes valores em tempo de execução quando inicializados. Por exemplo
Assim, cada instância tem um valor diferente do campo a .
Para final estático , todas as instâncias compartilham o mesmo valor e não podem ser alteradas após a primeira inicialização.
fonte
Uma
static
variável permanece na memória durante toda a vida útil do aplicativo e é inicializada durante o carregamento da classe. Uma nãostatic
variável está sendo inicializada cada vez que você constrói umnew
objeto. Geralmente é melhor usar:Por quê? Isso reduz o consumo de memória por instância. Possivelmente também é favorável para ocorrências de cache. E isso faz sentido:
static
deve ser usado para coisas que são compartilhadas em todas as instâncias (também conhecidas como objetos) de um determinado tipo (também conhecidas comoclass
).fonte
private final int
será removido da memória quando a instância for submetida a GCprivate static final int
e permanecerá na memória durante toda a vida útil desse aplicativo. O que você sugere no cenário acima?estática significa "associado à classe"; sem ela, a variável é associada a cada instância da classe. Se for estático, significa que você terá apenas um na memória; caso contrário, você terá um para cada instância que criar. estático significa que a variável permanecerá na memória enquanto a classe estiver carregada; sem ela, a variável pode ser alterada quando sua instância é.
fonte
Lendo as respostas, não encontrei nenhum teste real realmente chegando ao ponto. Aqui estão os meus 2 centavos:
Resultados para o primeiro objeto:
Resultados para o segundo objeto:
Conclusão:
Como eu pensei que o java faz a diferença entre tipos primitivos e outros. Tipos primitivos em Java são sempre "armazenados em cache", o mesmo para literais de strings (não novos objetos String), portanto, não há diferença entre membros estáticos e não estáticos.
No entanto, há uma duplicação de memória para membros não estáticos se eles não forem instância de um tipo primitivo.
Alterar o valor de valueStatic para 10 vai ainda mais longe, pois o Java fornecerá os mesmos endereços para as duas variáveis int.
fonte
ObjectUtils.identityToString(Object)
. (Além disso, Java não tem passagem por referência de qualquer maneira). Um teste realmente útil seria alocar dois objetos e alterar o valor de umapublic final int FOO = 10
variável usando reflexões Java de maneira forçada. Em seguida, verifique se o outro objeto também alterou seu valor.Embora as outras respostas pareçam deixar bem claro que geralmente não há razão para usar constantes não estáticas, não encontrei ninguém apontando que é possível ter várias instâncias com valores diferentes em suas variáveis constantes.
Considere o seguinte exemplo:
Criar três instâncias do TestClass imprimiria o mesmo valor aleatório três vezes, uma vez que apenas um valor é gerado e armazenado na constante estática.
No entanto, ao tentar o seguinte exemplo:
Criar três instâncias do TestClass agora imprimiria três valores aleatórios diferentes, porque cada instância tem seu próprio valor constante gerado aleatoriamente.
Não consigo pensar em nenhuma situação em que seria realmente útil ter valores constantes diferentes em diferentes instâncias, mas espero que isso ajude a ressaltar que há uma clara diferença entre finais estáticos e não estáticos.
fonte
Como já disse Jon, uma variável estática, também conhecida como variável de classe, é uma variável que existe entre instâncias de uma classe.
Encontrei um exemplo disso aqui :
A saída do programa é dada abaixo:
Como podemos ver neste exemplo, cada objeto tem sua própria cópia da variável de classe.
fonte
Dos testes que fiz, as variáveis finais estáticas não são as mesmas com as variáveis finais (não estáticas)! Variáveis finais (não estáticas) podem diferir de objeto para objeto !!! Mas isso é apenas se a inicialização for feita dentro do construtor! (Se não for inicializado pelo construtor, será apenas um desperdício de memória, pois cria variáveis finais para cada objeto criado que não pode ser alterado.)
Por exemplo:
O que aparece na tela é:
Sobre o objeto: A @ addbf1 Final: 14 Final estático: 5
Sobre o objeto: A @ 530daa Final: 21 Final estático: 5
Anônimo 1º ano estudante de TI, Grécia
fonte
Além da resposta de Jon, se você usar final estático, ele se comportará como uma espécie de "definição". Depois de compilar a classe que a utiliza, ela estará no arquivo .class compilado gravado. Confira meu tópico aqui .
Para seu objetivo principal: Se você não usar o NÚMERO de maneira diferente nas diferentes instâncias da classe, aconselho o uso final e estático. (Lembre-se de não copiar arquivos de classe compilados sem considerar possíveis problemas como o que meu estudo de caso descreve. Na maioria dos casos, isso não ocorre, não se preocupe :))
Para mostrar como usar valores diferentes nas instâncias, verifique este código:
fonte
Aqui estão meus dois centavos:
Exemplo:
A chave é que variáveis e funções podem retornar valores diferentes. Portanto, variáveis finais podem ser atribuídas com valores diferentes.
fonte
Apenas outro exemplo simples para entender o uso de variáveis estáticas, finais estáticas e finais. Os comentários do código têm a explicação adequada.
fonte
muito pouco e estático
Não há muita diferença, pois ambas são constantes. Para a maioria dos objetos de dados da classe, estático significaria algo associado à própria classe, havendo apenas uma cópia, independentemente de quantos objetos foram criados com o novo.
Como é uma constante, ele pode não ser realmente armazenado na classe ou em uma instância, mas o compilador ainda não permitirá que você acesse objetos da instância a partir de um método estático, mesmo que saiba quais seriam. A existência da API de reflexão também pode exigir algum trabalho inútil se você não a tornar estática.
fonte
Como uma variável em uma classe é declarada como final AND inicializada no mesmo comando, não há absolutamente nenhuma razão para não declarar como estática, pois ela terá o mesmo valor, independentemente da instância. Portanto, todas as instâncias podem compartilhar o mesmo endereço de memória para um valor, economizando tempo de processamento, eliminando a necessidade de criar uma nova variável para cada instância e economizando memória compartilhando um endereço comum.
fonte
final estático privado será considerado constante e a constante pode ser acessada somente nesta classe. Como a palavra-chave estática está incluída, o valor será constante para todos os objetos da classe.
O valor da variável final privada será como constante por objeto.
Você pode consultar o java.lang.String ou procurar o exemplo abaixo.
//Resultado:
fonte
O estático é o mesmo membro em todas as instâncias da classe e na própria classe.
O não estático é um para cada instância (objeto); portanto, no seu caso exato , é um desperdício de memória se você não colocar estática.
fonte
Se você marcar esta variável como estática, então, como você sabe, exigiria métodos estáticos para acessar novamente esses valores, isso será útil se você já pensa em usar essas variáveis apenas em métodos estáticos. Se é assim, então seria o melhor.
No entanto, você pode tornar a variável agora pública, já que ninguém pode modificá-la como "System.out", mas depende novamente de suas intenções e do que você deseja alcançar.
fonte
Digamos que, se a classe não tiver mais de uma instância, qual será a memória que mais terá:
ID final int estático privado = 250; ou ID final int privado = 250;
Eu entendi que estático se referirá ao tipo de classe com apenas uma cópia na memória e não estático estará em um novo local de memória para cada variável de instância. No entanto, internamente, se apenas compararmos uma instância da mesma classe (ou seja, mais de uma instância não seria criada), haverá alguma sobrecarga em termos de espaço usado por 1 variável final estática?
fonte
A variável estática pertence à classe (o que significa que todos os objetos compartilham essa variável). Variável não estática pertence a cada objeto.
Como você pode ver no exemplo acima, para "final int" podemos atribuir nossa variável para cada instância (objeto) da classe; no entanto, para "static final int", devemos atribuir uma variável na classe (a variável estática pertence à classe )
fonte
Se você usar estático, o valor da variável será o mesmo em todas as suas instâncias, se alterado em uma instância, as outras também serão alteradas.
fonte
Final: uma vez que uma variável final é atribuída, ela sempre contém o mesmo valor. onde a variável é estática ou não estática: será apenas uma variável para todas as instâncias inicializadas uma vez na Memória
fonte
Isso pode ajudar
fonte
A palavra-chave "Static" cria a propriedade variável da classe em vez de instâncias individuais da classe. Haverá uma cópia dessa variável que é compartilhada entre todas as instâncias dessa classe. Qualquer alteração no estado da variável estática será refletida em todas as instâncias. Adicione final ao static e obteremos uma variável que foi inicializada de uma vez por todas no tempo de carregamento da classe e não pode ser alterada posteriormente por nenhuma instância da classe. Variáveis finais estáticas precisam ser inicializadas no momento da declaração; caso contrário, temos um erro de tempo de compilação. No que diz respeito ao campo de instância privada, ele se refere à propriedade / estado de um objeto / instância de uma classe. Cada instância / objeto da classe terá sua própria cópia da variável de instância. Quando a variável de instância é declarada final, significa que não podemos alterar seu valor para esta instância. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Para isso, precisamos inicializar a variável final na declaração ou no construtor. Se isso não for feito em nenhuma delas, o erro em tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Se não for feito em nenhum deles, o erro de tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Se não for feito em nenhum deles, o erro de tempo de compilação será exibido. Uma vez inicializado, se você tentar reatribuir um valor, receberá um erro de tempo de compilação. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. Use variáveis finais estáticas nas quais os dados serão compartilhados em todas as instâncias da classe e você deseja que os dados sejam somente leitura. Use a variável final da instância se desejar representar alguns dados que pertencem a cada instância individual da classe, mas uma vez armazenado não pode ser alterado. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto. O uso da palavra-chave estática e da instância depende das suas necessidades de design e do que esses dados representam no domínio. Se os dados forem usados nas instâncias da classe, não haverá necessidade de referências individuais de cópias / memória para cada objeto.
fonte