Clases Estáticas En Java

947

¿Hay algo como static classen Java?

¿Cuál es el significado de tal clase? ¿Todos los métodos de la clase estática también deben serlo static?

¿Se requiere al revés, que si una clase contiene todos los métodos estáticos, la clase también será estática?

¿Para qué sirven las clases estáticas?

Kraken
fuente
Las clases estáticas se utilizan básicamente para agrupar clases.
RockingDev

Respuestas:

847

Java tiene clases anidadas estáticas , pero parece que está buscando una clase estática de nivel superior. Java no tiene forma de hacer que una clase de nivel superior sea estática, pero puede simular una clase estática como esta:

  • Declare su clase final: evita la extensión de la clase ya que extender una clase estática no tiene sentido
  • Cree el constructor private: evita la creación de instancias por código de cliente, ya que no tiene sentido crear una instancia de una clase estática
  • Cree todos los miembros y funciones de la clase static: dado que la clase no se puede instanciar, no se pueden llamar métodos de instancia ni acceder a los campos de instancia
  • Tenga en cuenta que el compilador no le impedirá declarar un miembro de instancia (no estático). El problema solo aparecerá si intentas llamar al miembro de la instancia

Ejemplo simple por sugerencias de arriba:

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 qué sirven las clases estáticas? Un buen uso de una clase estática es definir clases únicas, de utilidad y / o biblioteca donde la instanciación no tendría sentido. Un gran ejemplo es la clase Math que contiene algunas constantes matemáticas como PI y E y simplemente proporciona cálculos matemáticos. Requerir instanciación en tal caso sería innecesario y confuso. Ver la Mathclase y el código fuente . Tenga en cuenta que es finaly todos sus miembros son static. Si Java permitiera declarar las clases de nivel superior, staticla clase de matemáticas sería estática.

