Atributo estático final privado versus atributo final privado

Em Java, qual a diferença entre:

private final static int NUMBER = 10; 

e

 private final int NUMBER = 10; 

Ambos são private e final , a diferença é o atributo static .

O que é melhor? E porque?

Em geral, static significa “associado ao próprio tipo , em vez de uma instância do tipo”.

Isso significa que você pode referenciar 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 class. Então, por exemplo:

 Test x = new Test(); Test y = new Test(); x.instanceVariable = 10; y.instanceVariable = 20; System.out.println(x.instanceVariable); 

imprime 10: y.instanceVariable e x.instanceVariable são separados porque x e y referem a objects diferentes.

Você pode se referir a membros estáticos através de referências, embora seja uma má idéia fazê-lo. Se nós fizemos:

 Test x = new Test(); Test y = new Test(); x.staticVariable = 10; y.staticVariable = 20; System.out.println(x.staticVariable); 

então, imprimiria 20 – há apenas uma variável, não uma por instância. Teria sido mais claro escrever isso como:

 Test x = new Test(); Test y = new Test(); Test.staticVariable = 10; Test.staticVariable = 20; System.out.println(Test.staticVariable); 

Isso torna o comportamento muito mais óbvio. Os IDEs modernos geralmente sugerem a mudança da segunda listview para a terceira.

Não há razão para ter uma declaração como

 private final int NUMBER = 10; 

Se não puder mudar, não faz sentido ter uma cópia por instância.

Para final , pode ser atribuído diferentes valores em tempo de execução quando inicializado. Por exemplo

 Class Test{ public final int a; } Test t1 = new Test(); t1.a = 10; Test t2 = new Test(); t2.a = 20; //fixed 

Assim, cada instância tem um valor diferente de campo a .

Para final estático , todas as instâncias compartilham o mesmo valor e não podem ser alteradas após a primeira boot.

 Class TestStatic{ public static final int a; } TestStatic t1 = new TestStatic(); t1.a = 10; TestStatic t2 = new TestStatic(); t1.a = 20; // ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION. 

Uma variável static permanece na memory durante toda a vida útil do aplicativo e é inicializada durante o carregamento da class. Uma variável não static está sendo inicializada toda vez que você constrói um new object. Geralmente é melhor usar:

 private static final int NUMBER = 10; 

Por quê? Isso reduz o consumo de memory por instância. Possivelmente também é favorável para ocorrências de cache. E isso faz sentido: a static deve ser usada para coisas que são compartilhadas em todas as instâncias (também conhecidas como objects) de um determinado tipo (também conhecido como class ).

meios estáticos “associados à class”; sem isso, a variável é associada a cada instância da class. Se é estático, isso significa que você terá apenas um na memory; Caso contrário, você terá um para cada instância criada. static significa que a variável permanecerá na memory enquanto a class estiver carregada; sem isso, a variável pode ser gc quando sua instância é.

Lendo as respostas, não encontrei nenhum teste real que estivesse realmente chegando ao ponto. Aqui estão meus 2 centavos:

 public class ConstTest { private final int value = 10; private static final int valueStatic = 20; private final File valueObject = new File(""); private static final File valueObjectStatic = new File(""); public void printAddresses() { System.out.println("final int address " + ObjectUtils.identityToString(value)); System.out.println("final static int address " + ObjectUtils.identityToString(valueStatic)); System.out.println("final file address " + ObjectUtils.identityToString(valueObject)); System.out.println("final static file address " + ObjectUtils.identityToString(valueObjectStatic)); } public static void main(final String args[]) { final ConstTest firstObj = new ConstTest(); final ConstTest sndObj = new ConstTest(); firstObj.printAdresses(); sndObj.printAdresses(); } } 

Resultados para o primeiro object:

 final int address java.lang.Integer@6d9efb05 final static int address java.lang.Integer@60723d7c final file address java.io.File@6c22c95b final static file address java.io.File@5fd1acd3 

Resultados para o 2º object:

 final int address java.lang.Integer@6d9efb05 final static int address java.lang.Integer@60723d7c final file address java.io.File@3ea981ca final static file address java.io.File@5fd1acd3 

Conclusão:

Como eu pensei java faz uma diferença entre tipos primitivos e outros. Tipos primitivos em Java são sempre “armazenados em cache”, mesmo para strings literais (não novos objects String), portanto, não há diferença entre membros estáticos e não-estáticos.

