Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Funktionen des geschützten Modifikators und des statischen Modifikators in der Java-Programmierung

Detaillierte Erläuterung der Funktionen des geschützten Modifikators und des statischen Modifikators in der Java-Programmierung

高洛峰
高洛峰Original
2017-01-24 15:32:121684Durchsuche

geschützt
Sprechen wir über geschützte Zugriffsrechte. Schauen Sie sich Beispiel 1 unten an:
Test.java

class MyObject {}
  
public class Test {
  public static void main(String[] args) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile error.
  }
}

Der oben erwähnte Fehler erscheint: Der Methodenklon vom Typ Object ist nicht sichtbar.
Wir wissen es bereits dass Object.clone() eine geschützte Methode ist. Dies zeigt, dass auf diese Methode von demselben Paket (java.lang) und seinen Unterklassen (java.lang.Object) zugegriffen werden kann. Hier ist die MyObject-Klasse (die standardmäßig von java.lang.Object erbt).
In ähnlicher Weise ist Test auch eine Unterklasse von java.lang.Object. Auf geschützte Methoden einer Unterklasse kann jedoch nicht von einer anderen Unterklasse aus zugegriffen werden, auch wenn die beiden Unterklassen von derselben übergeordneten Klasse erben.
Sehen Sie sich Beispiel 2 noch einmal an:
Test2.java

class MyObject2 {
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
  
public class Test2 {
  public static void main(String[] args) throws CloneNotSupportedException {
    MyObject2 obj = new MyObject2();
    obj.clone(); // Compile OK.
  }
}

Hier überschreiben wir die clone()-Methode der übergeordneten Klasse in der MyObject2-Klasse und in Ein weiterer Die clone()-Methode wird in einer Klasse Test2 aufgerufen und der Compiler besteht.
Der Grund, warum die Kompilierung erfolgreich ist, ist offensichtlich. Wenn Sie die clone()-Methode in der MyObject2-Klasse überschreiben, befinden sich die MyObject2-Klasse und die Test2-Klasse im selben Paket, sodass diese geschützte Methode für die Test2-Klasse sichtbar ist.
An diesem Punkt der Analyse erinnern wir uns an die Aussage in Kapitel 2.2 des Artikels über flache Kopien und tiefe Kopien in Java. ② Überschreiben Sie die clone()-Methode der Basisklasse in der abgeleiteten Klasse und deklarieren Sie sie als öffentlich. Jetzt verstehen Sie den Grund für diesen Satz (damit andere Klassen die clone()-Methode dieser Klasse aufrufen können, müssen die Eigenschaften der clone()-Methode nach dem Überladen auf public gesetzt werden).
Sehen wir uns Beispiel 3 an:
Test3.java

package 1
class MyObject3 {
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
  
package 2
public class Test3 extends MyObject3 {
  public static void main(String args[]) {
    MyObject3 obj = new MyObject3();
    obj.clone(); // Compile error.
    Test3 tobj = new Test3();
    tobj.clone();// Complie OK.
  }
}

Hier verwende ich die Test3-Klasse, um MyObject3 zu erben Klassen sind unterschiedliche Pakete, ansonsten ist es die Situation in Beispiel 2. In der Test3-Klasse wird die clone()-Methode der Instanz tobj der Test3-Klasse aufgerufen und die Kompilierung durchgeführt. Wenn auch die Methode clone() der Instanz obj der Klasse MyObject3 aufgerufen wird, tritt ein Kompilierungsfehler auf!
Unerwartetes Ergebnis: Können geerbte Klassen nicht auf geschützte Methoden zugreifen?
Es muss klar sein, dass die Klasse Test3 die Klasse MyObject3 (einschließlich ihrer Klonmethode) erbt, sodass Sie Ihre eigene Klonmethode in der Klasse Test3 aufrufen können. Aber die geschützte Methode der Klasse MyObject3 ist für ihre andere Unterklasse Test3 unsichtbar.

Methodenzugriffskontrolle:

Detaillierte Erläuterung der Funktionen des geschützten Modifikators und des statischen Modifikators in der Java-Programmierung

statisch
1. Schlüsselwort statisch (merken Sie sich diese zuerst und lesen Sie dann weiter)
1) Statische Methoden und statische Variablen gehören zu einer bestimmten Klasse, nicht zu Objekten der Klasse.
2) Verweise auf statische Methoden und statische Variablen werden direkt über den Klassennamen referenziert.
3) Nicht statische Methoden und nicht statische Mitgliedsvariablen können in statischen Methoden nicht aufgerufen werden. Im Gegenteil, es ist in Ordnung.
4) Statische Variablen ähneln globalen Variablen in anderen Sprachen in einem bestimmten Programm. Wenn sie nicht privat sind, kann außerhalb der Klasse auf sie zugegriffen werden.
2. Wann man static verwendet
Wenn wir eine Instanz (ein Objekt) einer Klasse erstellen, verwenden wir normalerweise die neue Methode, damit der Datenraum dieser Klasse erstellt und ihre Methoden aufgerufen werden können.
Manchmal hoffen wir jedoch, dass, obwohl eine Klasse n Objekte erstellen kann (offensichtlich sind die Datenräume dieser n Objekte unterschiedlich), einige Daten dieser n Objekte gleich sind, dh unabhängig von der Anzahl der Instanzen der Klasse Dort gibt es eine Speicherkopie dieser Daten (siehe Beispiel 1). Dies ist bei statischen Variablen der Fall.
Eine andere Situation ist, wenn Sie möchten, dass eine Methode keinem Objekt der Klasse zugeordnet wird, die sie enthält. Mit anderen Worten: Diese Methode kann auch dann aufgerufen werden, wenn das Objekt nicht erstellt wurde. Ein wichtiger Nutzen statischer Methoden besteht darin, dass sie aufgerufen werden können, ohne Objekte zu erstellen (siehe Beispiel 2). Dies ist bei statischen Methoden der Fall.
Es gibt auch eine spezielle Verwendung, die in inneren Klassen vorkommt. Normalerweise darf eine gewöhnliche Klasse nicht als statisch deklariert werden, sondern nur eine innere Klasse. Zu diesem Zeitpunkt kann die als statisch deklarierte innere Klasse direkt als normale Klasse verwendet werden, ohne eine äußere Klasse zu instanziieren (siehe Beispiel 3). Dies ist bei statischen Klassen der Fall.
Beispiel 1

