web-dev-qa-db-de.com

Was macht das Schlüsselwort 'static' in einer Klasse?

Um genau zu sein, habe ich diesen Code ausprobiert:

package hello;

public class Hello {

    Clock clock = new Clock();

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

Aber es gab den Fehler

In der statischen Methode main kann nicht auf das nicht statische Feld zugegriffen werden

Also habe ich die Deklaration von clock folgendermaßen geändert:

static Clock clock = new Clock();

Und es hat funktioniert. Was bedeutet es, dieses Schlüsselwort vor die Deklaration zu setzen? Was genau wird es tun und/oder einschränken, was mit diesem Objekt getan werden kann?

426
Click Upvote

static Mitglieder gehören der Klasse an Stelle einer bestimmten Instanz an.

Es bedeutet das es ist nur eine Instanz eines static -Felds vorhanden[1] selbst wenn Sie eine Million Instanzen der Klasse erstellen oder keine erstellen. Es wird von allen Instanzen geteilt.

Da static Methoden auch nicht zu einer bestimmten Instanz gehören, können sie nicht auf Instanzmitglieder verweisen. Im angegebenen Beispiel weiß main nicht, auf welche Instanz der Hello -Klasse (und daher auf welche Instanz der Clock -Klasse) sie verweisen soll. static Mitglieder können sich nur auf static Mitglieder beziehen. Instanzmitglieder können natürlich auf static Mitglieder zugreifen.

Randnotiz: Natürlich können static Mitglieder auf Instanzmitglieder zugreifen durch eine Objektreferenz.

Beispiel:

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]: Abhängig von den Laufzeitmerkmalen kann es eines pro ClassLoader oder AppDomain oder Thread sein, aber das ist nicht der Punkt.

606
Mehrdad Afshari

Dies bedeutet, dass es in Hello nur eine Instanz von "clock" gibt, nicht eine für jede einzelne Instanz der "Hello" -Klasse. Dies bedeutet, dass es eine gemeinsam genutzte "clock" -Referenz unter allen Instanzen von gibt die "Hallo" -Klasse.

Wenn Sie also irgendwo in Ihrem Code ein "neues Hallo" machen würden: A - Im ersten Szenario (vor der Änderung, ohne "statisch" zu verwenden) würde jedes Mal, wenn ein "neues Hallo" aufgerufen wird, eine neue Uhr erstellt. Aber B - im zweiten Szenario (nach der Änderung unter Verwendung von "static") würde jede "new Hello" -Instanz weiterhin die ursprüngliche und dieselbe "clock" -Referenz verwenden, die zuerst erstellt wurde.

Wenn Sie nicht irgendwo außerhalb von main "clock" benötigen, funktioniert dies genauso gut:

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

Das Schlüsselwort static bedeutet, dass sich etwas (ein Feld, eine Methode oder eine verschachtelte Klasse) auf type bezieht und nicht auf eine bestimmte instance von der Typ. Zum Beispiel ruft man Math.sin(...) ohne eine Instanz der Klasse Math auf, und in der Tat kann man kann nicht eine Instanz der Klasse Math erstellen.

Weitere Informationen finden Sie im relevantes Bit im Java-Tutorial von Oracle .


Nebenbemerkung

Java erlaubt Ihnen leider , auf statische Mitglieder zuzugreifen, als ob sie Instanzmitglieder wären, z.

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

Das macht es sieht aus als ob sleep eine Instanzmethode ist, aber es ist eigentlich eine statische Methode - es immer lässt den aktuellen Thread schlafen . Es ist besser, dies im aufrufenden Code zu verdeutlichen:

// Clearer
Thread.sleep(5000);
96
Jon Skeet

Das Schlüsselwort static in Java bedeutet, dass die Variable oder Funktion von allen Instanzen dieser Klasse gemeinsam genutzt wird, da sie zum Typ gehört, nicht zu den eigentlichen Objekten.

Wenn Sie also eine Variable haben: private static int i = 0; und Sie erhöhen sie (i++) in einer Instanz, wird die Änderung in allen Instanzen wiedergegeben. i ist jetzt in allen Fällen 1.

Statische Methoden können verwendet werden, ohne ein Objekt zu instanziieren.

40
geowa4

Grundsätzliche Verwendung von statischen Elementen ...

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
}

Auf diese Weise können Sie Werte für alle Klassenmitglieder freigeben, ohne die Klasseninstanz Hello an eine andere Klasse zu senden. Und mit static müssen Sie keine Klasseninstanz erstellen.

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