Paul Sasik
fuente
35
una clase Foocon solo staticmétodos no es lo mismo questatic class Foo
craigb
12
@Evorlor: si una clase se declara final, sus métodos son automáticamente (efectivamente) finales. Esto se debe a que una clase final no puede subclasificarse y, por lo tanto, sus métodos no pueden anularse (es decir, son efectivamente finales). docs.oracle.com/javase/tutorial/java/IandI/final.html
jwayne
30
Esta respuesta tal vez aborde lo que significaba el OP, pero (actualmente) no explica las clases estáticas de Java, por lo que no responde a la pregunta en absoluto. Esto es muy malo para las personas que llegan aquí tratando de descubrir qué significa una clase estática en Java.
Tom
12
@JBoy: Existe una "clase estática" en Java, que es de lo que se trata la pregunta, pero esta respuesta no explica en absoluto. En cambio, explica cómo simular en Java lo que la respuesta llama una "clase estática", ¡pero no es lo que es una "clase estática" en Java! (Tal vez es lo que se llama una "clase estática" en algún otro idioma (s), pero las personas que vienen aquí para aprender sobre las clases estáticas de Java se confundirán y confundirán.)
Tom
44
debe mencionar explícitamente que private MyStaticClass () {// constructor privado myStaticMember = 1; } NO tendrá ningún efecto ya que no se llamará al constructor. Pero este no es el punto. Todavía estoy muy confundido acerca de la utilidad de las clases internas estáticas en Java y su utilidad o valor agregado.
moldovean
316

Bueno, Java tiene "clases anidadas estáticas", pero no son lo mismo que las clases estáticas de C #, si es de allí de donde vienes. Una clase anidada estática es solo una que no tiene implícitamente una referencia a una instancia de la clase externa.

Las clases anidadas estáticas pueden tener métodos de instancia y métodos estáticos.

No existe una clase estática de nivel superior en Java.

Jon Skeet
fuente
12
En Java ¿Por qué la clase anidada estática permite métodos de instancia? ¿Para qué sirve un método de instancia en una clase así?
Geek
19
@ Geek: ¿Leíste mi respuesta? Lee la segunda oración cuidadosamente. ¿Por qué no querrías poder tener métodos de instancia de clases estáticas? Puede crear instancias de ellos, después de todo.
Jon Skeet
17
@ Geek: Sí, es totalmente permisible. Su "comprensión" de que las clases estáticas son clases de utilidad es básicamente incorrecta. Eso no es lo que las clases estáticas en Java significan en absoluto.
Jon Skeet
14
@ Geek: Sí. Exactamente como escribí en mi respuesta: "Una clase anidada estática es solo una que no tiene implícitamente una referencia a una instancia de la clase externa".
Jon Skeet
66
@KhurramAli: ¿Te refieres implícitamente ? Ciertamente no son explícitamente estáticos, dado que no se usa la palabra clave statical declararlos. Son implícitamente estáticos en el sentido de que no necesita una referencia a nada más para construir uno. Personalmente, encuentro la terminología estática / no estática un poco extraña para las clases anidadas de todos modos ... Creo que sería más simple hablar sobre cuál es el comportamiento.
Jon Skeet
157

Hay una clase anidada estática , esta clase [anidada estática] no necesita una instancia de la clase adjunta para poder instanciarse.

Estas clases [las anidadas estáticas] solo pueden acceder a los miembros estáticos de la clase que encierra [ya que no tiene ninguna referencia a las instancias de la clase que encierra ...]

muestra 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
fuente
1
Entonces, ¿podemos decir que podemos usar clases estáticas internas para instanciarlas sin la necesidad de hacerlas públicas?
moldovean
@moldovean Utilizamos clases estáticas internas para crear instancias de un contexto estático (como main). No creo que tenga nada que ver con la visibilidad.
Michael Dorst
2
@moldovean static / non static es ortogonal a la visibilidad. Puede tener cualquier tipo de visibilidad con estática o no estática. El punto es, ¿necesita una instancia de la clase de cierre para crear la interna?
amit
103

Sí, hay una clase anidada estática en java. Cuando declara una clase anidada estática, se convierte automáticamente en una clase independiente que se puede instanciar sin tener que instanciar la clase externa a la que pertenece.

Ejemplo:

public class A
{

 public static class B
 {
 }
}

Como class Bse declara estático, puede crear instancias explícitamente como:

B b = new B();

Tenga en cuenta que si class Bno se declara estático para que sea independiente, una llamada de objeto de instancia se vería así:

A a= new A();
B b = a.new B();
Mapa de bits
fuente
77
tenga en cuenta que puede crear instancias de la clase no estática con regularidad, como B b = new B();si intentara crear una instancia de la Amisma clase .
Muhammed Refaat
33

¿Qué sucede cuando un miembro dentro de un classse declara como static...? Se puede acceder a los miembros sin crear instancias de class. Por lo tanto, hacer una clase externa (clase de nivel superior) staticno tiene sentido. Por lo tanto, no está permitido.

Pero puede establecer clases internas como estáticas (ya que es un miembro de la clase de nivel superior). Entonces se puede acceder a esa clase sin instanciar la clase de nivel superior. Considere el siguiente ejemplo.

public class A {
    public static class B {

    }
}

Ahora, dentro de una clase diferente C, Bse puede acceder a la clase sin hacer una instancia de clase A.

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

staticLas clases también pueden tener non-staticmiembros. Solo la clase se vuelve estática.

Pero si la staticpalabra clave se elimina de la clase B, no se puede acceder directamente sin hacer una instancia de A.

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

Pero no podemos tener staticmiembros dentro de una non-staticclase interna.

Ramesh-X
fuente
¿Podemos crear una instancia de una clase estática o tiene sentido?
Supun Wijerathne
66
No como en otros idiomas, staticsolo tiene un significado en java. Si algo está staticen una clase, eso significa que se puede acceder a esa cosa sin crear una instancia de esa clase. No dice nada sobre la creación de instancias o no ..
Ramesh-X
Lo siento stackoverflow! ¡No puedo evitar decir gracias Ramesh-X en este caso! Cubriste casi todo lo que me preguntaba sobre las clases internas estáticas y las clases internas.
moldovean
No se puede 'establecer clases internas como estáticas'. Esto es una contradicción en los términos . Una clase anidada es interna o estática.
Marqués de Lorne el
13

Al ver que este es el mejor resultado en Google para "Java de clase estática" y la mejor respuesta no está aquí, pensé que lo agregaría. Estoy interpretando la pregunta de OP con respecto a las clases estáticas en C #, que se conocen como singletons en el mundo de Java. Para aquellos que no lo saben, en C # la palabra clave "estática" se puede aplicar a una declaración de clase, lo que significa que la clase resultante nunca se puede instanciar.

Extracto de "Effective Java - Second Edition" de Joshua Bloch (ampliamente considerado como una de las mejores guías de estilo Java disponibles):

A partir de la versión 1.5, existe un tercer enfoque para implementar singletons. Simplemente haga un tipo de enumeración con un elemento:

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

Este enfoque es funcionalmente equivalente al enfoque de campo público, excepto que es más conciso, proporciona la maquinaria de serialización de forma gratuita y ofrece una garantía irrefrenable contra la creación de instancias múltiples, incluso frente a ataques de reflexión o serialización sofisticados. Si bien este enfoque aún no se ha adoptado ampliamente, un tipo de enumeración de un solo elemento es la mejor manera de implementar un singleton. (énfasis del autor)

Bloch, Joshua (2008-05-08). Java efectivo (Serie Java) (p. 18). Educación Pearson.

Creo que la implementación y la justificación se explican por sí mismas.

Bennet Huber
fuente
66
Una buena manera de implementar un Singleton. Desafortunadamente, la pregunta no se trata de Singletons, se trata de clases estáticas
David SN
1
Java tiene una interpretación bastante única de la palabra clave "estática". Parece que OP viene de C # donde "clase estática" es el equivalente de un singleton en Java. He actualizado mi respuesta para aclarar esta interpretación de la pregunta.
Bennet Huber
1
La clase estática AC # no es Singleton. Una instancia de Singleton es un objeto y puede implementar una interfaz, lo que significa que puede participar en la inyección de dependencia y puede ser burlado. La clase estática AC # no puede implementar una interfaz o ser inyectada de ninguna manera, y está mucho más cerca de un montón de funciones C, y por supuesto permite métodos de extensión.
Novaterata
13

¿Puede una clase ser estática en Java?

La respuesta es , podemos tener una clase estática en java. En java, tenemos variables de instancia estáticas , así como métodos estáticos y también bloques estáticos . Las clases también pueden hacerse estáticas en Java.

En java, no podemos hacer que la clase de nivel superior (exterior) sea estática. Solo las clases anidadas pueden ser estáticas.

clase anidada estática vs clase anidada no estática

1) La clase estática anidada no necesita una referencia de la clase externa, pero la clase anidada no estática o la clase interna requiere una referencia de clase externa.

