Die Geschichte, das Verhalten von String durch Passieren von Java nicht zu kennen

Was ist Java als Referenz übergeben?

Der Wert des von der Java-Methode behandelten Arguments wird als Wert für den Basistyp und als Referenz für den Referenztyp übergeben. Wenn diese Geschichte herauskommt, gibt es jedoch einige Fragen, bei denen ich das Verhalten von String nicht verstehe.

Nun, ich wünschte ich könnte das erklären.

Für Grundtyp

Für den Basistyp wird der Wert übergeben. Der Wert wird also kopiert und übergeben. Der Wert selbst wird nicht übergeben. Dies bedeutet, dass sich der Wert der übergebenen Variablen vor und nach der Übergabe an die Methode nicht ändert.

//Beispiel 1
public class PrimitiveType {

	public static void main(String[] args) {
		PrimitiveSample ps = new PrimitiveSample();
		int i = 5;
		System.out.println("Wert vor Änderung der Hauptmethode: " + i);
		ps.changeInt(i);
		System.out.println("Wert nach Änderung der Hauptmethode: " + i);
	}
}

class PrimitiveSample {
	public int changeInt(int i) {
		System.out.println("Wert vor Änderung mit changeInt: " + i);
		i = i + 10;
		System.out.println("Wert nach Änderung mit changeInt: " + i);
		return i;
	}
}
Wert vor Änderung der Hauptmethode: 5
Wert vor Änderung mit changeInt: 5
Wert nach Änderung mit changeInt: 15
Wert nach Änderung der Hauptmethode: 5

Als Referenz übergeben

Im Fall des Referenztyps handelt es sich tatsächlich um "Wert übergeben", da "die Referenzadresse des Referenztyps kopiert und übergeben wird".

Mit anderen Worten, wenn Sie ein Memo mit "Adresse von 1 Sakuragaoka-cho, Shibuya-ku, Tokio" kopieren und übergeben und die Kopie des Memos verwenden, um "einen Brief an die Adresse von 1 Sakuragaoka-cho, Shibuya-ku, Tokio" zu senden. "Adresse von 1 Sakuragaoka-cho, Shibuya-ku, Tokio" erhält den Brief. Selbst wenn Sie die Kopie des Memos zerreißen, hat dies keine Auswirkungen auf die "Adresse von 1 Sakuragaoka-cho, Shibuya-ku, Tokio".

//Beispiel 2
public class PointerType {

	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer();
		sb.append("AIUEO");
		System.out.println("Wert vor Änderung der Hauptmethode: " + sb.toString());
		PointerSample ps = new PointerSample();
		ps.appendData(sb);
		System.out.println("Wert vor Änderung der Hauptmethode: " + sb.toString());
		ps.deleteObject(sb);
		System.out.println("Das Objekt der Hauptmethode verschwindet nicht: " + sb.toString());

	}

}

class PointerSample {
	public void appendData(StringBuffer sb) {
		System.out.println("Wert vor Änderung in appendData: " + sb.toString());
		sb.append("Kakikukeko");
		System.out.println("Wert nach Änderung mit appendData: " + sb.toString());
	}
	public void deleteObject(StringBuffer sb) {
		sb = null;
	}
}
Wert vor Änderung der Hauptmethode:AIUEO
Wert vor Änderung in appendData:AIUEO
Wert nach Änderung mit appendData:Aiue Okakikukeko
Wert vor Änderung der Hauptmethode:Aiue Okakikukeko
Das Objekt der Hauptmethode verschwindet nicht:Aiue Okakikukeko

Ich denke, wir haben bisher darüber gesprochen. Erstens ist das Wort "Referenzübergabe" nicht gut, und "Wertübergabe des Referenzziels" ist korrekt, und es gibt andere Personen, die dies sagen. Ich weiß nicht viel über Java, aber als ich jemanden fragte, der gut in C und C ++ ist, erklärte er: "Dies ist von Wert." Es ist interessant.

String oder Integer ...

Wenn also String oder Integer herauskommt, gibt es ein mysteriöses Argument: "Obwohl der Referenztyp als Referenz übergeben wird, ändert sich der Wert von String nicht. Dies wird als Wert übergeben", wobei jedoch zunächst die obige Geschichte berücksichtigt wird Alles endet mit "Übergeben des Referenztyps als Wert des Referenzziels".

Um noch ein bisschen weiter zu gehen und zu erklären ** Der String-Typ hat keine Funktion zum Ändern des Objekts selbst **, er wird als Konstante behandelt. Gleich wie Integer-Typ. Es gibt keine Funktion zum Ändern des Objekts. Es gibt keine Funktion wie List oder StringBuffer, die "Ihrem Objekt einen Wert hinzufügt und den Inhalt des Objekts ändert".