No entanto, há uma duplicação de memory para membros não estáticos, se eles não forem uma instância de um tipo primitivo.

Alterar o valor de valueStatic para 10 irá ainda mais longe, pois o Java fornecerá os mesmos endereços para as duas variables ​​int.

Enquanto as outras respostas parecem deixar bem claro que geralmente não há razão para usar constantes não estáticas, não consegui encontrar ninguém apontando que é possível ter várias instâncias com valores diferentes em suas variables ​​constantes.

Considere o seguinte exemplo:

 public class TestClass { private final static double NUMBER = Math.random(); public TestClass () { System.out.println(NUMBER); } } 

Criar três instâncias de TestClass imprimiria o mesmo valor random três vezes, já que apenas um valor é gerado e armazenado na constante estática.

No entanto, ao tentar o seguinte exemplo:

 public class TestClass { private final double NUMBER = Math.random(); public TestClass () { System.out.println(NUMBER); } } 

Criar três instâncias de TestClass agora imprime três valores randoms 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 diferentes valores constantes em instâncias diferentes, mas espero que isso ajude a apontar que há uma clara diferença entre finais estáticos e não estáticos.

Como já disse Jon, uma variável estática, também chamada de variável de class, é uma variável que existe entre instâncias de uma class.

Eu encontrei um exemplo disso aqui :

 public class StaticVariable { static int noOfInstances; StaticVariable() { noOfInstances++; } public static void main(String[] args) { StaticVariable sv1 = new StaticVariable(); System.out.println("No. of instances for sv1 : " + sv1.noOfInstances); StaticVariable sv2 = new StaticVariable(); System.out.println("No. of instances for sv1 : " + sv1.noOfInstances); System.out.println("No. of instances for st2 : " + sv2.noOfInstances); StaticVariable sv3 = new StaticVariable(); 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 object tem sua própria cópia da variável de class.

 C:\java>java StaticVariable No. of instances for sv1 : 1 No. of instances for sv1 : 2 No. of instances for st2 : 2 No. of instances for sv1 : 3 No. of instances for sv2 : 3 No. of instances for sv3 : 3 

Dos testes que fiz, as variables ​​finais estáticas não são as mesmas com as variables ​​finais (não-estáticas)! Variáveis ​​finais (não estáticas) podem diferir de object para object !!! Mas isso é só se a boot for feita dentro do construtor! (Se não for inicializado a partir do construtor, será apenas um desperdício de memory, pois cria variables ​​finais para cada object criado que não pode ser alterado.)

Por exemplo:

 class A { final int f; static final int 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); } public static void main(String[] args) { A ob1 = new A(14); ob1.show(); A ob2 = new A(21); ob2.show(); } } 

O que aparece na canvas é:

Sobre o Objeto: A @ addbf1 Final: 14 Estático Final: 5

Sobre o Objeto: A @ 530daa Final: 21 Static Final: 5

Anônimo estudante de TI do 1º ano, Grécia

Além disso, para a resposta de Jon, se você usar a final estática, ela se comportará como uma espécie de “definição”. Depois de compilar a class que a usa, ela estará no arquivo .class compilado. Verifique meu tópico sobre isso aqui .

