JavaRush /Blog Java /Random-ES /Diez notas sobre el modificador estático en Java

Diez notas sobre el modificador estático en Java

Publicado en el grupo Random-ES
El modificador estático en Java está directamente asociado con la clase. Si el campo es estático, entonces pertenece a la clase, si el método es estático, ocurre lo mismo: pertenece a la clase. En base a esto, puede acceder a un método o campo estático utilizando el nombre de la clase. Por ejemplo, si el campo de recuento es estático en la clase Contador, puede acceder a la variable con una consulta como: Contador.count. Diez notas sobre el modificador estático en Java - 1Antes de comenzar con las notas, recordemos (y tal vez descubramos) qué es estático y qué puede ser estático en Java. Estático es un modificador aplicado a un campo, bloque, método o clase interna. Este modificador indica que el sujeto está vinculado a la clase actual.

Campos estáticos

Cuando denotamos una variable a nivel de clase, indicamos que el valor pertenece a una clase. Si no hace esto, el valor de la variable se vinculará a un objeto creado con esta clase. ¿Qué significa? Diez notas sobre el modificador estático en Java - 2Y es que si la variable no es estática, entonces cada nuevo objeto de esta clase tendrá su propio valor de esta variable, al cambiarlo lo cambiamos exclusivamente en un objeto: por ejemplo, tenemos una clase Car con un no -variable estática:
public class Car {
  int km;
}
Luego en principal:
Car orangeCar = new Car();
orangeCar.km = 100;

Car blueCar = new Car();
blueCar.km = 85;

System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
La salida que obtenemos es:

Orange car - 100
Blue car - 85
Como puede ver, cada objeto tiene su propia variable, cuyo cambio ocurre sólo para este objeto. Bueno, si tenemos una variable estática, entonces este valor global es el mismo para todos: Ahora tenemos un Coche con una variable estática:
public class Car {
  static int km;
}
Luego, el mismo código en main aparecerá en la consola:

Orange car - 85
Blue car - 85
Después de todo, tenemos una variable para todos y cada vez la cambiamos. Por lo general, el acceso a las variables estáticas no se realiza mediante una referencia de objeto: orangeCar.km, sino mediante el nombre de la clase: Car.km.

bloque estático

Hay dos bloques de inicialización: regular y estático. El bloque está destinado a inicializar variables internas. Si el bloque es normal, entonces las variables internas del objeto se inicializan con él, pero si es estático, entonces se les asignan variables estáticas (es decir, variables de clase). Ejemplo de una clase con un bloque de inicialización estático:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

método estático

Los métodos estáticos se diferencian de los métodos regulares en que también están vinculados a una clase en lugar de a un objeto. Una propiedad importante de un método estático es que solo puede acceder a variables/métodos estáticos. Como ejemplo, veamos una clase que será una especie de contador que realiza un seguimiento de las llamadas a métodos:
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Valor actual del contador -" + count);
  }
}
Llamémoslo en principal:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
Y obtenemos la salida a la consola:

Текущее significado счётчика - 1
Текущее significado счётчика - 2
Текущее significado счётчика - 3

Clase estática en Java

Sólo una clase interna puede ser una clase estática. Nuevamente, esta clase está vinculada a la clase externa, y si otra clase hereda la externa, esta no será heredada. Además, esta clase se puede heredar, al igual que se puede heredar de cualquier otra clase e implementar una interfaz. Esencialmente, una clase anidada estática no es diferente de cualquier otra clase interna, excepto que su objeto no contiene una referencia al objeto de clase externa que la creó. Sin embargo, esto hace que una clase estática sea más similar a una normal no anidada, porque la única diferencia es que está envuelta en otra clase. En algunos casos, esto es una ventaja para nosotros, ya que desde él tenemos acceso a las variables estáticas privadas de la clase externa. Ejemplo de una clase estática anidada:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
Creando una instancia de esta clase y estableciendo el valor de la variable interna:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
Para usar métodos/variables/clase estática, no necesitamos crear un objeto de esa clase. Por supuesto, se deben tener en cuenta los modificadores de acceso. Por ejemplo, privatesolo se puede acceder a los campos dentro de la clase en la que están declarados. Los campos protectedestán disponibles para todas las clases dentro de un paquete ( paquete ), así como para todas las clases descendientes fuera del paquete. Para obtener más detalles, consulte el artículo " privado frente a protegido frente a público ". Supongamos que hay un método estático increment()en la clase Countercuya tarea es incrementar el contador count. Para llamar a este método, puede utilizar una invocación del formulario Counter.increment(). No es necesario crear una instancia de una clase Counterpara acceder a un campo o método estático. Ésta es la diferencia fundamental entre objetos estáticos y NO estáticos (miembros de clase). Permítanme recordarles una vez más que los miembros de una clase estática pertenecen directamente a la clase, no a su instancia. Es decir, el valor de una variable estática countserá el mismo para todos los objetos de tipo Counter. Más adelante en este artículo, veremos los aspectos fundamentales del uso del modificador estático en Java, así como algunas características que lo ayudarán a comprender conceptos clave de programación.

Lo que todo programador debe saber sobre el modificador Estático en Java

