Um guia para a palavra-chave estática em Java
1. Introdução
Neste artigo, exploraremos a palavra-chavestatic da linguagem Java em detalhes. Vamos descobrir como podemos aplicar a palavra-chavestatic a variáveis, métodos, blocos, classes aninhadas e que diferença isso faz.
2. A anatomia da palavra-chavestatic
Na linguagem de programação Java,the keyword static indicates that the particular member belongs to a type itself, rather than to an instance of that type.
Isso significa que apenas uma instância desse membro estático é criada e compartilhada em todas as instâncias da classe.
A palavra-chave pode ser aplicada a variáveis, métodos, blocos e classe aninhada.
3. Os camposstatic (ou variáveis de classe)
Em Java,if a field is declared static, then exactly a single copy of that field is created and shared among all instances of that class. Não importa quantas vezes inicializamos uma classe; sempre haverá apenas uma cópia do campostatic pertencente a ele. O valor deste campostatic será compartilhado por todos os objetos de qualquer classe diferente.
Do ponto de vista da memória,static variables go in a particular pool in JVM memory called Metaspace (antes do Java 8, esse pool era chamado de Geração Permanente ou PermGen, que foi completamente removido e substituído por Metaspace).
3.1. Exemplo do campostatic
Suponha que tenhamos uma classeCar com vários atributos (variáveis de instância). Sempre que novos objetos são inicializados a partir deste blueprintCar, cada novo objeto terá sua cópia distinta dessas variáveis de instância.
No entanto, suponha que estamos procurando uma variável que contém a contagem do número de objetosCar que são inicializados e é compartilhada por todas as instâncias de forma que eles possam acessá-la e incrementá-la em sua inicialização.
É aí que entram as variáveisstatic:
public class Car {
private String name;
private String engine;
public static int numberOfCars;
public Car(String name, String engine) {
this.name = name;
this.engine = engine;
numberOfCars++;
}
// getters and setters
}
Agora, para cada objeto desta classe que é inicializado, a mesma cópia da variávelnumberOfCars é incrementada. Portanto, neste caso, as seguintes afirmações serão verdadeiras:
@Test
public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() {
new Car("Jaguar", "V8");
new Car("Bugatti", "W16");
assertEquals(2, Car.numberOfCars);
}
3.2. Razões convincentes para usar os camposstatic
-
Quando o valor da variável é independente dos objetos
-
Quando o valor deve ser compartilhado entre todos os objetos
3.3. Pontos-chave para lembrar
-
Como as variáveisstatic pertencem a uma classe, elas podem ser acessadas diretamente usando o nome da classe e não precisam de nenhuma referência de objeto
-
Variáveisstatic só podem ser declaradas no nível da classe
-
static campos podem ser acessados sem inicialização de objeto
-
Embora possamos acessar os camposstatic usando uma referência de objeto (comoford.numberOfCars_) , we should refrain from using it as in this case it becomes difficult to figure whether it’s an instance variable or a class variable; instead, we should always refer to _static_ variables using class name (for example, in this case, _Car.numberOfCars)
4. Os métodosstatic (ou métodos de classe)
Semelhante aos camposstatic, os métodosstatic também pertencem a uma classe em vez do objeto e, portanto, podem ser chamados sem criar o objeto da classe em que residem. Eles devem ser usados sem criar objetos da classe.
4.1. Exemplo de métodostatic
Os métodosstatic geralmente são usados para realizar uma operação que não depende da criação da instância.
Se houver um código que deve ser compartilhado entre todas as instâncias dessa classe, escreva esse código em um métodostatic:
public static void setNumberOfCars(int numberOfCars) {
Car.numberOfCars = numberOfCars;
}
Os métodosstatic também são amplamente usados para criar classes utilitárias ou auxiliares para que possam ser obtidos sem a criação de um novo objeto dessas classes.
Dê uma olhada nas classes de utilitáriosCollections ouMath do JDK,StringUtils do Apache ouCollectionUtils do framework Spring e observe que todos os métodos sãostatic.
4.2. Razões convincentes para usar métodosstatic
-
Para acessar / manipular variáveis estáticas e outros métodos estáticos que não dependem de objetos
-
Métodosstatic são amplamente usados em classes utilitárias e auxiliares
4.3. Pontos-chave para lembrar
-
Métodosstatic em Java são resolvidos em tempo de compilação. Como a substituição de método é parte do polimorfismo de tempo de execução,so static methods can’t be overridden
-
métodos abstratos não podem ser estáticos
-
Os métodosstatic não podem usar palavras-chavethis ousuper
-
As seguintes combinações da instância, métodos e variáveis de classe são válidas:
-
Os métodos de instância podem acessar diretamente os métodos de instância e as variáveis de instância
-
Métodos de instância também podem acessar variáveisstatic e métodosstatic diretamente
-
Os métodosstatic podem acessar todas as variáveisstatic e outros métodosstatic
-
static methods cannot access instance variables and instance methods directly; eles precisam de alguma referência de objeto para fazer isso
-
5. Bloco Astatic
Um blocostatic é usado para inicializar as variáveisstatic. Embora as variáveisstatic possam ser inicializadas diretamente durante a declaração, há situações em que somos obrigados a fazer o processamento multilinha.
Nesses casos, blocosstatic são úteis.
Se as variáveisstatic exigirem lógica adicional de múltiplas instruções durante a inicialização, um blocostatic pode ser usado.
5.1. O Exemplo de Blocostatic
Suponha que desejemos inicializar um objeto de lista com alguns valores predefinidos.
Isso se torna fácil com blocos destatic:
public class StaticBlockDemo {
public static List ranks = new LinkedList<>();
static {
ranks.add("Lieutenant");
ranks.add("Captain");
ranks.add("Major");
}
static {
ranks.add("Colonel");
ranks.add("General");
}
}
Neste exemplo, não seria possível inicializar o objetoList com todos os valores iniciais junto com a declaração; e é por isso que usamos o blocostatic aqui.
5.2. Razões convincentes para usar blocos destatic
-
Se a inicialização das variáveisstatic requer alguma lógica adicional, exceto a atribuição
-
Se a inicialização de variáveis estáticas for suscetível a erros e exigir tratamento de exceção
5.3. Pontos-chave para lembrar
-
Uma classe pode ter vários blocosstatic
-
static campos e blocosstatic são resolvidos e executados na mesma ordem em que estão presentes na classe
6. Classe Astatic
A linguagem de programação Java nos permite criar uma classe dentro de uma classe. Ele fornece uma maneira convincente de agrupar elementos que serão usados apenas em um único local, o que ajuda a manter nosso código mais organizado e legível.
A arquitetura de classe aninhada é dividida em duas:
-
classes aninhadas que são declaradasstatic são chamadasstatic nested classes enquanto,
-
classes aninhadas que não sãostatic são chamadasinner classes
A principal diferença entre essas duas é que as classes internas têm acesso a todos os membros da classe envolvente (incluindo privada), enquanto as classes aninhadasstatic têm acesso apenas a membros estáticos da classe externa.
Na verdade,static nested classes behaved exactly like any other top-level class but enclosed in the only class which will access it, to provide better packaging convenience.
6.1. Exemplo de classestatic
A abordagem mais amplamente usada para criar objetos singleton é por meio da classe aninhadastatic, que não requer sincronização e é fácil de aprender e implementar:
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
6.2. Razões convincentes para usar uma classe internastatic
-
O agrupamento de classes que serão usadas apenas em um local aumenta o encapsulamento
-
O código é aproximado do local que será o único a usá-lo; isso aumenta a legibilidade e o código é mais sustentável
-
Se a classe aninhada não requer nenhum acesso a seus membros de instância de classe envolvente, então é melhor declará-la comostatic porque desta forma, ela não será acoplada à classe externa e, portanto, será mais ideal, pois eles não exigirá qualquer heap ou memória de pilha
6.3. Pontos-chave para lembrar
-
static nested classes do not have access to any instance members of the enclosing outer class; ele só pode acessá-los por meio da referência de um objeto
-
classes aninhadas estáticas podem acessar todos os membros estáticos da classe envolvente, incluindo os privados
-
A especificação de programação Java não nos permite declarar a classe de nível superior comostatic; apenas classes dentro das classes (classes aninhadas) podem ser feitas comostatic
7. Conclusão
Neste artigo, vimos a palavra-chavestatic em ação. Também lemos sobre as razões e vantagens do uso de campos estáticos, métodos estáticos, blocos estáticos e classes internas estáticas.
Como sempre, podemos encontrar o código completoover on GitHub.