Para o seu objective principal: Se você não usar o NUMBER de forma diferente nas diferentes instâncias da class, aconselho usar final e estático. (Você só precisa se lembrar de não copiar arquivos compilados da class sem considerar possíveis problemas como o descrito no meu estudo de caso. 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:

 public class JustFinalAttr { public final int Number; public JustFinalAttr(int a){ Number=a; } } ...System.out.println(new JustFinalAttr(4).Number); 

Aqui estão meus dois centavos:

 final String CENT_1 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS"; final static String CENT_2 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS"; 

Exemplo:

 package test; public class Test { final long OBJECT_ID = new Random().nextLong(); final static long CLASSS_ID = new Random().nextLong(); public static void main(String[] args) { Test[] test = new Test[5]; for (int i = 0; i < test.length; i++){ test[i] = new Test(); System.out.println("Class id: "+test[i].CLASSS_ID);//<- Always the same value System.out.println("Object id: "+test[i].OBJECT_ID);//<- Always different } } } 

A chave é que as variables ​​e funções podem retornar valores diferentes. Portanto, as variables ​​finais podem ser atribuídas com valores diferentes.

muito pouco e estático

Não há muita diferença, pois ambas são constantes. Para a maioria dos objects de dados de class, static significaria algo associado à própria class, havendo apenas uma cópia, não importando quantos objects fossem criados com new.

Como é uma constante, ela pode não ser armazenada na class ou em uma instância, mas o compilador ainda não permitirá que você acesse objects da instância a partir de um método estático, mesmo que saiba o que eles seriam. A existência da API de reflection também pode exigir algum trabalho inútil se você não torná-la estática.

Como uma variável em uma class é declarada como final e inicializada no mesmo comando, não há absolutamente nenhum motivo para não declará-la como estática, pois ela terá o mesmo valor, independentemente da instância. Assim, todas as instâncias podem compartilhar o mesmo endereço de memory para um valor, economizando tempo de processamento, eliminando a necessidade de criar uma nova variável para cada instância e economizando memory compartilhando um endereço comum.

final estático privado será considerado como constante e a constante pode ser acessada somente dentro desta class. Como a palavra-chave estática incluída, o valor será constante para todos os objects da class.

O valor da variável final privada será como constante por object.

Você pode consultar o java.lang.String ou procurar o exemplo abaixo.

 public final class Foo { private final int i; private static final int j=20; public Foo(int val){ this.i=val; } public static void main(String[] args) { Foo foo1= new Foo(10); Foo foo2= new Foo(40); System.out.println(foo1.i); System.out.println(foo2.i); System.out.println(check.j); } } 

//Saída:

 10 40 20 

O estático é o mesmo membro em todas as instâncias de classs e na própria class.
O não-estático é um para cada instância (object), portanto, no seu caso exato , é um desperdício de memory se você não colocar estática.

Se você marcar esta variável como estática, como você sabe, você precisaria de methods estáticos para acessar novamente esses valores, isso será útil se você já pensar em usar essas variables ​​apenas em methods estáticos. Se assim for, então este seria o melhor.

Você pode, no entanto, tornar a variável agora pública, já que ninguém pode modificá-la como “System.out”, novamente depende de suas intenções e do que você deseja alcançar.

Digamos que se a class não tiver mais de uma instância, então qual delas recebe mais memory:

final estático privado int ID = 250; ou int final privado ID = 250;

Eu entendi que estática se referirá ao tipo de class com apenas uma cópia na memory e não estático estará em um novo local de memory para cada variável de instância. No entanto, internamente, se apenas compararmos uma instância da mesma class (ou seja, mais de 1 instância não seria criada), existe alguma sobrecarga em termos de espaço usado por uma variável final estática?

Variável estática pertence à class (o que significa que todos os objects compartilham essa variável). Variável não estática pertence a cada object.

 public class ExperimentFinal { private final int a; private static final int b = 999; public ExperimentFinal(int a) { super(); this.a = a; } public int getA() { return a; } public int getB() { return b; } public void print(int a, int b) { System.out.println("final int: " + a + " \nstatic final int: " + b); } public static void main(String[] args) { ExperimentFinal test = new ExperimentFinal(9); test.print(test.getA(), test.getB()); } } 

Como você pode ver acima exemplo, para “final int” podemos atribuir nossa variável para cada instância (object) da class, porém para “static final int”, devemos atribuir uma variável na class (variável estática pertence à class ).

Apenas mais um exemplo simples para entender o uso de variables ​​finais estáticas, estáticas e finais. Comentários de código têm a devida explicação.

 public class City { // base price that is always same for all objects[For all cities]. private static double iphone_base_price = 10000; // this is total price = iphone_base_price+iphone_diff; private double iphone_citi_price; // extra price added to iphone_base_price. It is constant per city. Every // city has its own difference defined, private final double iphone_diff; private String cityName = ""; // static final will be accessible everywhere within the class but cant be // changed once initialized. private static final String countryName = "India"; public City(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 */ private double getPrice() { return iphone_citi_price; } /** * Get city name * * @return */ private String getCityName() { return cityName; } public static void main(String[] args) { // 300 is the City newyork = new City("Newyork", 300); System.out.println(newyork.getPrice() + " " + newyork.getCityName()); City california = new City("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 = new City("delhi", 400); System.out.println(delhi.getPrice() + " " + delhi.getCityName()); City moscow = new City("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 statements System.out.println(countryName); // countryName="INDIA"; // System.out.println(countryName); } } 

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.

Isso pode ajudar

 public class LengthDemo { public static void main(String[] args) { Rectangle box = new Rectangle(); System.out.println("Sending the value 10.0 " + "to the setLength method."); box.setLength(10.0); System.out.println("Done."); } }