Heim > Java > javaLernprogramm > Hauptteil

Erklären Sie, wie Sie in Java innere Klassenobjekte erstellen und auf Objekte zugreifen

高洛峰
Freigeben: 2017-01-20 17:42:38
Original
1243 Leute haben es durchsucht

Konstruieren Sie interne Klassenobjekte durch Reflexion
Schreiben Sie zunächst eine Klasse mit internen Klassen unter dem Javalang-Paket:

package javalang;
 
public class Outer {
  public static class Inner1{}
}
Nach dem Login kopieren

Beachten Sie, dass diese Klasse öffentlich statisch ist. Wir werden sie verlangsamen später nach unten Entfernen Sie diese Modifikatoren langsam.

Um das Inner1-Objekt durch Reflexion zu erstellen, müssen Sie zunächst das Klassenobjekt von Inner1 abrufen. Wir schreiben die Hauptmethode in Outer:

public class Outer {
  public static class Inner1{}
   
  public static void main(String[] args) {
    System.out.println(Inner1.class);
  }
}
Nach dem Login kopieren

Ausgabeergebnis:

class javalang.Outer$Inner1
Nach dem Login kopieren

Dann versuchen wir herauszufinden, ob dieser Klassenname korrekt ist:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1"));
}
Nach dem Login kopieren

Führen Sie es aus, das ist richtig. Dann verwenden Sie es einfach, um Objekte zu erstellen. Das Erstellen von Objekten basiert auf Konstruktoren. Verfügt diese Klasse über eine Konstruktormethode? Wir können schreiben:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors().length);
}
Nach dem Login kopieren


Führen Sie es aus und geben Sie 1 aus. Es scheint so zu sein. Dann schauen Sie sich an, wie diese Konstruktionsmethode aussieht:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors()[0]);
}
Nach dem Login kopieren


Ausgabeergebnis: public javalang.Outer$Inner1(). Dies ist die Standardkonstruktionsmethode. Wir können also so schreiben:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors()[0].newInstance();
}
Nach dem Login kopieren

Ausgabeergebnis: javalang.Outer$Inner1@ca0b6. Dies zeigt an, dass die Ausführung erfolgreich war.

Als nächstes entfernen wir das öffentliche Schlüsselwort Inner und führen es erneut aus. Das Ergebnis ist ein Fehler:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
Nach dem Login kopieren

Dies bedeutet, dass die Bauweise nicht gefunden wurde. Wirklich nicht? Wir ändern die Hauptmethode zurück:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors().length);
}
Nach dem Login kopieren

Ausgabeergebnis: 0. Gibt es wirklich keinen Konstruktor? Eigentlich nein, es ist nur so, dass die Bauweise nicht öffentlich ist. Zu diesem Zeitpunkt müssen wir getDeclaredConstructors() verwenden, um Folgendes zu erhalten:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors().length);
}
Nach dem Login kopieren

Ausgabeergebnis: 1. Dies findet die Bauweise. Dann rufen wir diesen Konstruktor weiterhin auf:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance());
}
Nach dem Login kopieren

Ausgabeergebnis: javalang.Outer$Inner1@ca0b6. Jetzt können wir Reflektion verwenden, um Objekte nicht öffentlicher innerer Klassen zu konstruieren.

Als nächstes entfernen wir das statische Schlüsselwort. Zu diesem Zeitpunkt wurde ein Fehler gemeldet:
Ausnahme im Thread „main“ java.lang.IllegalArgumentException: falsche Anzahl von Argumenten

Was bedeutet das? Wir haben beim Aufruf keine Parameter übergeben und der Fehlerinhalt bestand darin, dass die Anzahl der Parameter falsch war. Welche Parameter hat dieser Konstruktor? Lassen Sie uns den Code ändern und einen Blick darauf werfen:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0]);
}
Nach dem Login kopieren

Ausgabeergebnis: javalang.Outer$Inner1(javalang.Outer)

Es stellt sich heraus, dass der Konstruktor einen Outer-Typparameter benötigt. Das geht ganz einfach:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance(new Outer()));
}
Nach dem Login kopieren

Ausgabeergebnis:

javalang.Outer$Inner1@ca0b6
Nach dem Login kopieren