En esta sección, veremos los conceptos básicos del uso de métodos, campos y clases estáticos. Empecemos por las variables.
  1. NO puede acceder a miembros no estáticos de una clase dentro de un contexto estático, como un método o bloque. Al compilar el código siguiente se producirá un error:

    public class Counter{
    private int count;
    public static void main(String args[]){
       System.out.println(count); //compile time error
    }}

    Este es uno de los errores más comunes que cometen los programadores de Java, especialmente los novatos. Dado que el método maines estático, pero la variable countno lo es, en este caso el método printlndentro del método mainarrojará un "Error de tiempo de compilación".

  2. A diferencia de las variables locales, los campos y métodos estáticos NO son seguros para subprocesos en Java. En la práctica, esta es una de las causas más comunes de problemas relacionados con la seguridad de la programación multiproceso. Teniendo en cuenta que cada instancia de una clase tiene la misma copia de una variable estática, dicha variable debe estar protegida, “bloqueada” por la clase. Por lo tanto, cuando utilice variables estáticas, asegúrese de que estén sincronizadas correctamente para evitar problemas como las condiciones de carrera.

  3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый un objeto для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы Cómo нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утoт (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утoты в Java финализированы (final).

  4. Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) en lugar de переопределения. Это явление известно Cómo сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен Cómo в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

    class Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Dentro de la clase principal/método estático");
         } }
    
    class Car extends Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Dentro de clase secundaria/método estático");
         } }
    
    public class Demo{
       public static void main(String args[]){
          Vehicle v = new Car();
           v.kmToMiles(10);
      }}

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что un objeto имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

  5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны Cómo «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также Cómo и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявo пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

  6. Модификатор static также может быть объявлен в статичном блоке, более известным Cómo «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

  7. Es útil saber que los métodos estáticos están vinculados en tiempo de compilación, a diferencia de los métodos virtuales o no estáticos vinculantes, que están vinculados en tiempo de ejecución al objeto real. Por lo tanto, los métodos estáticos no se pueden anular en Java porque El polimorfismo en tiempo de ejecución no se aplica a ellos. Esta es una limitación importante a considerar al declarar un método estático. Esto sólo tiene sentido cuando no existe la posibilidad o necesidad de anular dicho método heredando clases. Los métodos de fábrica y los métodos de utilidad son buenos ejemplos del uso del modificador estático. Joshua Bloch describió varias ventajas de utilizar un método de fábrica estático sobre un constructor en su libro Effective Java , que es de lectura obligatoria para todo programador del lenguaje.

  8. Una propiedad importante de un bloque estático es la inicialización. Los campos o variables estáticos se inicializan después de que la clase se carga en la memoria. El orden de inicialización es de arriba a abajo, en el mismo orden en que se describen en el archivo fuente de la clase Java. Dado que los campos estáticos se inicializan de forma segura para subprocesos, esta propiedad también se utiliza para implementar Singleton. Si no utiliza una lista Enumcomo Singleton, por una razón u otra, entonces existe una buena alternativa para usted. Pero en este caso hay que tener en cuenta que no se trata de una inicialización “perezosa”. Esto significa que el campo estático se inicializará ANTES de que alguien lo "pida". Si el objeto consume muchos recursos o se usa con poca frecuencia, inicializarlo en un bloque estático no funcionará a su favor.

  9. Durante la serialización, al igual que transientlas variables, los campos estáticos no se serializan. De hecho, si guarda datos en un campo estático, después de la deserialización el nuevo objeto contendrá su valor principal (predeterminado), por ejemplo, si el campo estático era una variable de tipo int, entonces su valor después de la deserialización será cero, si el tipo floates 0.0, si escribe Objectnull. Honestamente, esta es una de las preguntas más frecuentes sobre la serialización en las entrevistas sobre Java. ¡No almacene los datos más importantes sobre un objeto en un campo estático!

  10. Y por último, hablemos de static import. Este modificador tiene mucho en común con el operador estándar import, pero a diferencia de él, le permite importar uno o todos los miembros estáticos de una clase. Al importar métodos estáticos, se puede acceder a ellos como si estuvieran definidos en la misma clase, de manera similar al importar campos, podemos acceder a ellos sin especificar el nombre de la clase. Esta característica se introdujo en la versión 1.5 de Java y, cuando se usa correctamente, mejora la legibilidad del código. Esta construcción se encuentra con mayor frecuencia en las pruebas JUnit , porque Casi todos los desarrolladores de pruebas utilizan static importmétodos de afirmación, por ejemplo, assertEquals()y sus duplicados sobrecargados. Si nada está claro, bienvenido a recibir información adicional .

Eso es todo. Todo programador debe conocer todos los puntos anteriores sobre el modificador estático en Java . Este artículo cubrió información básica sobre variables estáticas, campos, métodos, bloques de inicialización e importaciones. Incluyendo algunas propiedades importantes, cuyo conocimiento es fundamental a la hora de escribir y comprender programas en Java. Espero que todos los desarrolladores perfeccionen sus habilidades en el uso de conceptos estáticos porque... Esto es muy importante para una programación seria".
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION