Verweise auf Ganzzahlobjekte in Java
Es gibt keinen Zeiger in Java, aber es gibt auch Referenzkonzepte. Was wir hier sprechen wollen, ist, ob Ganzzahl das gleiche Objekt ist.
1. Schauen wir uns zuerst einen Code an:
public static void main (String [] args) {Integer a1 = 100; Ganzzahl B1 = A1; // Der andere kann auch B1 = 100 Feld Feld = null sein; try {field = a1.getClass (). getDeclaredfield ("Wert"); } catch (NoSuchfieldException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } catch (SecurityException e) {// Todo automatisch generierter Block e.printstacktrace (); } field.setAccessible (true); try {field.set (a1, 5000); } catch (illegalArgumentException e) {// Todo automatisch generierter Fangblock e.printstacktrace (); } catch (illegalAccessException e) {// Todo automatisch generierter Fangblock E. printstacktrace (); } System.out.println ("B1 ="+B1); Ganzzahl C1 = 100; System.out.println ("c1 ="+c1); } Ergebnis:
B1 = 5000
C1 = 5000
Zuallererst möchte ich hier ein paar Dinge erklären.
1) Für die Ganzzahl wurde die Ganzzahl zwischen -128-127 initialisiert und in Integercache platziert. Wenn es gepackt ist, wird das Objekt daraus entnommen.
2) Ist B1 = A1 eine numerische Zuordnung oder dasselbe Objekt? Dies ist aus den Ergebnissen ersichtlich, dass B1 und A1 auf dasselbe Objekt deuten, nicht auf denselben numerischen Wert
3) C1 = 100 bedeutet, dass für die Werte zwischen -128-127 alle von Integercache erhaltenen Objekte. Nachdem das Ganzzahl -Objekt, das 100 entspricht, geändert wurde, wird die anschließende Packung von 100 geändert. Da beim Erhalten von Objekten im Cache der Array -Index verwendet wird, werden nicht numerische Vergleiche verwendet.
Das Ändern dieses Cache ist jedoch gefährlicher, also macht es nichts aus. Wer weiß, welches JAR -Paket oder welche Plattform ein 100 Yuan packt, aber das Ergebnis ist nicht 100 Yuan, und es wird zu diesem Zeitpunkt abstürzen.
2. In der obigen Beschreibung, wie lautet die Antwort, wenn sie darauf geändert wird
public static void main (String [] args) {Integer a1 = 200; Ganzzahl B1 = A1; Feldfeld = null; try {field = a1.getClass (). getDeclaredfield ("Wert"); } catch (NoSuchfieldException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } catch (SecurityException e) {// Todo automatisch generierter Block e.printstacktrace (); } field.setAccessible (true); try {field.set (a1, 5000); } catch (illegalArgumentException e) {// Todo automatisch generierter Fangblock e.printstacktrace (); } catch (illegalAccessException e) {// Todo automatisch generierter Fangblock E. printstacktrace (); } System.out.println ("B1 ="+B1); Ganzzahl C1 = 200; System.out.println ("c1 ="+c1); } 3. Ändern Sie es dann
public static void main (String [] args) {Integer a1 = new Integer (100); Ganzzahl B1 = A1; Feldfeld = null; try {field = a1.getClass (). getDeclaredfield ("Wert"); } catch (NoSuchfieldException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } catch (SecurityException e) {// Todo automatisch generierter Block e.printstacktrace (); } field.setAccessible (true); try {field.set (a1, 5000); } catch (illegalArgumentException e) {// Todo automatisch generierter Fangblock e.printstacktrace (); } catch (illegalAccessException e) {// Todo automatisch generierter Fangblock E. printstacktrace (); } System.out.println ("B1 ="+B1); Ganzzahl C1 = 100; System.out.println ("c1 ="+c1); } Was ist die Antwort? Für neue Operationen werden Objekte nicht gebeugt, sondern im Haufen generiert.
Es ist nicht schwer zu verstehen, wenn Sie Boxen, Caching und Zitat verstehen. Sie können es selbst ausprobieren.
Lassen Sie uns zuerst Grundkenntnisse erhalten
Korrespondenz von Basistypen und Wrapper -Klassen Byte Byte Kurzform kurz intiernieger Long Long Float Double Double Char Zeichen Boolean Boolean Boolean
Die Korrespondenz zwischen den grundlegenden Datentypen in den oben genannten acht ist nur integer char-> charakter. Die beiden Änderungen sind signifikant und der Rest konvertieren nur den ersten Buchstaben in Kleinbuchstaben.
Erfahren wir über die neuen Funktionen von JDK5: Automatisches Verpacken und Unboxing
Automatisches Boxen: Wenden Sie Grundtypen in Verpackungsklassentypen um
Automatisches Unboxing: Konvertieren Sie den Wrapper -Klassentyp in den Basistyp
öffentliche Klasse Demo_Integer {public static void main (String [] args) {// vor jdk1.5 int a = 100; Ganzzahl a1 = New Integer (a); // Wickeln Sie den grundlegenden Datentyp in ein Objekt ein, Kasten int b = a1.intValue (); // das Objekt in den Basis -Datentyp und Unbox // nach jdk1.5 int x = 100 konvertieren; Ganzzahl x1 = x; // automatisch den Basis -Datentyp in ein Objekt int y = x1 + x konvertieren; // automatisch unbox das Objekt in den grundlegenden Datentyp}} konvertieren}} konvertierenDinge zu beachten
öffentliche Klasse Demo_Integer {public static void main (String [] args) {Integer a = null; int b = a + 100; // Die untere Schicht des automatischen Unboxing nennt A.IntValue (), a ist null und ein Wille werfen natürlich NullPointerexception -System.out.println (b); }}Interviewfragen
public class Demo_Integer {public static void main (String [] args) {Integer i1 = new Integer (97); Ganzzahl i2 = New Integer (97); System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("-------------"); Ganzzahl i3 = New Integer (197); Ganzzahl i4 = New Integer (197); System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("----------------"); }}Ausgabe: Falsch True ----------------------------------
Grund:
Neu ist, den Raum im Heap -Speicher zu öffnen, und der natürliche Vergleichsadressenwert (==) ist falsch.
Da Ganzzahl die Equals -Methode umschreibt, ist die Equals -Ausgabe wahr.
Möglicherweise sind Sie das Gefühl, dass es zu einfach ist und keinen technischen Inhalt hat, da dies nicht der Punkt ist. Schauen Sie sich den folgenden Code an
öffentliche Klasse Demo_Integer {public static void main (String [] args) {Integer i1 = 127; Ganzzahl i2 = 127; System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("--------------"); Ganzzahl i3 = 128; Ganzzahl i4 = 128; System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("---------------"); }}Ausgabe: True True ----------------------------------------------
Grund:
Warum machen zwei Objekte, wenn int größer als 127 ist? Fühlt sich die Nummer 127 sehr vertraut an?
-128 bis 127 sind der Wertebereich von Byte. Wenn es sich in diesem Wertebereich befindet, erstellt automatisches Boxen kein neues Objekt und erhalten Sie es aus dem konstanten Pool aus
Wenn der Wertebereich von Byte überschritten wird, wird ein neues Objekt erstellt.
Packen Sie automatisch die zugrunde liegende Ebene und rufen Sie die ValueOF () -Methode, einfache Quellcodeanalyse (JDK1.8) auf:
öffentliche endgültige Klasse Integer erweitert die Zahl implementiert vergleichbar <Integer> {public static Integer ValueOf (int i) {// Wenn i> = -128 und i <= 127, wird das Objekt im Puffer direkt abgerufen, wenn (i> = Integercache.low && i <= Integercache.HWIGHT zurückgegeben). Neue Ganzzahl zurückgeben (i); // Wenn der Byte -Wert -Bereich den Bereich überschreitet, wird er in Heap -Speicher} // Die innere Klasse erstellt als Puffer private statische Klasse IntegerCache {static Final int low = -128; statische endgültige int hoch; statischer endgültiger Ganzzahl -Cache []; static {// hoher Wert kann durch Eigenschaft int H = 127 konfiguriert werden; String IntegerCacheHighPropValue = sun.misc.vm.getSavedProperty ("java.lang.Ineger.Inegercache.high"); if (IntegerCacheHighPropValue! i = math.max (i, 127); // Maximale Arraygröße ist integer.max_value h = math.min (i, ginneger.max_value -(-low) -1); } catch (numberFormatexception nfe) {// Wenn die Eigenschaft nicht in ein int analysiert werden kann, ignorieren Sie sie. }} High = H; Cache = New Integer [(hoch - niedrig) + 1]; int j = niedrig; für (int k = 0; k <cache.length; k ++) cache [k] = new Integer (j ++); // Bereich [-128, 127] muss internalisiert werden (JLS7 5.1.7) Integercache durchsetzen.High> = 127; } private IntegerCache () {}}} 8 Grundtypen von Wickelklassen und Objektpools
Die meisten Grundtypen von Wrapper -Klassen in Java implementieren konstante Pooling -Technologie. Diese Klassen sind Byte, Kurz-, Ganzzahl-, Long-, Charakter-, Boolesche und die beiden anderen Arten von Wrapper -Klassen mit schwimmender Punktzahl werden nicht implementiert. Darüber hinaus kann die fünf Ganzzahl -Wrapper -Klassen von Byte-, Kurz-, Ganzzahl-, Long-, Zeichen nur den Objektpool verwenden, wenn der entsprechende Wert weniger als oder gleich 127 ist, dh das Objekt ist nicht für das Erstellen und Verwalten von Objekten dieser Klassen von mehr als 127 verantwortlich.
Erweitertes Wissen
In der JVM -Spezifikation hat jeder Typ seinen eigenen konstanten Pool. Ein konstanter Pool ist eine geordnete Sammlung von Konstanten, die von einem bestimmten Typ verwendet werden, einschließlich direkter Konstanten (primitive Typen, Zeichenfolgen) und symbolische Verweise auf andere Typen, Felder und Methoden. Der Grund, warum es eine symbolische Referenz ist, anstatt andere Typen zur Kompilierungszeit direkt anzugeben, liegt darin, dass Java dynamisch gebunden ist und nur zur Laufzeit die spezifischen Abhängigkeitsinstanzen vom Typ bestimmter Regeln bestimmt werden. Dies ist die Grundlage für Java, um Polymorphismus umzusetzen.
Im JVM beginnt der gesamte Lebenszyklus einer Klasse in den Speicher der virtuellen Maschine und bis sie aus dem Speicher entladen wird. Der gesamte Lebenszyklus umfasst: Laden, Überprüfung, Vorbereitung, Parsen, Initialisierung, Verwendung und Entladen. Die Parsenstufe ist der Prozess des virtuellen Maschinen, der Symbolreferenzen im konstanten Pool durch direkte Referenzen ersetzt.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.