Classes estáticas em Java

947

Existe algo como static classem java?

Qual é o significado dessa classe. Todos os métodos da classe estática também precisam ser static?

É necessário o contrário, que se uma classe contiver todos os métodos estáticos, a classe também deve ser estática?

Para que servem as classes estáticas?

Kraken
fonte
4
Você pode estar interessado em stackoverflow.com/questions/3584113/java-static-class
Ishtar
Classes estáticas são basicamente usadas para agrupar classes.
RockingDev 15/0418

Respostas:

847

Java possui classes aninhadas estáticas , mas parece que você está procurando uma classe estática de nível superior. Java não tem como tornar estática uma classe de nível superior, mas você pode simular uma classe estática como esta:

  • Declarar sua classe final- Impede a extensão da classe, pois estender uma classe estática não faz sentido
  • Crie o construtor private- Impede a instanciação pelo código do cliente, pois não faz sentido instanciar uma classe estática
  • Tornar todos os membros e funções da classe static- Como a classe não pode ser instanciada, nenhum método de instância pode ser chamado ou campos de instância acessados
  • Observe que o compilador não impedirá que você declare um membro da instância (não estático). O problema será exibido apenas se você tentar chamar o membro da instância

Exemplo simples por sugestões acima:

public class TestMyStaticClass {
     public static void main(String []args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); // results in compile time error
     }
}

