En términos sencillos, ¿qué significa "estático" en Java? [duplicar]
Me dijeron varias definiciones, busqué en Wikipedia, pero como principiante en Java todavía no estoy seguro de lo que significa. ¿Alguien habla Java con fluidez?
Estático significa que la variable o método marcado como tal está disponible a nivel de clase. En otras palabras, no es necesario crear una instancia de la clase para acceder a ella.
public class Foo {
public static void doStuff(){
// does stuff
}
}
Entonces, en lugar de crear una instancia de Foo y luego llamar doStuff
así:
Foo f = new Foo();
f.doStuff();
Simplemente llamas al método directamente contra la clase, así:
Foo.doStuff();
En términos muy simples la clase es un molde y el objeto es la copia hecha con ese molde. Los estáticos pertenecen al molde y se puede acceder a ellos directamente sin hacer copias, de ahí el ejemplo anterior.
La palabra clave estática se puede utilizar de varias maneras diferentes en Java y en casi todos los casos es un modificador, lo que significa que lo que se está modificando se puede utilizar sin una instancia de objeto adjunta .
Java es un lenguaje orientado a objetos y, de forma predeterminada, la mayoría del código que escribe requiere una instancia del objeto que se utilizará.
public class SomeObject {
public int someField;
public void someMethod() { };
public Class SomeInnerClass { };
}
Para utilizar someField, someMethod o SomeInnerClass, primero tengo que crear una instancia de SomeObject .
public class SomeOtherObject {
public void doSomeStuff() {
SomeObject anInstance = new SomeObject();
anInstance.someField = 7;
anInstance.someMethod();
//Non-static inner classes are usually not created outside of the
//class instance so you don't normally see this syntax
SomeInnerClass blah = anInstance.new SomeInnerClass();
}
}
Si declaro esas cosas estáticas entonces no requieren una instancia adjunta .
public class SomeObjectWithStaticStuff {
public static int someField;
public static void someMethod() { };
public static Class SomeInnerClass { };
}
public class SomeOtherObject {
public void doSomeStuff() {
SomeObjectWithStaticStuff.someField = 7;
SomeObjectWithStaticStuff.someMethod();
SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass();
//Or you can also do this if your imports are correct
SomeInnerClass blah2 = new SomeInnerClass();
}
}
Declarar algo estático tiene varias implicaciones.
En primer lugar, solo puede haber un valor de un campo estático en toda la aplicación .
public class SomeOtherObject {
public void doSomeStuff() {
//Two objects, two different values
SomeObject instanceOne = new SomeObject();
SomeObject instanceTwo = new SomeObject();
instanceOne.someField = 7;
instanceTwo.someField = 10;
//Static object, only ever one value
SomeObjectWithStaticStuff.someField = 7;
SomeObjectWithStaticStuff.someField = 10; //Redefines the above set
}
}
El segundo problema es que los métodos estáticos y las clases internas no pueden acceder a los campos del objeto adjunto (ya que no hay ninguno).
public class SomeObjectWithStaticStuff {
private int nonStaticField;
private void nonStaticMethod() { };
public static void someStaticMethod() {
nonStaticField = 7; //Not allowed
this.nonStaticField = 7; //Not allowed, can never use *this* in static
nonStaticMethod(); //Not allowed
super.someSuperMethod(); //Not allowed, can never use *super* in static
}
public static class SomeStaticInnerClass {
public void doStuff() {
someStaticField = 7; //Not allowed
nonStaticMethod(); //Not allowed
someStaticMethod(); //This is ok
}
}
}
La palabra clave estática también se puede aplicar a interfaces internas, anotaciones y enumeraciones.
public class SomeObject {
public static interface SomeInterface { };
public static @interface SomeAnnotation { };
public static enum SomeEnum { };
}
En todos estos casos la palabra clave es redundante y no tiene ningún efecto. Las interfaces, anotaciones y enumeraciones son estáticas de forma predeterminada porque nunca tienen una relación con una clase interna.
Esto simplemente describe lo que hace la palabra clave. No describe si el uso de la palabra clave es una mala idea o no. Esto se puede tratar con más detalle en otras preguntas como ¿ Es malo usar muchos métodos estáticos?
También existen algunos usos menos comunes de la palabra clave static. Hay importaciones estáticas que le permiten utilizar tipos estáticos (incluidas interfaces, anotaciones y enumeraciones no marcadas de forma redundante como estáticas) no calificadas.
//SomeStaticThing.java
public class SomeStaticThing {
public static int StaticCounterOne = 0;
}
//SomeOtherStaticThing.java
public class SomeOtherStaticThing {
public static int StaticCounterTwo = 0;
}
//SomeOtherClass.java
import static some.package.SomeStaticThing.*;
import some.package.SomeOtherStaticThing.*;
public class SomeOtherClass {
public void doStuff() {
StaticCounterOne++; //Ok
StaticCounterTwo++; //Not ok
SomeOtherStaticThing.StaticCounterTwo++; //Ok
}
}
Por último, existen inicializadores estáticos que son bloques de código que se ejecutan cuando la clase se carga por primera vez (que generalmente ocurre justo antes de que se cree una instancia de una clase por primera vez en una aplicación) y (al igual que los métodos estáticos) no pueden acceder a campos no estáticos. o métodos.
public class SomeObject {
private static int x;
static {
x = 7;
}
}
Otro gran ejemplo de cuándo se utilizan operaciones y atributos estáticos cuando se desea aplicar el patrón de diseño Singleton . En pocas palabras, el patrón de diseño Singleton garantiza que se construya uno y sólo un objeto de una clase particular durante la vida útil de su sistema. Para garantizar que solo se construya un objeto, las implementaciones típicas del patrón Singleton mantienen una referencia estática interna a la única instancia de objeto permitida, y el acceso a esa instancia se controla mediante una static
operación.