1. Jämförelser

Programmerare måste jämföra olika variabler med varandra hela tiden. Men som du redan har sett är allt inte så enkelt.

Heltal är väldigt lätta att jämföra - du bara använder ==och du är klar. För att jämföra reella tal måste du jämföra deras skillnad (eller snarare, det absoluta värdet av skillnaden) med ett mycket litet tal.

Att jämföra strängar är ännu svårare. Framför allt beror detta på att strängar är objekt. Dessutom vill programmerare ofta att strängjämförelsen ska gå lite annorlunda beroende på situationen.


2. Hur strängar är ordnade minne

Som du redan har sett lagras strängar i minnet annorlunda än heltal och reella tal:

Hur strängar är ordnade minne

Två minnesblock används för att lagra strängar: ett block lagrar själva texten (dess storlek beror på storleken på texten) medan det andra blocket (4 byte) lagrar adressen till det första blocket.

Även om en erfaren programmerare skulle säga något i stil med " String strvariabeln lagrar en referens till ett Stringobjekt.


3. Tilldela referenser till en sträng

Fördelarna med detta tillvägagångssätt blir uppenbara när du behöver tilldela en strängvariabel till en annan strängvariabel. Exempel:

String text = "This is a very important message";
String message = text;

Och här är vad minnet kommer att innehålla som ett resultat:

Tilldela referenser till en sträng

Efter denna typ av tilldelningsoperation Stringförblir objektet där det var, och bara dess adress (en referens till objektet) kopieras in i variabeln message.


4. Arbeta med referenser och objekt

Men om du bestämmer dig för att konvertera en sträng till versaler (versaler) gör Java-maskinen allt rätt: du kommer att sluta med två Stringobjekt, och variablerna textoch messagelagrar referenser, var och en till sitt eget objekt.

Exempel:

String text = "This is a very important message";
String message = text.toUpperCase(); 

Och här är vad minnet kommer att innehålla som ett resultat:

Arbeta med referenser och objekt

Observera att toUpperCase()metoden inte ändrar strängen den anropas på. Istället skapar den en ny sträng (nytt objekt) och returnerar en referens till den.

Vad sägs om ett ännu mer intressant exempel. Låt oss säga att du bestämmer dig för att skicka en sträng till ett Scannerobjekt (så att den läser värden från strängen).

Exempel:

String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();

Du kan lära dig mer om hur Scannerklassen fungerar här .

Så här kommer allt att lagras i minnet:

Arbeta med referenser och objekt.  Skannerklass

I det här fallet förblir ett enda Stringobjekt i minnet precis som det var - endast referenser till det skickas runt och lagras i variabler.


5. Jämföra referenser till Stringobjekt

Och äntligen har vi nått den roliga delen: strängjämförelse.

Det finns två operatorer du kan använda för att jämföra strängvariabler: ==(lika) och !=(inte lika). Du kan inte använda operatorerna "större än", "mindre än" eller "större än eller lika med" - kompilatorn tillåter det inte.

Men det finns en intressant nyans här: vad lagras egentligen i strängvariabler? Det stämmer: adresser (referenser) till objekt. Och det är dessa adresser som kommer att jämföras:

String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase(); 

Här är vad som kommer att finnas i minnet:

Jämför referenser till strängobjekt

Variablerna messageoch textrefererar till (lagrar adressen till) samma objekt. Men variablerna s1och s2lagrar referenser till objekt som är väldigt lika men distinkta.

Och om du jämför dessa 4 variabler i koden får du följande resultat:

Koda Konsolutgång
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
System.out.println(text == message);
System.out.println(text == s1);
System.out.println(s1 == s2); 


true  // The addresses are equal
false // The addresses are different
false // The addresses are different