Pregunta

Para ser específico, estaba intentando este código:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

Pero dio el error

  

No se puede acceder al campo no estático en el método principal estático

Así que cambié la declaración de clock a esto:

static Clock clock = new Clock();

Y funcionó. ¿Qué significa poner esa palabra clave antes de la declaración? ¿Qué hará y / o restringirá exactamente en términos de lo que se puede hacer con ese objeto?

¿Fue útil?

Solución

Los miembros de

static pertenecen a la clase en lugar de a una instancia específica.

Significa que solo existe una instancia de un campo static [1] incluso si crea un millón de instancias de la clase o no cree ninguno. Será compartido por todas las instancias.

Como los métodos static tampoco pertenecen a una instancia específica, no pueden referirse a miembros de la instancia. En el ejemplo dado, main no sabe qué instancia de la clase Hello (y, por lo tanto, qué instancia de la clase Clock ) debe consultar . Los miembros de static solo pueden referirse a los miembros de static . Los miembros de la instancia pueden, por supuesto, acceder a los miembros de static .

Nota al margen: Por supuesto, los miembros de static pueden acceder a los miembros de la instancia a través de una referencia de objeto .

Ejemplo:

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]: Dependiendo de las características de tiempo de ejecución, puede ser uno por ClassLoader o AppDomain o hilo, pero eso no está al lado.

Otros consejos

Significa que solo hay una instancia de " reloj " en Hello, no una por cada instancia separada de " Hello " clase, o más, significa que habrá un " reloj " referencia entre todas las instancias del " Hola " clase.

Así que si hicieras un " nuevo Hello " En cualquier parte de tu código: A- en el primer escenario (antes del cambio, sin usar " estática "), haría un nuevo reloj cada vez que un " nuevo Hello " se llama, pero B: en el segundo escenario (después del cambio, usando " estática "), cada " nuevo Hello " la instancia aún compartiría y usaría el mismo " reloj " referencia creada por primera vez.

A menos que necesitaras " reloj " En algún lugar fuera de main, esto funcionaría igual de bien:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}

La palabra clave static significa que algo (un campo, método o clase anidada) está relacionado con el tipo en lugar de cualquier instancia de el tipo. Así, por ejemplo, uno llama a Math.sin (...) sin ninguna instancia de la clase Math y, de hecho, no puede crear una instancia de la clase Math .

Para obtener más información, consulte parte relevante del Tutorial de Java de Oracle .


Sidenote

Java desafortunadamente te permite acceder a miembros estáticos como si fueran miembros de instancia, por ejemplo

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

Eso hace que se vea como si sleep sea un método de instancia, pero en realidad es un método estático: siempre hace que el hilo actual esté inactivo . Es una mejor práctica dejar esto claro en el código de llamada:

// Clearer
Thread.sleep(5000);

La palabra clave static en Java significa que la variable o función se comparte entre todas las instancias de esa clase, ya que pertenece al tipo , no a los objetos reales en sí.

Entonces, si tiene una variable: private static int i = 0; y la incrementa ( i ++ ) en una instancia, el cambio se reflejará en todas las instancias . i ahora será 1 en todas las instancias.

Los métodos estáticos se pueden usar sin crear una instancia de un objeto.

Uso básico de miembros 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
}

Así es como puedes tener valores compartidos en todos los miembros de la clase sin enviar la instancia de la clase Hello a otra clase. Y con la estática no es necesario crear una instancia de clase.

Hello hello = new Hello();
hello.staticValue = "abc";

Puede llamar valores estáticos o métodos por nombre de clase:

Hello.staticValue = "abc";

Estático en Java:

Static es un modificador de no acceso. La palabra clave estática pertenece a la clase que a la instancia de la clase. se puede usar para adjuntar una variable o un método a una clase.

La palabra clave estática PUEDE utilizarse con:

Método

Variable

Clase anidada dentro de otra clase

Bloque de inicialización

NO se puede usar con:

Clase (no anidada)

Constructor

Interfaces

Método de clase interna local (diferencia luego clase anidada)

Métodos de clase interna

Variables de instancia

Variables locales

Ejemplo :

Imagine el siguiente ejemplo que tiene una variable de instancia llamada count que se incrementa en el constructor:

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

Dado que la variable de instancia obtiene la memoria en el momento de la creación del objeto, cada objeto tendrá la copia de la variable de instancia, si se incrementa, no se reflejará en otros objetos.

Ahora, si cambiamos el recuento de variables de instancia a uno estático , el programa producirá una salida 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

En este caso, la variable estática obtendrá la memoria solo una vez, si algún objeto cambia el valor de la variable estática, conservará su valor.

Estático con final:

La variable global que se declara como final y estática permanece sin cambios durante toda la ejecución. Porque, los miembros estáticos se almacenan en la memoria de clase y se cargan solo una vez en toda la ejecución. Son comunes a todos los objetos de la clase. Si declara las variables estáticas como finales, cualquiera de los objetos & # 8217; t puede cambiar su valor ya que es definitivo. Por lo tanto, las variables declaradas como finales y estáticas a veces se denominan constantes. Todos los campos de interfaces se denominan constantes, porque son finales y estáticos de forma predeterminada.

 introduce la descripción de la imagen aquí