public class TStatic {
  static int i;
  
  public TStatic() {
    i = 4;
  }
  
  public TStatic(int j) {
    i = j;
  }
  
  public static void main(String args[]) {
    System.out.println(TStatic.i);
    TStatic t = new TStatic(5); // 声明对象引用,并实例化。此时i=5
    System.out.println(t.i);
    TStatic tt = new TStatic(); // 声明对象引用,并实例化。此时i=4
    System.out.println(t.i);
    System.out.println(tt.i);
    System.out.println(t.i);
  }
}

Ergebnis:

0
5
4
4
4

Statische Variablen werden beim Laden der Klasse erstellt und bleiben bestehen, solange die Klasse existiert. Sie müssen bei der Definition initialisiert werden. Im obigen Beispiel ist i nicht initialisiert, sodass der Standardanfangswert 0 erhalten wird. Statische Variablen können nur einmal initialisiert werden und statische Variablen erhalten nur die letzte Initialisierung.
Tatsächlich handelt es sich immer noch um ein Problem, bei dem mehrere Instanzen eine statische Variable gemeinsam nutzen.

Beispiel 2
Nicht als statisch deklariert

class ClassA {
  int b;
  
  public void ex1() {}
  
  class ClassB {
    void ex2() {
      int i;
      ClassA a = new ClassA();
      i = a.b; // 这里通过对象引用访问成员变量b
      a.ex1(); // 这里通过对象引用访问成员函数ex1
    }
  }
}


Als statisch deklariert

class ClassA {
  static int b;
  
  static void ex1() {}
}
  
class ClassB {
  void ex2() {
    int i;
    i = ClassA.b; // 这里通过类名访问成员变量b
    ClassA.ex1(); // 这里通过类名访问成员函数ex1
  }
}

在使用静态方法时要注意,在静态方法中不能调用非静态的方法和引用非静态的成员变量(在static方法中也不能以任何方式引用this或super)。理由很简单,对于静态的东西,JVM在加载类时,就在内存中开辟了这些静态的空间(所以可以直接通过类名引用),而此时非静态的方法和成员变量所在的类还没有实例化。
所以如果要使用非静态的方法和成员变量,可以直接在静态方法中实例化该方法或成员变量所在的类。public static void main就是这么干的。
 
示例3

public class StaticCls {
  public static void main(String[] args) {
    OuterCls.InnerCls oi = new OuterCls.InnerCls();// 这之前不需要new一个OuterCls
  }
}
  
class OuterCls {
  public static class InnerCls {
    InnerCls() {
      System.out.println("InnerCls");
    }
  }
}

 
结果:

InnerCls

3.静态初始化
static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。静态代码块(在“static{”后面跟着一段代码),是用来进行显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。看下面示例。

class Value {
  static int c = 0;
  
  Value() {
    c = 15;
  }
  
  Value(int i) {
    c = i;
  }
  
  static void inc() {
    c++;
  }
}
  
class Count {
  public static void prt(String s) {
    System.out.println(s);
  }
  
  Value v = new Value(10);
  
  static Value v1, v2;
  static {
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
    v1 = new Value(27);
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
    v2 = new Value();
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
  }
}
  
public class TStaticBlock {
  public static void main(String[] args) {
    Count ct = new Count();
    Count.prt("in the main:");
    Count.prt("ct.c=" + ct.v.c);
    Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
    Count.v1.inc();
    Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
    Count.prt("ct.c=" + ct.v.c);
  }
}

 

 
结果:

in the static block of calss Count v1.c=0 v2.c=0
in the static block of calss Count v1.c=27 v2.c=27
in the static block of calss Count v1.c=15 v2.c=15
in the main:
ct.c=10
v1.c=10 v2.c=10
v1.c=11 v2.c=11
ct.c=11

   

不管是v,v1还是v2,它们操作的成员变量都是同一个静态变量c。
在类Count中先初始化v1,v2(static Value v1, v2;),再初始化静态代码块(static{}),最后初始化v。

更多Detaillierte Erläuterung der Funktionen des geschützten Modifikators und des statischen Modifikators in der Java-Programmierung相关文章请关注PHP中文网!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn