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?
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.
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();
}
}
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);
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.
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";
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.
Bildquelle: Final Static
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.
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.
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.
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).
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:
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)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();
}
}
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.
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();
statische Methoden verwenden keine Instanzvariablen der Klasse, in der sie definiert sind. Eine sehr gute Erklärung des Unterschieds finden Sie auf diese Seite
Ich kann mir auch vorstellen, dass statische Member keinen "this" -Zeiger haben. Sie werden von allen Instanzen gemeinsam genutzt.
//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
}
}
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");
}
}
main()
ist eine statische Methode mit zwei grundlegenden Einschränkungen:
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
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;
}
}
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.