Activity 9.2.1.
What will the code below print out? Try to guess before you run it! Then, add another Turtle friend2 and set it to juan. Does friend2 == juan? Does friend2 == friend? Print out the Boolean expressions for these.
equals method to test whether two String values were the same if what we cared about was whether they contained the same text. Now that we understand object references we can dig a bit deeper into exactly why that is.
int and reference types like Dog are compared with == in a physical model of Java memory.
== or != to test if two reference values, refer to the same object. In the video, she used Dog objects. In the figure below, we use Turtle objects, creating two Turtle objects assigned to variables juan and mia. Because each variable is assigned to the result of calling the Turtle constructor they do not refer to same object.
friend, assigning it the value from mia. The turtle object mia referenced is now also referenced by the variable friend because each variable holds a copy of the same reference. This is sometimes called an aliases because there are two names, mia and friend that refer to the same object in memory. If two reference variables refer to the same object like the turtle on the right in the image below, the test with == will return true which you can see in the code below.

== and != have a clear meaning when comparing references, with object types we often care about a different notion of equality that looks at the values stored an objectsβ instance variables to decide if they are the same. This is particularly true of classes like String that represent immutable values that just happen to be stored in a more complex way than primitive types like intand double.
s1.equals(s2) is true if s1 and s2 have all the same characters in the same order. It is beyond the scope of the AP curriculum but any class can define its own equals method to compare instances of the class in some meaningful way. By default all classes have an equals method that just uses == but many classes will provide a more meaningful equals so in general whenever you are testing whether two non-primitive values are the same you should use equals unless for some reason you specifically care about whether they are literally the same (or different) objects in memory.
String values that are both == and equals and not. The value of a is neither == nor equals to any of the other variablesβ values since it is the only String with the contents "hi". The other three variablesβ values are all equals to each other since they all contain the text "bye" but only c and d are == since they reference the same actual object. The values of b and c are not == because whenever a String (or any other object) is created with new, it is always a new object that is not == to any other.
== and equals work with String objects in memory.

new keyword, two different String objects will be created that each have the characters Hello in them. So s1 == s2 will be false since they donβt refer to the same object, but s1.equals(s2) is true since the two different objects contain the same characters in the same order.

equals but not with ==.Strings values that come from string literals like String s = "Hello" behave a little differently because Java makes sure, as a way of saving memory, that each unique string literal is represented by the same object in memory. Thus two string literals with the same content would in fact be ==. But that is pretty esoteric Java knowledge and nothing on the AP exam would expect you to know that and almost no Java code is written to take advantage of that fact.
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
s2 = s1;
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
== or != with reference values is to compare a reference value to null to see if it safe to use. Remember that accessing an instance variable or invoking a method on null produces a NullPointerException so if we donβt know that a reference is non-null we need to check before we use it.
&& which ensures that if the first expression in the && is false, it doesnβt evaluate the second expression since it already knows the whole && test is false. So we can write something like:
if (s != null && s.indexOf("x") != -1) { ...
NullPointerException (if you donβt see the exception because of the autograding, you can copy it into the pencil icon scratch area to run it without the grader). Since s is null, trying to access indexOf on s throws an NullPointerException. Comment out the first if statement and run the program again. The second if statement avoids the error with shortcircuit evaluation. Because s != null is false, the rest of the Boolean expression is not evaluated. Now, change s to set it to "apple" instead of null in the first line and run the code again to see that the if statements can print out that βapple contains an aβ.