// A top-level Java class mimicking static class behavior
public final class MyStaticClass {
    private MyStaticClass () { // private constructor
        myStaticMember = 1;
    }
    private static int myStaticMember;
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

De que servem as classes estáticas? Um bom uso de uma classe estática é na definição de classes pontuais, utilitárias e / ou de biblioteca, em que a instanciação não faria sentido. Um ótimo exemplo é a classe Math, que contém algumas constantes matemáticas, como PI e E, e simplesmente fornece cálculos matemáticos. Exigir instanciação nesse caso seria desnecessário e confuso. Veja a Mathclasse e o código fonte . Observe que é finale todos os seus membros são static. Se o Java permitisse que classes de nível superior fossem declaradas static, a classe Math seria realmente estática.

Paul Sasik
fonte
35
uma classe Foocom apenas staticmétodos não é o mesmo questatic class Foo
craigb
12
@Evorlor: Se uma classe é declarada final, então seus métodos são automaticamente (efetivamente) finais. Isso ocorre porque uma classe final não pode ser subclassificada e, portanto, seus métodos não podem ser substituídos (ou seja, são efetivamente finais). docs.oracle.com/javase/tutorial/java/IandI/final.html
jwayne 15/03
30
Essa resposta talvez aborda o que o OP significava, mas (atualmente) não explica as classes estáticas do Java e, portanto, não responde à pergunta! Isso é muito ruim para as pessoas que chegam aqui tentando descobrir o que uma classe estática significa em Java.
Tom
12
@JBoy: Existe uma coisa como "classe estática" em Java, que é a questão, mas essa resposta não explica nada. Em vez disso, explica como simular em Java o que a resposta chama de "classe estática" - mas que não é o que é uma "classe estática" em Java! (Talvez seja o que é chamado de "classe estática" em algum outro idioma (s), mas as pessoas que vêm aqui para aprender sobre classes estáticas Java, serão enganados e confundidos.)
Tom
4
você deve mencionar explicitamente que private MyStaticClass () {// construtor privado myStaticMember = 1; } não terá efeito, pois o construtor não será chamado. Mas este não é o ponto. Ainda estou muito confuso sobre a utilidade das classes internas estáticas em Java e sua utilidade ou valor agregado.
23417 Moldovean
316

Bem, o Java possui "classes aninhadas estáticas", mas não são iguais às classes estáticas do C #, se é de onde você veio. Uma classe aninhada estática é apenas uma que não tem implicitamente uma referência a uma instância da classe externa.

Classes aninhadas estáticas podem ter métodos de instância e métodos estáticos.

Não existe classe estática de nível superior em Java.

Jon Skeet
fonte
12
Em Java Por que a classe aninhada estática permite métodos de instância? Qual é o uso de um método de instância nessa classe?
Geek
19
@ Geek: Você leu minha resposta? Leia a segunda frase com atenção. Por que você não gostaria de ter métodos de instância de classes estáticas? Você pode criar instâncias deles, afinal.
21813 Jon Skeet
17
@ Geek: Sim, é totalmente permitido. Seu "entendimento" de que classes estáticas são classes de utilidade está incorreto, basicamente. Não é isso que classes estáticas em Java significam.
precisa
14
@ Geek: Sim. Exatamente como escrevi na minha resposta: "Uma classe aninhada estática é apenas aquela que não tem implicitamente uma referência a uma instância da classe externa".
Jon tiro ao prato
6
@KhurramAli: Você quer dizer implicitamente ? Eles certamente não são explicitamente estáticos, já que você não usa a palavra-chave staticao declará-las. Eles são implicitamente estáticos, pois você não precisa de referência a mais nada para construir um. Pessoalmente, acho a terminologia estática / não estática um pouco estranha para classes aninhadas de qualquer maneira ... Eu acho que seria mais simples falar sobre qual é o comportamento.
Jon Skeet
157

Há uma classe aninhada estática , essa classe [aninhada estática] não precisa de uma instância da classe envolvente para ser instanciada.

Essas classes [aninhadas estáticas] podem acessar apenas os membros estáticos da classe anexa [já que ela não tem nenhuma referência a instâncias da classe anexa ...]

amostra de código:

public class Test { 
  class A { } 
  static class B { }
  public static void main(String[] args) { 
    /*will fail - compilation error, you need an instance of Test to instantiate A*/
    A a = new A(); 
    /*will compile successfully, not instance of Test is needed to instantiate B */
    B b = new B(); 
  }
}
amit
fonte
1
Então, podemos dizer que podemos usar classes estáticas internas para instancia-las sem a necessidade de torná-las públicas?
22417 Moldovean
@moldovean Usamos classes estáticas internas para instancia-las a partir de um contexto estático (como main). Não acho que tenha algo a ver com visibilidade.
quer
2
@moldovean estático / não estático é ortogonal à visibilidade. Você pode ter qualquer tipo de visibilidade com estática ou não estática. A questão é: você precisa de uma instância da classe envolvente para criar a interna?
Amit
103

Sim, há uma classe aninhada estática em java. Quando você declara estática uma classe aninhada, ela se torna automaticamente uma classe independente que pode ser instanciada sem precisar instanciar a classe externa à qual ela pertence.

Exemplo:

public class A
{

 public static class B
 {
 }
}

Como class Bé declarado estático, você pode instanciar explicitamente como:

B b = new B();

Observe que se class Bnão foi declarado estático para torná-lo independente, uma chamada de objeto de instância teria a seguinte aparência:

A a= new A();
B b = a.new B();
Bitmap
fonte
7
note que você pode instanciar a classe não estática regularmente, como B b = new B();se estivesse tentando instancia-la da Aprópria classe .
Muhammed Refaat
33

O que está acontecendo quando um membro dentro de um classé declarado como static..? Esses membros podem ser acessados ​​sem instanciar o class. Portanto, criar classe externa (classe de nível superior) staticnão tem significado. Portanto, não é permitido.

Mas você pode definir classes internas como estáticas (como membro da classe de nível superior). Em seguida, essa classe pode ser acessada sem instanciar a classe de nível superior. Considere o seguinte exemplo.

public class A {
    public static class B {

    }
}

Agora, dentro de uma classe diferente C, a classe Bpode ser acessada sem criar uma instância da classe A.

public class C {
    A.B ab = new A.B();
}

staticas classes também podem ter non-staticmembros. Somente a classe fica estática.

Mas se a staticpalavra-chave for removida da classe B, ela não poderá ser acessada diretamente sem criar uma instância de A.

public class C {
    A a = new A();
    A.B ab = a. new B();
}

Mas não podemos ter staticmembros dentro de uma non-staticclasse interna.

Ramesh-X
fonte
Podemos instanciar uma classe estática ou faz sentido?
Supun Wijerathne
6
Não é como em outros idiomas, statictem apenas um significado em java. Se algo estiver staticem uma classe, significa que ela pode ser acessada sem instanciar essa classe. Ele não diz nada sobre a criação de instâncias ou não ..
Ramesh-X
Desculpe stackoverflow! Não posso deixar de agradecer Ramesh-X neste caso! Você cobriu quase tudo o que me perguntava sobre classes internas estáticas e classes internas.
23417 Moldovean
Você não pode 'definir classes internas como estáticas'. Isso é uma contradição em termos . Uma classe aninhada é interna ou estática.
Marquês de Lorne,
13

Visto que este é o melhor resultado do Google para "classe estática java" e a melhor resposta não está aqui, achei que o adicionaria. Estou interpretando a pergunta do OP em relação às classes estáticas em C #, conhecidas como singletons no mundo Java. Para quem não sabe, em C # a palavra-chave "estática" pode ser aplicada a uma declaração de classe, o que significa que a classe resultante nunca pode ser instanciada.

Trecho de "Effective Java - Second Edition", de Joshua Bloch (amplamente considerado um dos melhores guias de estilo Java disponíveis):

Desde o release 1.5, existe uma terceira abordagem para implementar singletons. Simplesmente faça um tipo de enumeração com um elemento:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

Essa abordagem é funcionalmente equivalente à abordagem de campo público, exceto que é mais concisa, fornece o mecanismo de serialização gratuitamente e oferece uma garantia rígida contra instanciações múltiplas, mesmo em face de sofisticados ataques de serialização ou reflexão. Embora essa abordagem ainda não tenha sido amplamente adotada, um tipo de enum de elemento único é a melhor maneira de implementar um singleton. (ênfase do autor)

Bloch, Joshua (08-05-2008). Java efetivo (Java Series) (p. 18). Pearson Education.

Eu acho que a implementação e justificativa são bastante auto-explicativas.

Bennet Huber
fonte
6
Uma boa maneira de implementar um Singleton. Infelizmente, a questão não é sobre Singletons, é sobre classes estáticas
David SN
1
Java tem uma interpretação bastante exclusiva da palavra-chave "estática". Parece que o OP está vindo do C #, onde "classe estática" é o equivalente a um singleton em Java. Atualizei minha resposta para deixar clara essa interpretação da pergunta.
Bennet Huber
1
A classe estática AC # não é um Singleton. Uma instância Singleton é um objeto e pode implementar uma interface, o que significa que ela pode participar da injeção de dependência e pode ser ridicularizada. A classe estática AC # não pode implementar uma interface ou ser injetada de forma alguma, e está muito mais próxima de várias funções C e, é claro, permite métodos de extensão.
Novaterata
13

Uma classe pode ser estática em Java?

A resposta é SIM , podemos ter uma classe estática em java. Em java, temos variáveis estáticas exemplo , bem como métodos estáticos e também bloco estático . As classes também podem se tornar estáticas em Java.

Em java, não podemos tornar estática a classe de nível superior (externa). Somente classes aninhadas podem ser estáticas.

classe aninhada estática vs classe aninhada não estática

1) A classe estática aninhada não precisa de uma referência da classe externa, mas a classe aninhada não estática ou a classe interna requer referência da classe externa.

2) A classe interna (ou classe aninhada não estática) pode acessar membros estáticos e não estáticos da classe externa. Uma classe estática não pode acessar membros não estáticos da classe Exterior. Ele pode acessar apenas membros estáticos da classe Outer.