Sie können statische Werte oder Methoden nur nach Klassennamen aufrufen:

Hello.staticValue = "abc";
24
Vasil Valchev

Statisch in Java:

Static ist ein Non Access Modifier. Das statische Schlüsselwort gehört zur Klasse als Instanz der Klasse. kann verwendet werden, um eine Variable oder Methode an eine Klasse anzuhängen.

Statisches Schlüsselwort KANN verwendet werden mit:

Methode

Variable

In einer anderen Klasse verschachtelte Klasse

Initialisierungsblock

KANN NICHT verwendet werden mit:

Klasse (nicht verschachtelt)

Konstrukteur

Schnittstellen

Methode Local Inner Class (Differenz zur verschachtelten Klasse)

Methoden der inneren Klasse

Instanzvariablen

Lokale Variablen

Beispiel:

Stellen Sie sich das folgende Beispiel mit einer Instanzvariablen namens count vor, die im Konstruktor inkrementiert wird:

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();

    }
}

Ausgabe:

1 1 1

Da die Instanzvariable zum Zeitpunkt der Objekterstellung den Speicher erhält, verfügt jedes Objekt über die Kopie der Instanzvariablen. Wenn sie inkrementiert wird, wird sie nicht für andere Objekte übernommen.

Wenn wir nun die Anzahl der Instanzvariablen in eine statische ändern, erzeugt das Programm eine andere Ausgabe:

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();

    }
}

Ausgabe:

1 2 3

In diesem Fall erhält die statische Variable den Speicher nur einmal. Wenn ein Objekt den Wert der statischen Variablen ändert, behält es seinen Wert bei.

Statisch mit Final:

Die globale Variable, die als final und static deklariert ist, bleibt für die gesamte Ausführung unverändert. Denn statische Member werden im Klassenspeicher abgelegt und in der gesamten Ausführung nur einmal geladen. Sie sind allen Objekten der Klasse gemeinsam. Wenn Sie statische Variablen als endgültig deklarieren, können alle Objekte ihren Wert nicht ändern, da er endgültig ist. Daher werden Variablen, die als final und static deklariert sind, manchmal als Konstanten bezeichnet. Alle Felder von Schnittstellen werden als Konstanten bezeichnet, da sie standardmäßig endgültig und statisch sind.

enter image description here

Bildquelle: Final Static

20
Virtual

Statisch bedeutet, dass Sie keine Instanz der Klasse erstellen müssen, um die der Klasse zugeordneten Methoden oder Variablen zu verwenden. In Ihrem Beispiel könnten Sie anrufen:

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

direkt anstelle von:

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

Innerhalb einer statischen Methode (die zu einer Klasse gehört) können Sie auf keine nicht statischen Member zugreifen, da deren Werte von Ihrer Instanziierung der Klasse abhängen. Ein nicht statisches Clock-Objekt, bei dem es sich um ein Instanzmitglied handelt, verfügt für jede Instanz Ihrer Hello-Klasse über einen anderen Wert/eine andere Referenz. Daher können Sie nicht über den statischen Teil der Klasse darauf zugreifen.

19
Elie

In dieser Diskussion wurden bisher Überlegungen zu Klassenladeprogrammen ignoriert. Genau genommen werden Java statische Felder von allen Instanzen einer Klasse für ein gegebenes Klassenladeprogramm geteilt.

13
Julien Chastang

Lassen Sie mich mit einem Bild versuchen, um vorhandene Antworten zu ergänzen:

Auf ALLE Sparkonten wird ein Zinssatz von 2% angewendet. Daher ist es statisch .

Ein Saldo sollte individuell sein, also ist er nicht statisch.

enter image description here

13
Andrejs

Ein Feld kann entweder der Klasse oder einer Instanz einer Klasse zugewiesen werden. Standardmäßig sind Felder Instanzvariablen. Durch die Verwendung von static wird das Feld zu einer Klassenvariablen, daher gibt es nur eine clock. Wenn Sie Änderungen an einer Stelle vornehmen, ist dies überall sichtbar. Instanzvariablen werden unabhängig voneinander geändert.

7
sblundy

In Java kann das Schlüsselwort static einfach als Hinweis auf Folgendes angesehen werden:

"ohne Rücksicht oder Beziehung zu einer bestimmten Instanz"

