identity
Hej! när metoden skrivs på följande sätt så får jag en oändlig loop :
public void start()
{
boolean finished = false;
printWelcome();
while(!finished) {
String input = reader.getInput().trim().toLowerCase();
if(input == "bye") {
finished = true;
}
else {
String response = responder.generateResponse();
System.out.println(response);
}
}
printGoodbye();
}
// jag vet hur man fixar problemet men jag försöker förstå String identity när jag kollar på metoden. Lokal variabeln input är lika med en string literal. Om the input är bye så blir min if statement alltså if ( "bye" == "bye") vilket ska stämma ? för om jag skriver metoden till:'
public void start()
{
boolean finished = false;
printWelcome();
while(!finished) {
String input = "bye"
if(input == "bye") {
finished = true;
}
else {
String response = responder.generateResponse();
System.out.println(response);
}
}
printGoodbye();
}
// så får jag INTE en oändlig metod.... hur kommer detta sig? Tack på förhand !!
Problemet är den här raden:
if(input == "bye")
input kommer aldrig vara lika med "bye".
Även om de har samma innehåll, är de två separata objekt.
Strängjämförelse bör göras med metoden equals. Och det är en "good practice" att börja med literalen (för att inte få exception):
if("bye".equals(input))
Å andra sidan är java sparsam. Den skapar inte flera literaler med samma innehåll, utan återanvänder literalen som redan skapats.
(Jag ber om ursäkt, svarade på första delen först, men jag ser att du förstår konceptet.)
jag vet att man istället bör använda equals metoden MEN jag fattar inte varför den första metoden inte ger samma resultat som den andra :(
Variabeln input refererar inte till en strängliteral i första metoden.
hur kan man se det ?
Om du kollar källkoden för String.toLowerCase() kommer du se att ett String objekt skapas.
Och i din kod ser du att ingen literal tilldelas input.
Men du behöver egentligen inte se det. Du får aldrig använda "==" för strängjämförelse. (Även om du vet att det är verkligen säkert i just ditt fall, kommer du att förvirra andra.)
Man behöver inte kolla källkoden. En färdig sträng skulle behöva finnas i programmet för varje tänkbar sträng du matar in, och det kan det inte göra, den behöver skapas.
Tillägg: 1 nov 2021 21:32
Ordet literal används nog lite fel nånstans här. En literal är ett syntaktiskt begrepp. En literal anges i källkoden med hela sitt innehåll, i stället för att vara resultatet av någon operation.