veja aqui: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

roottraveller
fonte
também aulas interior 'não estáticos' não pode declarar campos ou métodos estáticos
Mr.cat
8

Classes externas não podem ser estáticas, mas classes aninhadas / internas podem ser. Isso basicamente ajuda você a usar a classe aninhada / interna sem criar uma instância da classe externa.

Saket
fonte
2

Em termos simples, Java suporta a declaração de uma classe para ser estática apenas para as classes internas, mas não para as classes de nível superior.

classes de nível superior: um projeto java pode conter mais de uma classe de nível superior em cada arquivo de origem java, sendo uma das classes nomeadas após o nome do arquivo. Há apenas três opções ou palavras-chave permitidas na frente das classes de nível superior, pública, abstrata e final .

Classes internas: as classes que estão dentro de uma classe de nível superior são chamadas de classes internas, que é basicamente o conceito de classes aninhadas. Classes internas podem ser estáticas . A idéia de tornar as classes internas estáticas é aproveitar a vantagem de instanciar os objetos das classes internas sem instanciar o objeto da classe de nível superior. É exatamente da mesma maneira que os métodos e variáveis ​​estáticos trabalham dentro de uma classe de nível superior.

Portanto, o Java suporta classes estáticas no nível da classe interna (em classes aninhadas)

