A14: The answer is b. Java uses pass by vlaue. When a reference is passed to a method, its reference is copied, but the original reference and the copied refrence will be pointing to the same object. When a primitive value is passed, its value is copied.

In the above example,

Step 1: reference p1 in the stack points to a new Person object created in the heap. When changReference(p1) is invoked, a copy of reference p1 is passed to the method changReference(Person person). Both references p1 and person will be pointing to the same "John" person object.

Step 2: Reference p2 will be referencing a new Person object named "Peter".

Step 3: When person = p2;, the person will be referencing "Peter", but reference p1 is still pointing to "John".

Step 4: When method changName(Person person) is invoked, p1 reference is again copied and reference person will be pointing to "John". Inside the method, the name is changed to "Sam" via the person refrence. Remmeber that p1 is also pointing to the same object, but its value has now changed to "Sam" via the copied reference person.

A15: The answer is a. s1 and s2 are 2 different objects, but have the same value "Hello". So s1.equals(s2) is always true. But s1 == s2 is not true because those references are not pointing to the same "Hello" object, but 2 different objects happen to have same value.

Why is then s1 == s3 is true?

This is the tricky bit. This is a special condition for String objects only. Not for any other objects. You know that String objects are immutable, and for performance reason Java stores Strings created without the new operator in a String pool. So, String s1 = "Hello"; will be stored in the String pool. When you create String s3 = "Hello";, the JVM first checks the String pool to see if the value "Hello" exists in the String pool. If it does, it will not create a new String object but, s3 will be pointing to the same object in the pool. This means, s1 and s3 will be pointing to the same String object. In other words, reference s1 == s3 is true.