O que faz o 'estático' palavra-chave fazer em uma classe?
-
03-07-2019 - |
Pergunta
Para ser mais específico, eu estava tentando este código:
package hello;
public class Hello {
Clock clock = new Clock();
public static void main(String args[]) {
clock.sayTime();
}
}
Mas deu o erro
Não é possível o acesso de campo não estático no método estático principal
Então eu mudei a declaração de clock
a esta:
static Clock clock = new Clock();
E funcionou. O que significa colocar a palavra-chave antes da declaração? O que exatamente ele vai fazer e / ou restringir em termos do que pode ser feito para esse objeto?
Solução
membros static
pertencem à classe em vez de uma instância específica.
Isso significa que apenas uma instância de um campo static
existe [1] , mesmo se você criar um milhão de instâncias da classe ou você não criar qualquer. Ele vai ser compartilhado por todas as instâncias.
Desde métodos static
também não pertencem a uma instância específica, eles não podem referir-se a membros de instância. No exemplo dado, main
não sabe qual instância da classe Hello
(e, portanto, qual instância da classe Clock
) deve se referir. membros static
só pode se referir aos membros static
. membros de instância pode, naturalmente membros acesso static
.
Nota lateral:. É claro, os membros static
pode acessar membros de instância através de uma referência de objeto
Exemplo:
public class Example {
private static boolean staticField;
private boolean instanceField;
public static void main(String[] args) {
// a static method can access static fields
staticField = true;
// a static method can access instance fields through an object reference
Example instance = new Example();
instance.instanceField = true;
}
[1]:. Dependendo das características de execução, pode ser um por ClassLoader ou AppDomain ou segmento, mas que é ao lado do ponto
Outras dicas
Isso significa que existe apenas uma instância do "relógio" em Olá, não um por cada instância separada do "Olá" classe, ou mais-lo, isso significa que haverá um comumente compartilhada de referência "relógio" entre todas as instâncias do "Olá" classe.
Então, se você fosse fazer um "novo Olá" em qualquer lugar no seu código: A- no primeiro cenário (antes da mudança, sem usar "estático"), que faria um novo relógio cada vez que um "novo Olá" é chamado, mas B- no segundo cenário (após a mudança, utilizando "estático"), cada "nova Olá" instância seria ainda compartilhar e usar a referência inicial e mesmo "relógio" criada pela primeira vez.
A menos que você precisava de "relógio" do lado de fora em algum lugar de principal, este iria funcionar tão bem:
package hello;
public class Hello
{
public static void main(String args[])
{
Clock clock=new Clock();
clock.sayTime();
}
}
Os meios static
-chave que alguma coisa (um campo, método ou classe aninhada) está relacionado com o tipo em vez de qualquer particular, exemplo do tipo. Assim, por exemplo, um chamadas Math.sin(...)
sem qualquer instância da classe Math
, e na verdade você não pode criar uma instância da classe Math
.
Para obter mais informações, consulte a pouco relevante do Java da Oracle Tutorial .
Sidenote
Java infelizmente permite você aos membros acesso estáticas como se fossem membros de instância, por exemplo.
// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
Isso torna olhar como se sleep
é um método de instância, mas na verdade é um método estático - ele sempre faz com que o sono thread atual. É melhor prática para fazer isso claro no código de chamada:
// Clearer
Thread.sleep(5000);
A palavra-chave static
no meio Java que a variável ou função é compartilhado entre todas as instâncias dessa classe, uma vez que pertence à tipo , e não os próprios objetos reais.
Então, se você tem uma variável: private static int i = 0;
e incrementá-lo (i++
) em um exemplo, a alteração será refletida em todas as instâncias. i
será agora 1 em todas as instâncias.
métodos estáticos pode ser utilizado sem instanciar um objecto.
O uso básico de membros estáticos ...
public class Hello
{
// value / method
public static String staticValue;
public String nonStaticValue;
}
class A
{
Hello hello = new Hello();
hello.staticValue = "abc";
hello.nonStaticValue = "xyz";
}
class B
{
Hello hello2 = new Hello(); // here staticValue = "abc"
hello2.staticValue; // will have value of "abc"
hello2.nonStaticValue; // will have value of null
}
É assim que você pode ter valores compartilhados em todos os membros da classe sem o envio de instância de classe Olá a outra classe. E br estática você não precisa criar instância de classe.
Hello hello = new Hello();
hello.staticValue = "abc";
Você pode apenas chamar valores ou métodos estáticos pelo nome da classe:
Hello.staticValue = "abc";
estático em Java:
estática é um acesso modificador não. A palavra-chave estática pertence à classe de instância da classe. pode ser usado para anexar uma variável ou método a uma classe.
palavra-chave estática pode ser usado com:
Método
variável
classe aninhada dentro de outra classe
A inicialização do bloco
não pode ser usado com:
Class (Não Nested)
Construtor
Interfaces
Método Inner Classe Local (Diferença então classe aninhada)
métodos de classe interna
variáveis ??de instância
Variáveis ??locais
Imagine a seguinte exemplo que tem um variável de instância chamada count que por incrementado no construtor:
package pkg;
class StaticExample {
int count = 0;// will get memory when instance is created
StaticExample() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
StaticExample c1 = new StaticExample();
StaticExample c2 = new StaticExample();
StaticExample c3 = new StaticExample();
}
}
Output:
1 1 1
Uma vez que a variável de instância obtém a memória no momento da criação do objeto, cada objeto terá a cópia da variável exemplo, se ele é incrementado, ele não vai refletir a outros objetos.
Agora, se nós alterar a variável de instância contagem a um estático um, então o programa irá produzir uma saída diferente:
package pkg;
class StaticExample {
static int count = 0;// will get memory when instance is created
StaticExample() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
StaticExample c1 = new StaticExample();
StaticExample c2 = new StaticExample();
StaticExample c3 = new StaticExample();
}
}
Output:
1 2 3
Neste variável caso estático vai ficar na memória apenas uma vez, se qualquer objeto muda o valor da variável estática, ele irá manter o seu valor.
estático com o Final:
A variável global que é declarado como final e estática permanece inalterada durante toda a execução. Porque, membros estáticos são armazenados na memória de classe e eles são carregados apenas uma vez em toda a execução. Eles são comuns a todos os objetos da classe. Se você declarar variáveis ??estáticas como final, qualquer um dos objetos não pode mudar o seu valor, pois é final. Portanto, as variáveis ??declaradas como final e estática são muitas vezes referidos como constantes. Todos os campos de interfaces são referidos como constantes, porque eles são finais e estático por padrão.
Resource Imagem: static final
meios estáticos que você não tem que criar uma instância da classe para usar os métodos ou variáveis ??associadas com a classe. No seu exemplo, você poderia chamar:
Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class
diretamente, em vez de:
Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable
De dentro de um método estático (que pertence a uma classe), você não pode acessar quaisquer membros que não são estáticos, uma vez que seus valores dependem de sua instanciação da classe. Um Relógio objeto não estático, que é um membro de instância, teria um valor / referência diferente para cada instância de sua classe Olá, e, portanto, você não pode acessá-lo a partir da parte estática da classe.
Esta discussão tem, até agora ignorada classloader considerações. Estritamente falando, campos estáticos em Java são compartilhados entre todas as instâncias de uma classe para um determinado carregador de classe .
Um campo pode ser atribuído a qualquer classe ou uma instância de uma classe. Por campos padrão são variáveis ??de instância. Usando static
o campo torna-se uma variável de classe, portanto, há uma e apenas uma clock
. Se você faz uma alteração em um único lugar, é visível em todos os lugares. varables instância são alterados de forma independente um do outro.
O static
palavra-chave é utilizada para designar uma área ou um método como pertencendo à classe em si e não a ocorrência. Usando o seu código, se o objeto Clock
é estática, todas as instâncias da classe Hello
irá compartilhar este membro de dados Clock
(campo) em comum. Se você faz non-static, cada instância individual de Hello
pode ter um campo Clock
único.
O problema é que você adicionou um main para o seu Hello
classe para que você possa executar o código. O problema aqui é que o main método é estático e, como tal, não pode se referir a campos não-estático ou métodos de dentro dela. Você pode resolver isso de duas maneiras:
- Faça todos os campos e métodos da classe estática
Hello
para que pudessem ser referido dentro do main método. Isto não é realmente uma coisa boa para fazer (ou pelo motivo errado t fazer um campo e / ou um método estático) - Criar uma instância de sua classe
Hello
dentro do método principal e acessar todos os campos de TI e métodos da maneira que eles tinham a intenção de, em primeiro lugar.
Para você, isso significa a seguinte alteração ao seu código:
package hello;
public class Hello {
private Clock clock = new Clock();
public Clock getClock() {
return clock;
}
public static void main(String args[]) {
Hello hello = new Hello();
hello.getClock().sayTime();
}
}
Em Java, a palavra-chave static
pode ser simplesmente considerado como indicando o seguinte:
"sem levar em conta ou relação a qualquer instância específica"
Se você pensar em static
desta forma, torna-se mais fácil compreender a sua utilização nos diversos contextos em que ele é encontrado:
-
Um campo
static
é um campo que pertence à classe e não a qualquer instância específica -
Um método
static
é um método que não tem noção dethis
; ele é definido na classe e não sabe sobre qualquer caso particular dessa classe, a menos que uma referência é passado para ele -
Uma classe membro
static
é uma classe aninhada sem qualquer noção ou o conhecimento de um exemplo da sua classe envolvente (a menos que uma referência a uma instância da classe envolvente é passado para ele)
estática faz com que o membro do relógio um membro da classe em vez de um membro de instância. Sem o estático palavra-chave que você precisa para criar uma instância da classe Olá (que tem uma variável membro do relógio) -. Por exemplo
Hello hello = new Hello();
hello.clock.sayTime();
métodos estáticos não utilize variáveis ??de instância da classe são definidos em. Uma boa explicação da diferença pode ser encontrado em desta página
Eu desenvolvi um gosto para métodos estáticos (somente, se possível) em classes "ajudante".
A necessidade classe chamada não criar uma outra variável de membro (instância) da classe auxiliar. Você acabou de chamar os métodos da classe auxiliar. Além disso, a classe auxiliar é melhorada, porque você não precisa mais de um construtor, e você não precisa de variáveis ??(instância) de membro.
Há provavelmente outras vantagens.
também pode pensar em membros estáticos não tendo um ponteiro "este". Eles são compartilhados entre todas as instâncias.
Compreender conceitos estáticos
public class StaticPractise1 {
public static void main(String[] args) {
StaticPractise2 staticPractise2 = new StaticPractise2();
staticPractise2.printUddhav(); //true
StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */
StaticPractise2.printUddhavsStatic1(); //true
staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static things and it organizes in its own heap. So, class static methods, object can't reference */
}
}
Second Class
public class StaticPractise2 {
public static void printUddhavsStatic1() {
System.out.println("Uddhav");
}
public void printUddhav() {
System.out.println("Uddhav");
}
}
//Here is an example
public class StaticClass
{
static int version;
public void printVersion() {
System.out.println(version);
}
}
public class MainClass
{
public static void main(String args[]) {
StaticClass staticVar1 = new StaticClass();
staticVar1.version = 10;
staticVar1.printVersion() // Output 10
StaticClass staticVar2 = new StaticClass();
staticVar2.printVersion() // Output 10
staticVar2.version = 20;
staticVar2.printVersion() // Output 20
staticVar1.printVersion() // Output 20
}
}
main()
é um método estático que tem duas restrições fundamentais:
- O método estático não pode usar um membro de dados não-estático ou diretamente chamar o método não-estático.
-
this()
esuper()
não pode ser usado no contexto estático.class A { int a = 40; //non static public static void main(String args[]) { System.out.println(a); } }
Saída: tempo de compilação Erro
Variáveis ??estáticas Só pode ser acessada apenas em métodos estáticos, por isso, quando nós declaramos as variáveis ??estáticas esses métodos get e set será métodos estáticos
métodos estáticos é um nível de classe que pode acessar usando nome da classe
A seguir é exemplo para estáticos Variáveis ??getters e setters:
public class Static
{
private static String owner;
private static int rent;
private String car;
public String getCar() {
return car;
}
public void setCar(String car) {
this.car = car;
}
public static int getRent() {
return rent;
}
public static void setRent(int rent) {
Static.rent = rent;
}
public static String getOwner() {
return owner;
}
public static void setOwner(String owner) {
Static.owner = owner;
}
}
Ao executar algum projeto em primeiro lugar carregar coisas estático (variáveis, métodos, blocos ..).
Ao executar este projeto principal método load primeiro. Devido a sua static method
. Em seguida, ele olha objeto "a" object
.mas objeto não é uma definição ainda. Porque sua não estática. Em seguida, vêm como este erro.