E o Java não suporta classes estáticas nas classes de nível superior.

Espero que isso dê uma solução mais simples para a questão do entendimento básico das classes estáticas em Java.

saichand
fonte
0

Java possui métodos estáticos associados a classes (por exemplo, java.lang.Math possui apenas métodos estáticos), mas a própria classe não é estática.

duffymo
fonte
0

Você não pode usar a palavra-chave estática com uma classe, a menos que seja uma classe interna. Uma classe interna estática é uma classe aninhada que é um membro estático da classe externa. Ele pode ser acessado sem instanciar a classe externa, usando outros membros estáticos. Assim como os membros estáticos, uma classe aninhada estática não tem acesso às variáveis ​​e métodos da instância da classe externa.

public class Outer {
   static class Nested_Demo {
      public void my_method() {
          System.out.println("This is my nested class");
      }
   }
public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();
      nested.my_method();
   }
}
Nahid Nisho
fonte
Você não pode usar a staticpalavra-chave com uma classe, a menos que seja uma classe aninhada . 'Interior estático' é uma contradição em termos .
Marquês de Lorne #
0

Um método estático significa que ele pode ser acessado sem criar um objeto da classe, ao contrário do público:

public class MyClass {
   // Static method
   static void myStaticMethod() {
      System.out.println("Static methods can be called without creating objects");
   }

  // Public method
  public void myPublicMethod() {
      System.out.println("Public methods must be called by creating objects");
   }

  // Main method
  public static void main(String[ ] args) {
      myStaticMethod(); // Call the static method
    // myPublicMethod(); This would output an error

    MyClass myObj = new MyClass(); // Create an object of MyClass
    myObj.myPublicMethod(); // Call the public method
  }
}
dJack
fonte
Não responde a pergunta.
Marquês de Lorne,
-1

Todas as boas respostas, mas eu não vi uma referência ao java.util.Collections que usa toneladas de classe interna estática para seus métodos de fator estático. Então adicionando o mesmo.

Adicionando um exemplo de java.util.Collections que possui várias classes internas estáticas. Classes internas são úteis para agrupar códigos que precisam ser acessados ​​via classe externa.

/**
 * @serial include
 */
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                             implements Set<E>, Serializable {
    private static final long serialVersionUID = -9215047833775013803L;

    UnmodifiableSet(Set<? extends E> s)     {super(s);}
    public boolean equals(Object o) {return o == this || c.equals(o);}
    public int hashCode()           {return c.hashCode();}
}

Aqui está o método do fator estático na classe java.util.Collections

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}
Jay Rajput
fonte
Não recebeu seu comentário? Você pode elaborar? Tentando entender seu comentário.
Jay Rajput