//Beispiel 3, das nicht aktualisiert wird
public class StringType {
	public static void main(String[] args) {
		StringSample ss = new StringSample();
		String str = "AIUEO";
		System.out.println("Wert vor Änderung der Hauptmethode: " + str);
		ss.changeString(str);
		System.out.println("Wert nach Änderung der Hauptmethode: " + str);
	}
}

class StringSample {
	public void changeString(String str) {
		System.out.println("Wert vor Änderung mit changeString: " + str);
		str = str + "Kakikukeko";
		System.out.println("Wert nach Änderung mit changeString: " + str);
	}
}
Wert vor Änderung der Hauptmethode:AIUEO
Wert vor Änderung mit changeString:AIUEO
Wert nach Änderung mit changeString:Aiue Okakikukeko
Wert nach Änderung der Hauptmethode:AIUEO

Wenn Sie nur Beispiel 3 betrachten, sieht es genauso aus wie Beispiel 1 und Sie sagen "Wert übergeben". Tatsächlich müssen Sie den Inhalt von str = str +" Kakikukeko "; überprüfen.

System.identityHashCode (obj) ist nicht universell einsetzbar, kann jedoch für diese Forschungsstufe verwendet werden. Wenn Sie versuchen, es in Ihr Unternehmen zu integrieren, müssen Sie berücksichtigen, dass "möglicherweise Duplikate vorliegen". Wenn sich der Wert jedoch ändert, ist es gut zu sehen, dass sich das Objekt selbst geändert hat.

public class StringType {
	public static void main(String[] args) {
		StringSample ss = new StringSample();
		String str = "AIUEO";
		System.out.println("Wert vor Änderung der Hauptmethode: " + str);
		System.out.println("Hash 1 in main:" + System.identityHashCode(str));
		ss.changeString(str);
		System.out.println("Wert nach Änderung der Hauptmethode: " + str);
		System.out.println("Hash 2 in main:" + System.identityHashCode(str));
	}
}

class StringSample {
	public void changeString(String str) {
		System.out.println("-------");
		System.out.println("Wert vor Änderung mit changeString: " + str);
		System.out.println("Hash 1 in changeString:" + System.identityHashCode(str));
		System.out.println("-------");
		str = str + "Kakikukeko";
		System.out.println("Wert nach Änderung mit changeString: " + str);
		System.out.println("Hash 2 in changeString:" + System.identityHashCode(str));
		System.out.println("-------");
	}
}
Wert vor Änderung der Hauptmethode:AIUEO
Hash 1 in main:2018699554
-------
Wert vor Änderung mit changeString:AIUEO
Hash 1 in changeString:2018699554
-------
Wert nach Änderung mit changeString:Aiue Okakikukeko
Hash 2 in changeString:1311053135
-------
Wert nach Änderung der Hauptmethode:AIUEO
Hash 2 in main:2018699554

Der Haupt-Hash ist "2018699554", aber in changeString gibt es "2018699554" und "1311053135". Wenn sich das Argument str nicht ändert, entspricht es dem Hash-Wert in main, aber das Objekt hat sich geändert, wenn der str-Wert geändert wird.

Mit anderen Worten, anstatt vom ursprünglichen "2018699554" zu wechseln, haben wir ein neues Objekt "1311053135" erstellt und dort auf "Aiue Okakikukeko" verwiesen.

Dies ist dasselbe wie in Beispiel 2, "Brechen einer Kopie eines Memos". In Bezug auf str ist es nur der Unterschied zwischen "Einfügen von Null" und "Einfügen eines neuen Objekts".

Wenn der String-Typ eine Methode wie "Ändern des Werts seines eigenen Objekts" hätte, wäre dies möglicherweise keine so verwirrende Kontroverse gewesen. Umgekehrt gilt für den String-Typ auch, dass ein einmal festgelegtes Objekt unveränderlich ist, bis ein anderes Objekt zugewiesen wird.

Arrangement ... du ...

Ich weine manchmal, wenn ich sage, dass ein Array ein Array vom Typ int ist, daher muss es als Wert übergeben werden. Da ein Array jedoch ein reales Objekt ist, ist es gut, es genauso zu betrachten wie andere Referenztypen. Ich denke nicht, dass es so schwierig ist, wenn Sie sich den Grundtyp als eine Schachtel mit Objekten vorstellen, die hineingelegt werden können.

Am Ende

Das Übergeben als Referenz ist nicht gut, da das Bild so aussieht, als würde der Referenzwert des Objekts selbst übergeben. Es war eine Geschichte.

Recommended Posts