Picture Resource: Final Static

Estático significa que no tiene que crear una instancia de la clase para usar los métodos o las variables asociadas con la clase. En tu ejemplo, podrías llamar:

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

directamente, en lugar de:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

Desde dentro de un método estático (que pertenece a una clase), no puede acceder a miembros que no sean estáticos, ya que sus valores dependen de su creación de instancias de la clase. Un objeto de reloj no estático, que es un miembro de instancia, tendría un valor / referencia diferente para cada instancia de su clase Hello y, por lo tanto, no podría acceder a él desde la parte estática de la clase.

Esta discusión hasta ahora ha ignorado las consideraciones del cargador de clases. En sentido estricto, los campos estáticos de Java se comparten entre todas las instancias de una clase para un cargador de clases .

Para agregar a las respuestas existentes, permítame probar con una imagen:

Se aplica una tasa de interés del 2% a TODAS las cuentas de ahorro. Por lo tanto, es estático .

Un saldo debe ser individual , por lo que no estático.

 introduce la descripción de la imagen aquí

Se puede asignar un campo a la clase o a una instancia de una clase. Por defecto los campos son variables de instancia. Al usar static , el campo se convierte en una variable de clase, por lo tanto, hay un solo reloj . Si realiza cambios en un lugar, es visible en todas partes. Los varables de instancia se cambian independientemente uno del otro.

La palabra clave static se usa para denotar que un campo o un método pertenecen a la clase en sí y no a la instancia. Usando su código, si el objeto Clock es estático, todas las instancias de la clase Hello compartirán este miembro de datos Clock (campo) en común. Si lo hace no estático, cada instancia individual de Hello puede tener un campo único Clock .

El problema es que agregó un método main a su clase Hello para que pueda ejecutar el código. El problema aquí es que el método main es estático y, como tal, no puede referirse a campos o métodos no estáticos dentro de él. Puedes resolver esto de dos maneras:

  1. Establezca todos los campos y métodos de la clase Hello para que se puedan consultar dentro del método main . Realmente no es una buena cosa que hacer (o la razón equivocada para hacer que un campo y / o un método sea estático)
  2. Cree una instancia de su clase Hello dentro del método principal y acceda a todos sus campos y métodos de la forma en que estaban destinados en primer lugar.

Para usted, esto significa el siguiente cambio en su 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();
    }
}

En Java, se puede considerar que la palabra clave static indica lo siguiente:

  

" sin tener en cuenta ni relación con ninguna instancia en particular "

Si piensa en static de esta manera, será más fácil comprender su uso en los diversos contextos en los que se encuentra:

  • Un campo static es un campo que pertenece a la clase en lugar de a cualquier instancia en particular

  • Un método static es un método que no tiene noción de this ; está definido en la clase y no conoce ninguna instancia en particular de esa clase a menos que se le pase una referencia

  • Una clase miembro static es una clase anidada sin ninguna noción o conocimiento de una instancia de su clase envolvente (a menos que se le pase una referencia a una instancia de clase envolvente)

Estático hace que el miembro del reloj sea un miembro de la clase en lugar de un miembro de la instancia. Sin la palabra clave estática, tendría que crear una instancia de la clase Hello (que tiene una variable de miembro de reloj), por ejemplo,

Hello hello = new Hello();
hello.clock.sayTime();

los métodos estáticos no utilizan ninguna variable de instancia de la clase en la que están definidos. Se puede encontrar una muy buena explicación de la diferencia en esta página

He desarrollado un gusto por los métodos estáticos (solo, si es posible) en " helper " clases.

La clase que llama no necesita crear otra variable miembro (instancia) de la clase auxiliar. Usted acaba de llamar a los métodos de la clase de ayuda. Además, la clase auxiliar se ha mejorado porque ya no necesita un constructor y no necesita variables miembro (instancia).

Probablemente hay otras ventajas.

También puedo pensar en miembros estáticos que no tienen un " este " puntero. Se comparten entre todas las instancias.

Comprender los conceptos 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 */

    }
}

Segunda Clase

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 () es un método estático que tiene dos restricciones fundamentales:

  1. El método estático no puede usar un miembro de datos no estáticos ni llamar directamente a un método no estático.
  2. this () y super () no se pueden usar en un contexto estático.

    class A {  
        int a = 40; //non static
        public static void main(String args[]) {  
            System.out.println(a);  
        }  
    }
    
  

Salida: Error de compilación

Las variables estáticas solo se pueden acceder mediante métodos estáticos, por lo tanto, cuando declaremos las variables estáticas, dichos métodos de obtención y configuración serán métodos estáticos

métodos estáticos es un nivel de clase al que podemos acceder utilizando el nombre de clase

El siguiente es un ejemplo para Getters And Setters de variables estáticas:

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;
    }

}
  

Cuando ejecute algún proyecto, primero cargue cosas estáticas (variables, métodos, bloques ...).

Cuando ejecutes este proyecto, carga el método principal. Debido a su método estático . Luego se ve el objeto " a " objeto .Pero el objeto no está definido todavía. Porque no es estático. Entonces ven como este error.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top