OK, das war's. Es scheint, dass nicht statische innere Klassen keine Standardkonstruktionsmethode haben und während der Konstruktion eine Instanz einer äußeren Klasse als Parameter übergeben werden muss.


Java: So greifen Sie auf ein Objekt zu
Ein Problem für Java-Anfänger ist die Frage, wie man entscheidet, ob ein Objekt als Methodenvariable oder als Mitgliedsvariable definiert werden soll.

Einsteigern wird das zunächst egal sein. Aber wenn die geschriebenen Programme immer größer werden und es immer mehr Klassen gibt, entsteht auch diese Art von Bedrängnis.

Aber was ich hier schreiben möchte, ist: Wie man ein Objekt nach Belieben anordnet, damit man jederzeit darauf zugreifen kann. Sobald Sie dies beherrschen, können Sie frei entscheiden, wo Sie ein Objekt platzieren möchten.

Hier ist ein einfaches Beispiel:

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    // 这里如何获得 main() 方法中的 date 变量?
  }
}
Nach dem Login kopieren

Wie in der anHourLater()-Methode beschrieben, möchten Sie die Uhrzeit eine Stunde nach dem Datum erhalten. Was zu tun? Im Folgenden finden Sie mehrere Methoden.

(1) Parameterübergabe

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater(Date d) {
    Date anHourLater = new Date(d.getTime() + 3600000);
  }
}
Nach dem Login kopieren

(2) Als Mitglied definiert. Auf Mitglieder kann mit allen Methoden zugegriffen werden, und die Mitgliederinitialisierung kann dort platziert werden, wo sie definiert sind, oder in einer beliebigen Methode.

public class AccessingObject {
   
  private static Date date;
   
  public static void main(String[] args) {
    date = new Date();
    anHourLater();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(date.getTime() + 3600000);
  }
}
Nach dem Login kopieren

(3) Ordne es einer anderen Klasse zu. Im folgenden Beispiel können alle Klassen im selben Paket auf DateHolder.date zugreifen, nicht nur die AccessingObject-Klasse.

public class AccessingObject {
   
  public static void main(String[] args) {
    DateHolder.date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(DateHolder.date.getTime() + 3600000);
  }
}
   
class DateHolder {
  public static Date date;
}
Nach dem Login kopieren

Vergleicht man diese drei Beispiele, können die ersten beiden nur innerhalb der Klasse verwendet werden und sind relativ sicher. Wenn Sie nicht möchten, dass dieses Objekt direkt von anderen Klassen geändert wird, verwenden Sie nicht die dritte Methode.

Der Unterschied zwischen der ersten Methode und der zweiten Methode besteht darin, dass, wenn ein Objekt nur in einer Methode verwendet wird, das Objekt bei Ausführung der Methode problemlos recycelt werden kann (beachten Sie, dass es nicht sofort recycelt wird). . Wenn das Objekt als Mitglied einer Klasse definiert ist, wird es erst recycelt, nachdem die Klasse, in der es sich befindet, recycelt wurde. Offensichtlich ist die erste Methode die ressourcenschonendste, und wir sollten versuchen, die erste Methode zu verwenden.

Rückblickend auf diese drei Beispiele: Wenn die main()-Methode die in der anHourLater()-Methode erhaltene Zeit eine Stunde später erhalten möchte, gibt es auch mehrere entsprechende Möglichkeiten. Die letzten beiden Beispiele müssen nicht geändert werden. Im ersten Beispiel kann direkt auf das Datumsobjekt zugegriffen werden. Es gibt zwei Änderungsmethoden:

(1) als Rückgabewert

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    Date anHourLater = anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static Date anHourLater(Date d) {
    return new Date(d.getTime() + 3600000);
  }
}
Nach dem Login kopieren

(2) Den Inhalt von Parametern direkt ändern

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater(Date d) {
    d.setTime(d.getTime() + 3600000);
  }
}
Nach dem Login kopieren

Die zweite Methode sollte verwendet werden mit Vorsicht, denn Es ist falsch, die Sachen anderer Leute beiläufig anzufassen. Sie wissen nicht, ob es dem Aufrufer der Methode gefällt oder nicht.

Weitere Artikel, die erklären, wie man interne Klassenobjekte erstellt und auf Objekte in Java zugreift, finden Sie auf der chinesischen PHP-Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!