Die Geschichte, das Verhalten von String durch Passieren von Java nicht zu kennen
Die Geschichte des einfachen String-Vergleichs in Java
[Java] Das Referenzwort ist schlecht!
[Java Edition] Geschichte der Serialisierung
Die Geschichte von Java Gold SE8
Die Geschichte von Java SE11 Silber erhalten
Die Geschichte des Schreibens von Java in Emacs
[Java] [Spring] Testen Sie das Verhalten des Loggers
[Java] Die Geschichte, dass das erwartete Array nicht von der String.split-Methode erhalten wurde.
Die Geschichte eines gewöhnlichen Othello in Java
Die Geschichte des Lernens von Java in der ersten Programmierung
[Java] Ermittelt die Länge der Ersatzpaarzeichenfolge
[Java] Der verwirrende Teil von String und StringBuilder
[Hinweis] Java: Messen Sie die Geschwindigkeit der Zeichenfolgenverkettung
[Java] Grundlegende Zusammenfassung von Java, die nicht von Progate abgedeckt wird ~ Teil 1 ~
Überprüfen Sie das Verhalten von Java Intrinsic Locks mit bpftrace
Erfahren Sie, was es bedeutet, den Pfad zu übergeben, indem Sie eine Java-Entwicklungsumgebung auf einem Mac erstellen
Geschichte des Bestehens von Java Silver SE8 (Oracle Certified Java Programmer, Silver SE 8)
Die Geschichte von dto, dao-like mit Java, SQLite
Ich habe das Verhalten von Java Scanner und .nextLine () nicht wirklich verstanden.
Informationen zum Abschneiden von Zeichenfolgen um die Anzahl der Bytes unter Android
20190803_Java & k8s on Azure Die Geschichte vom Festivalbesuch
Java-Anfänger fassten das Verhalten von Array und ArrayList kurz zusammen
[Java] Versuchen Sie, die Elemente der Json-Zeichenfolge mithilfe der Bibliothek zu bearbeiten
[Java] Grundlegende Zusammenfassung von Java, die nicht von Progate abgedeckt wird ~ Teil 2 ・ Liste ~
Die Falle, die die Standardimplementierung der Java 8-Schnittstelle mit sich bringt
Zusammenfassung der von der Spliterator-Merkmalsmethode #java zurückgegebenen Werte
Die Geschichte, Java mithilfe der BitBucket-Pipeline nach Heroku zu bringen
Umgang mit Java-Gleitkomma Beim Lesen des Nachschlagewerks [Hinweis]
Wechseln Sie die von SDKMAN installierte Java-Version, wenn Sie Verzeichnisse verschieben
Teil 4: Passen Sie das Verhalten der von Spring Security 5 unterstützten OAuth 2.0-Anmeldung an
Die Geschichte, dass die Standardausgabe auch das Verhalten des Programms tödlich verändert
Die Geschichte von toString () beginnt mit der Übergabe eines Arrays an System.out.println
Eine Geschichte über das Erreichen der League Of Legends-API mit JAVA
[Java] Angemessene Einführung durch Tenpa-Leute Java Teil 0 (Code-Regeln)
Ich habe versucht, die Methoden von Java String und StringBuilder zusammenzufassen
Die Geschichte des Anhaltens, weil der Schienentest nicht durchgeführt werden konnte
So überprüfen Sie den Inhalt der Java-Zeichenfolge mit fester Länge
Das Verhalten von JS auf Java SE 8 Nashorn änderte sich plötzlich
[Java] Äquivalenzvergleich, bei dem Anfänger beim Vergleich von Zeichenfolgen fehlschlagen. Möglicherweise sind Sie sich des Fehlers nicht einmal bewusst! ??
Über das Verhalten von Ruby Hash # ==
[Java] Löschen Sie die Elemente von List
Verschiedene Methoden der Java String Klasse
[Java] Ausgabe von DateTimeFormatter durch FormatStyle
Die Geschichte von @ViewScoped, die Speicher verschlingt
Beliebiger Code zum Erstellen von Zeichenfolgen durch Java
Java als Wert übergeben und als Referenz übergeben
Verschiedene Methoden der String-Klasse
[Java] Referenz / Update von Active Directory
Java "Pass by Reference" Problemzusammenfassung
[Java] Korrekter Vergleich des String-Typs
Ich habe die Quelle von String gelesen
Der Ursprung von Java-Lambda-Ausdrücken
Die Geschichte eines Game Launcher mit automatischer Ladefunktion [Java]
Die Geschichte des Erwerbs von Java Silver in zwei Monaten von völlig unerfahrenen.
[Java] Wie man mit der String-Klasse an die Spitze eines bestimmten Strings kommt
Die Geschichte, dass das Servlet nicht in die Java-Webanwendung geladen werden konnte
Überprüfen Sie den MX-Eintrag der E-Mail-Adresse mit Java und die Domain
[Java] Überprüfen Sie, ob die Zeichenfolge nur aus Leerzeichen besteht (= Leerzeichen)
<Java> Quiz zum Batch-Konvertieren von Dateinamen, die durch eine bestimmte Zeichenfolge mit einem Teil des Dateinamens getrennt sind