Ich habe Java Silver SE11 gelernt und die Bedeutung von "String-Objekt ist ein unveränderliches Objekt" nicht verstanden. Deshalb habe ich ein Memorandum hinzugefügt.
Was ist überhaupt der Unterschied zwischen veränderlich (variabel) und unveränderlich (unveränderlich)? Einfach ausgedrückt ist ein veränderliches Objekt ein Objekt, das den Wert ändern kann, sobald es ** später festgelegt wurde. Unveränderliche Objekte sind Objekte, die ** den einmal festgelegten Wert ** nicht ändern können **. Es ist so wie es ist.
Die Definitionsmethode für unveränderliche Objekte lautet wie folgt.
Ab dem nächsten Abschnitt werden wir die Details der einzelnen Klassen überprüfen, indem wir eine unveränderliche Klasse erstellen: Hoge. (Andere Klassen sind aufgeführt, aber diese sind nicht unveränderlich)
Das ist leicht zu verstehen, nicht wahr? Wenn Sie sich für die Öffentlichkeit qualifizieren, können Sie diese beliebig ändern.
Test.java
public class Test {
public static void main(String args[]){
Hoge hoge = new Hoge("Daigouji", "Kerl" ,18);
}
}
class Hoge{
private String name;
private int age;
private Foo foo;
Hoge(){}
Hoge(String lastName, String firstName, int age){
foo = new Foo(lastName, firstName);
this.name = lastName + firstName;
this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Foo getFoo() { return foo; }
public void setFoo(Foo foo) { this.foo = foo; }
public void dummy(){}
}
class Foo{
private String lastName;
private String firstName;
Foo(String lastName, String firstName){ this.lastName = lastName; this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public String getFirstName() { return firstName; }
}
Die Zugriffsmodifikatoren für die Felder, Namen, Alter und Foo der Klasse Hoge sind privat. Ja.
Das ist auch leicht zu verstehen. Selbst wenn Sie sich für privat qualifizieren, bedeutet dies nichts, wenn Sie es über eine Methode ändern können.
Test.java
public class Test {
public static void main(String args[]){
Hoge hoge = new Hoge("Daigouji", "Kerl" ,18);
}
}
class Hoge{
private String name;
private int age;
private Foo foo;
Hoge(){}
Hoge(String lastName, String firstName, int age){
foo = new Foo(lastName, firstName);
this.name = lastName + firstName;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public Foo getFoo() { return foo; }
public void dummy(){}
}
class Foo{
private String lastName;
private String firstName;
Foo(String lastName, String firstName){ this.lastName = lastName; this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public String getFirstName() { return firstName; }
}
Über die Methode können Sie keine Änderungen mehr vornehmen.
Klasse: Erstellen wir einen HogeSub, der Hoge erbt.
Test.java
public class Test {
public static void main(String args[]){
HogeSub hogesub = new HogeSub("Daigouji", "Kerl", 18);
System.out.println("lastName:" + hogesub.getFoo().getLastName() + " firstName:" + hogesub.getFoo().getFirstName());
System.out.println("-----------------");
hogesub.setLastName("Yamada");
hogesub.setFirstName("Jiro");
hogesub.dummy();
System.out.println("lastName:" + hogesub.getFoo().getLastName() + " firstName:" + hogesub.getFoo().getFirstName());
}
}
class Hoge{
private String name;
private int age;
private Foo foo;
Hoge(){}
Hoge(String lastName, String firstName, int age){
foo = new Foo(lastName, firstName);
this.name = lastName + firstName;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public Foo getFoo() { return foo; }
public void dummy(){}
}
class HogeSub extends Hoge {
private String lastName;
private String firstName;
HogeSub(String lastName, String firstName, int age) {
super(lastName, firstName, age);
this.lastName = lastName;
this.firstName = firstName;
}
@Override
public void dummy() {
super.getFoo().setFirstName(this.firstName);
super.getFoo().setLastName(this.lastName);
}
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
}
class Foo{
private String lastName;
private String firstName;
Foo(String lastName, String firstName){ this.lastName = lastName; this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public String getFirstName() { return firstName; }
}
Das Ausführungsergebnis ist wie folgt.
Ausführungsergebnis
lastName:Daigouji Vorname:Kerl
-----------------
lastName:Yamada Vorname:Jiro
HogeSub überschreibt die Dummy-Methode von Hoge und ändert das foo-Feld. Um eine solche Implementierung zu vermeiden, erklären Sie Hoge als endgültig.
Test.java
public class Test {
public static void main(String args[]){
Hoge hoge = new Hoge("Daigouji", "Kerl", 18);
}
}
final class Hoge{
private String name;
private int age;
private Foo foo;
Hoge(){}
Hoge(String lastName, String firstName, int age){
foo = new Foo(lastName, firstName);
this.name = lastName + firstName;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public Foo getFoo() { return foo; }
public void dummy(){}
}
class Foo{
private String lastName;
private String firstName;
Foo(String lastName, String firstName){ this.lastName = lastName; this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public String getFirstName() { return firstName; }
}
Sie können Felder nicht mehr durch Überschreiben ändern.
In der vorherigen Phase wurde der Wert des Objekts über den Getter des Feldes geändert: foo.
Hoge.getFoo().setXXXName(”xxx”);
Wenn Sie diese Art von Operation ausführen, können Sie nicht sagen, dass sie unveränderlich ist. Löschen Sie auch Getter.
Test.java
public class Test {
public static void main(String args[]){
Hoge hoge = new Hoge("Daigouji", "Kerl", 18);
}
}
final class Hoge{
private String name;
private int age;
private Foo foo;
Hoge(){}
Hoge(String lastName, String firstName, int age){
foo = new Foo(lastName, firstName);
this.name = lastName + firstName;
this.age = age;
}
public void dummy(){}
}
class Foo{
private String lastName;
private String firstName;
Foo(String lastName, String firstName){ this.lastName = lastName; this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public String getFirstName() { return firstName; }
}
Sie haben jetzt eine unveränderliche Klasse: Hoge. Der fertige Hoge kann nichts, aber bitte verzeihen Sie mir als Probe ...
** * Dieser Abschnitt ist eine Vermutung. Bitte weisen Sie auf Fehler hin. ** **.
Test2.java
public class Test2 {
public static void main(String args[]){
String str = "Sutoringu 1";
System.out.println(str);
System.out.println("-----------------");
str = "Sutoringu 2";
System.out.println(str);
}
}
Ausführungsergebnis
Sutoringu 1
-----------------
Sutoringu 2
Sicher hat sich der Inhalt von str geändert. Es ist zu beachten, dass sich ** der Wert der Variablen str geändert hat (auf den verwiesen wird), der Wert der Instanz sich jedoch nicht geändert hat **.
Ich werde es mit einem Debugger folgen. Stellen Sie den Haltepunkt wie folgt ein:
Zunächst aus dem Inhalt am ersten Haltepunkt.
Als nächstes der Inhalt am zweiten Haltepunkt.
Sie können sehen, dass sich das Referenzziel von str geändert hat.
Die String-Klasse ist etwas Besonderes, und Sie können mit dem Zuweisungsoperator eine Instanz erstellen, ohne den neuen Operator zu verwenden.
(str =" Storingu 2 ";
und str = new String (" Storingu 2 ");
sind beide der gleiche Prozess)
Mit anderen Worten, das Festlegen einer Zeichenfolge in einer Variablen vom Typ "Zeichenfolge" mit dem Zuweisungsoperator ist gleichbedeutend mit dem Erstellen einer Instanz jedes Mal.
(Genau genommen wird es nicht immer jedes Mal generiert)
Je nachdem, wie Sie es verwenden, verbrauchen Sie möglicherweise immer mehr Speicher in der JVM. Ich gehe davon aus, dass die RingBuilder-Klasse erstellt wurde, um diese Probleme zu lösen.
Immerhin hatte ich das Gefühl, dass die Ausgabe mein Verständnis vertiefen würde (obwohl es spekulativ ist). Ich werde weiterhin mein Bestes geben, um Silver / SE11 zu erwerben.
Recommended Posts