Wenn Sie auf diese Weise an static denken, wird es einfacher, seine Verwendung in den verschiedenen Kontexten zu verstehen, in denen es auftritt:

  • Ein static -Feld ist ein Feld, das eher zur Klasse als zu einer bestimmten Instanz gehört

  • Eine static -Methode ist eine Methode, die keine Vorstellung von this hat. Es ist in der Klasse definiert und kennt keine bestimmte Instanz dieser Klasse, es sei denn, eine Referenz wird an sie übergeben

  • Eine static -Mitgliederklasse ist eine verschachtelte Klasse, ohne dass eine Instanz ihrer einschließenden Klasse bekannt ist (es sei denn, ihr wird ein Verweis auf eine einschließende Klasseninstanz übergeben).

6
scottb

Das Schlüsselwort static bezeichnet ein Feld oder eine Methode als zur Klasse selbst und nicht zur Instanz gehörend. Wenn das Objekt Clock statisch ist, verwenden alle Instanzen der Klasse Hello unter Verwendung Ihres Codes dieses Clock -Datenelement (Feld) gemeinsam. Wenn Sie es nicht statisch machen, kann jede einzelne Instanz von Hello ein eindeutiges Clock -Feld haben.

Das Problem ist, dass Sie Ihrer Klasse Hello eine main - Methode hinzugefügt haben, damit Sie den Code ausführen können. Das Problem hierbei ist, dass die main -Methode statisch ist und daher nicht auf nicht statische Felder oder Methoden darin verweisen kann. Sie können dies auf zwei Arten lösen:

  1. Machen Sie alle Felder und Methoden der Klasse Hello statisch, damit in der Methode main auf sie verwiesen werden kann. Dies ist wirklich keine gute Sache (oder der falsche Grund, um ein Feld und/oder eine Methode statisch zu machen)
  2. Erstellen Sie eine Instanz Ihrer Klasse Hello in der Hauptmethode und greifen Sie auf alle Felder und Methoden so zu, wie sie ursprünglich vorgesehen waren.

Für Sie bedeutet dies die folgende Änderung Ihres Codes:

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();
    }
}
6
hfontanez

Ich habe eine Vorliebe für statische Methoden (nur wenn möglich) in "Helfer" -Klassen entwickelt.

Die aufrufende Klasse muss keine weitere Mitgliedsvariable (Instanzvariable) der Hilfsklasse erstellen. Sie rufen einfach die Methoden der Hilfsklasse auf. Außerdem wurde die Hilfsklasse verbessert, da Sie keinen Konstruktor und keine Mitgliedsvariablen (Instanzvariablen) mehr benötigen.

Es gibt wahrscheinlich andere Vorteile.

5
javaguy

Statisch macht das Uhr-Member zu einem Klassen-Member anstelle eines Instanz-Members. Ohne das statische Schlüsselwort müssten Sie eine Instanz der Hello-Klasse erstellen (die eine Clock-Member-Variable enthält) - z.

Hello hello = new Hello();
hello.clock.sayTime();
5
Stephen Doyle

statische Methoden verwenden keine Instanzvariablen der Klasse, in der sie definiert sind. Eine sehr gute Erklärung des Unterschieds finden Sie auf diese Seite

5
Marc Novakowski

Ich kann mir auch vorstellen, dass statische Member keinen "this" -Zeiger haben. Sie werden von allen Instanzen gemeinsam genutzt.

3
kal
//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
    }
}
3
Mohammad Parvez

Statische Konzepte verstehen

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 */

    }
}

Zweite Klasse

public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
3
Uddhav Gautam

main() ist eine statische Methode mit zwei grundlegenden Einschränkungen:

  1. Die statische Methode kann kein nicht statisches Datenelement verwenden oder die nicht statische Methode nicht direkt aufrufen.
  2. this() und super() können nicht im statischen Kontext verwendet werden.

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

Ausgabe: Compile Time Error

2
Bharthan

Auf statische Variablen kann nur in statischen Methoden zugegriffen werden. Wenn wir also die statischen Variablen deklarieren, sind diese Getter- und Setter-Methoden statische Methoden

statische Methoden sind eine Klassenebene, auf die wir über den Klassennamen zugreifen können

Das Folgende ist ein Beispiel für statische Variablen Getters und Setters:

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

}
1
Bala Krishna

Wenn Sie ein Projekt ausführen, laden Sie zuerst statische Dinge (Variablen, Methoden, Blöcke ..).

Wenn Sie dieses Projekt ausführen, laden Sie zuerst die Hauptmethode. Weil es static method ist. Dann sieht es Objekt "a" object .Aber Objekt ist noch nicht definiert. Weil es nicht statisch ist. Dann komm wie dieser Fehler.

0
Dev4World