2) La clase interna (o clase anidada no estática) puede acceder a los miembros estáticos y no estáticos de la clase externa. Una clase estática no puede acceder a miembros no estáticos de la clase Outer. Solo puede acceder a miembros estáticos de la clase Outer.

ver aquí: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

roottraveller
fuente
tampoco las clases internas 'no estáticas' pueden declarar campos o métodos estáticos
Mr.Cat
2

En términos simples, Java admite la declaración de que una clase sea estática solo para las clases internas, pero no para las clases de nivel superior.

Clases de nivel superior: un proyecto de Java puede contener más de una clase de nivel superior en cada archivo fuente de Java, una de las clases que lleva el nombre del archivo. Solo hay tres opciones o palabras clave permitidas frente a las clases de nivel superior, public, abstract y final .

Clases internas: las clases que están dentro de una clase de nivel superior se denominan clases internas, que es básicamente el concepto de clases anidadas. Las clases internas pueden ser estáticas . La idea de hacer que las clases internas sean estáticas es aprovechar la instancia de los objetos de las clases internas sin instanciar el objeto de la clase de nivel superior. Esto es exactamente lo mismo que los métodos estáticos y las variables funcionan dentro de una clase de nivel superior.

Por lo tanto, Java admite clases estáticas en el nivel de clase interna (en clases anidadas)

Y Java no admite clases estáticas en las clases de nivel superior.

Espero que esto brinde una solución más simple a la pregunta para la comprensión básica de las clases estáticas en Java.

saichand
fuente
0

Java tiene métodos estáticos asociados con las clases (por ejemplo, java.lang.Math solo tiene métodos estáticos), pero la clase en sí no es estática.

duffymo
fuente
0

No puede usar la palabra clave estática con una clase a menos que sea una clase interna. Una clase interna estática es una clase anidada que es un miembro estático de la clase externa. Se puede acceder sin crear instancias de la clase externa, utilizando otros miembros estáticos. Al igual que los miembros estáticos, una clase anidada estática no tiene acceso a las variables de instancia y los métodos de la clase 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
fuente
No puede usar la staticpalabra clave con una clase a menos que sea una clase anidada . 'Estático interno' es una contradicción en los términos .
Marqués de Lorne el
0

Un método estático significa que se puede acceder sin crear un objeto de la clase, a diferencia de public:

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
fuente
No responde la pregunta.
Marqués de Lorne el
-1

Todas buenas respuestas, pero no vi una referencia a java.util.Collections que usa toneladas de clase interna estática para sus métodos de factor estático. Entonces agregando lo mismo.

Agregar un ejemplo de java.util.Collections que tiene múltiples clases internas estáticas. Las clases internas son útiles para agrupar el código al que se debe acceder a través de la clase 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();}
}

Aquí está el método del factor estático en la clase java.util.Collections

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}
Jay Rajput
fuente
¿No recibiste tu comentario? ¿Puedes elaborar? Intentando entender tu comentario.
Jay Rajput