Susan Harkins (274) [Avatar] Offline
#1
Please post errors in the published version of OCA Java SE 8 Programmer I Certification Guide here. We'll publish a comprehensive list for everyone's convenience. Thank you!

Susan Harkins
Errata Editor
Manning Publications
428299 (1) [Avatar] Offline
#2
Hi,
In page 416, figure 6.16 "What happens when you change an abstract method in an interface to a default or static method", please, read my comment in line 14 of the code.

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
public int maxDistance() {
return 100;
}
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); // ERROR: in the book says that this code "Doesn't compile", but it compiles because we still have the method maxDistance in Animal class.
}
}


The above code compiles. The below code won't compile, because we have removed the method maxDistance() in Animal class. This way:

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
//Removing this code because the method is static, then it is optional to have the method maxDistance here.
/*public int maxDistance() {
return 100;
}*/ 
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); //Now, because we are refering tho "maxDistance" using the class Animal, the code "Doesn't compile".
}
}


I think the book wanted to explain the second option (showing a compilation error) and it forgot to remove the maxDistance from class Animal.

Please, correct me if I am wrong.

Thanks.

Daniel Augusto de Alcântara Neto (4) [Avatar] Offline
#3
Interface with private member? - Private access modifier - section 1.4.5
Susan Harkins wrote:Please post errors in the published version of OCA Java SE 8 Programmer I Certification Guide here. We'll publish a comprehensive list for everyone's convenience. Thank you!

Susan Harkins
Errata Editor
Manning Publications

Previous, I wrote a post with the same question, but latter i see this post. I am sorry for duplicated post.

In the book (section 1.4.5 - page 61), is written:

"private members are acessible only to the classes and interfaces in which they're defined."

My question is: interfaces can have private member? This is correct?
Daniel Augusto de Alcântara Neto (4) [Avatar] Offline
#4
Example with wrong name of parameter
In the page 132, there is a code:


public int increment (Integer obj) {
   return ++i;
}


The correct is (change name of parameter obj to i):
public int increment (Integer i) {
   return ++i;
}


Or this (change name of variable i to obj):

public int increment (Integer obj) {
   return ++obj;
}
Christopher Kaufmann (1) [Avatar] Offline
#5
Message received from a customer on Facebook regarding an error:

Location: Chapter 4, page 238.

Photo indicating mistake is in the attachment.

Cheers
443739 (1) [Avatar] Offline
#6
Mock Exam Q40. Explanation on page 609. Option c is indicated as correct. Option c is not correct, there are only two correct options, not three.

c. Jump[] eJump3 = new Jump[10];
d. Jump[] eJump4 = new Animal[87];
e. Jump[] eJump5 = new Jump()[12];

...

"Option (e) is incorrect. Apart from using an invalid syntax to initialize an array (as mentioned previously), it also tries to create objects of the interface Jump. Objects of interfaces can't be created."

This same logic applies to option c. You cannot create objects of type Jump because it is an interface. Option c cannot be correct.
AndreiT17 (2) [Avatar] Offline
#7
Hi,

I am new to this forum and I try to remember java programming from while a go (around 12 years...), since I left programming altogether, so I apologize if the question is off topic, or if it does not make sense. I also bought the ebook version of the book, so I am not able to locate the page number.

Anyways, my question is about a statement in section 4.4.6, specifically "Adding multiple elements to an ArrayList", just before/above the Exam Tip:
<blockquote>What happens if you modify the common object references in these lists, myArrList and yourArrList? We have two cases here: in the first one, you reassign the object reference using either of the lists. In this case, the value in the second list will remain unchanged. In the second case, you modify the internals of any of the common list elements—in this case, the change will be reflected in both of the lists.<blockquote>
I understand the first part of this statement, but I don't understand the second part (second case). It looks like even if I change an element in yourArrList (formerly added to the myArrList) this is not reflected in myArrayList (which contains also yourArrList). Please somenone help me understand what do I miss. Below extract of code and output:
Code:
=====
ArrayList<StringBuilder> myArrList = new ArrayList<StringBuilder>();
myArrList.add(new StringBuilder("One"));
myArrList.add(new StringBuilder("Two"));
ArrayList<StringBuilder> yourArrList = new ArrayList<StringBuilder>();
yourArrList.add(new StringBuilder("Three"));
yourArrList.add(new StringBuilder("Four"));
myArrList.addAll(yourArrList);
System.out.println("After adding yourArrList to myArrList");
System.out.println("myArrList:");
for(StringBuilder sb:myArrList){
System.out.println(sb);
}
System.out.println("yourArrList:");
for(StringBuilder sb:yourArrList){
System.out.println(sb);
}

System.out.println("Modify the internal of yourArrList and see what happens with myArrList which contains now yourArrlist");
yourArrList.set(1, new StringBuilder("Ten"));

System.out.println("myArrList:");
for(StringBuilder sb:myArrList){
System.out.println(sb);
}
System.out.println("yourArrList:");
for(StringBuilder sb:yourArrList){
System.out.println(sb);
}

========================================
Output:
======
After adding yourArrList to myArrList
myArrList:
One
Two
Three
Four
yourArrList:
Three
Four
Modify the internal of yourArrList and see what happens with myArrList which contains now yourArrlist
myArrList:
One
Two
Three
Four
yourArrList:
Three
Ten
===========================================

As you can see, myArrList did not change.

Thanks,

Andrei

mala.gupta (245) [Avatar] Offline
#8
Example with wrong name of parameter
Daniel Augusto de Alcântara Neto wrote:In the page 132, there is a code:


public int increment (Integer obj) {
   return ++i;
}


The correct is (change name of parameter obj to i):
public int increment (Integer i) {
   return ++i;
}


Or this (change name of variable i to obj):

public int increment (Integer obj) {
   return ++obj;
}


Thanks for reporting it Daniel. You are correct.

I've added it to the book's errata.

With much respect,
Mala
mala.gupta (245) [Avatar] Offline
#9
AndreiT17 wrote:Hi,

I am new to this forum and I try to remember java programming from while a go (around 12 years...), since I left programming altogether, so I apologize if the question is off topic, or if it does not make sense. I also bought the ebook version of the book, so I am not able to locate the page number.

Anyways, my question is about a statement in section 4.4.6, specifically "Adding multiple elements to an ArrayList", just before/above the Exam Tip:
<blockquote>What happens if you modify the common object references in these lists, myArrList and yourArrList? We have two cases here: in the first one, you reassign the object reference using either of the lists. In this case, the value in the second list will remain unchanged. In the second case, you modify the internals of any of the common list elements—in this case, the change will be reflected in both of the lists.<blockquote>
I understand the first part of this statement, but I don't understand the second part (second case). It looks like even if I change an element in yourArrList (formerly added to the myArrList) this is not reflected in myArrayList (which contains also yourArrList). Please somenone help me understand what do I miss. Below extract of code and output:
Code:
=====
ArrayList<StringBuilder> myArrList = new ArrayList<StringBuilder>();
myArrList.add(new StringBuilder("One"));
myArrList.add(new StringBuilder("Two"));
ArrayList<StringBuilder> yourArrList = new ArrayList<StringBuilder>();
yourArrList.add(new StringBuilder("Three"));
yourArrList.add(new StringBuilder("Four"));
myArrList.addAll(yourArrList);
System.out.println("After adding yourArrList to myArrList");
System.out.println("myArrList:");
for(StringBuilder sb:myArrList){
System.out.println(sb);
}
System.out.println("yourArrList:");
for(StringBuilder sb:yourArrList){
System.out.println(sb);
}

System.out.println("Modify the internal of yourArrList and see what happens with myArrList which contains now yourArrlist");
yourArrList.set(1, new StringBuilder("Ten"));

System.out.println("myArrList:");
for(StringBuilder sb:myArrList){
System.out.println(sb);
}
System.out.println("yourArrList:");
for(StringBuilder sb:yourArrList){
System.out.println(sb);
}

========================================
Output:
======
After adding yourArrList to myArrList
myArrList:
One
Two
Three
Four
yourArrList:
Three
Four
Modify the internal of yourArrList and see what happens with myArrList which contains now yourArrlist
myArrList:
One
Two
Three
Four
yourArrList:
Three
Ten
===========================================

As you can see, myArrList did not change.

Thanks,

Andrei



Hi Andrei -

Thanks for posting this issue.

I've posted a response to this query in your initial thread - https://forums.manning.com/posts/list/40232.page

Apologies for the delay in responding.

With much respect,
Mala
mala.gupta (245) [Avatar] Offline
#10
428299 wrote:Hi,
In page 416, figure 6.16 "What happens when you change an abstract method in an interface to a default or static method", please, read my comment in line 14 of the code.

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
public int maxDistance() {
return 100;
}
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); // ERROR: in the book says that this code "Doesn't compile", but it compiles because we still have the method maxDistance in Animal class.
}
}


The above code compiles. The below code won't compile, because we have removed the method maxDistance() in Animal class. This way:

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
//Removing this code because the method is static, then it is optional to have the method maxDistance here.
/*public int maxDistance() {
return 100;
}*/ 
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); //Now, because we are refering tho "maxDistance" using the class Animal, the code "Doesn't compile".
}
}


I think the book wanted to explain the second option (showing a compilation error) and it forgot to remove the maxDistance from class Animal.

Please, correct me if I am wrong.

Thanks.



Hi there -

Thanks for reporting this issue.

You are correct. I've added it to the book's errata.

With much respect,
Mala
mala.gupta (245) [Avatar] Offline
#11
443739 wrote:Mock Exam Q40. Explanation on page 609. Option c is indicated as correct. Option c is not correct, there are only two correct options, not three.

c. Jump[] eJump3 = new Jump[10];
d. Jump[] eJump4 = new Animal[87];
e. Jump[] eJump5 = new Jump()[12];

...

"Option (e) is incorrect. Apart from using an invalid syntax to initialize an array (as mentioned previously), it also tries to create objects of the interface Jump. Objects of interfaces can't be created."

This same logic applies to option c. You cannot create objects of type Jump because it is an interface. Option c cannot be correct.


Hi there -

The option (c) isn't trying to instantiate the interface Jump (the new operator is not called). The code is stating that this array will store upto 10 instances of classes that implement the interface Jump.

Thanks.

With much respect,
Mala
Susan Harkins (274) [Avatar] Offline
#12
475376 (24) [Avatar] Offline
#13
Part of the explanation of the answer A.2.5 Twist in the Tale 2.4 is incorrect.

Toward the bottom of page 646, the author correctly explains that because of operator precedence the expression is evaluated as (a >= 99 || (a <= 33 && b == 10)). However, the subsequent explanation of how that expression is evaluated is incorrect (last paragraph of page 646 though the beginning of page 647).

According to the book, "Evaluation of the preceding expression starts with the evaluation of (a <= 33 && b == 10)" and the original expression reduces to (a >= 99 || false).

In truth, evaluation of the expression starts with evaluation of the first operand of the short-circuit OR operator, the expression a >= 99. It is only because a >= 99 evaluates to false that the second operand of the short-circuit OR operator, the expression (a <= 33 && b == 10), is (then subsequently) evaluated.
475376 (24) [Avatar] Offline
#14
On page 193, the line

Class Test {

should read

class Test {
475376 (24) [Avatar] Offline
#15
Page 283 EXAM TIP states,
If you don't pass a DateTimeFormatter, the format of the string passed to parse() must be exactly of the format 99:99:99.

No, it doesn't have to be exactly that. Specifying the seconds is optional. Also, nanoseconds can be specified, by following the seconds with a decimal point and one to nine digits. Strings of "10:15", "10:15:30", and "10:15:30.512345" are all valid. The parse(CharSequence text) method uses DateTimeFormatter.ISO_LOCAL_TIME, which per https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_TIME accepts such variations.
475376 (24) [Avatar] Offline
#16
Page 285 section 4.6.3 LocalDateTime: delimiter between seconds and nanoseconds should be a decimal point, not a colon.
It stores a value like 2050-06-18T14:20:30:908765 (year-month-dayThours:minutes:seconds:nanoseconds).

should be
It stores a value like 2050-06-18T14:20:30.908765 (year-month-dayThours:minutes:seconds.nanoseconds).
475376 (24) [Avatar] Offline
#17
Page 293 Table 4.4: symbol in last line (for meaning "escape for text") should be a regular apostrophe ('), not a back quote (`).
475376 (24) [Avatar] Offline
#18
Page 295 mid-page states,
Also, using a pattern letter doesn't specify the count of digits or texts. For an example, using Y or YYYY to format a date object returns the same results.

That's misleading at best. Using YY or YYYYY may produce different results, as could using M vs. MM vs. MMM vs. MMMM, etc. As documented at https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns, the count of pattern letters determines the format.

As an illustration,
LocalDate date = LocalDate.of(2057, 8, 11);
String[] patterns = {"Y M d", "YY MM d", "YYY MMM d", "YYYY MMMM d",
                    "YYYYY MMMMM d"};
for (String p : patterns)
    System.out.println(p + " -> " + DateTimeFormatter.ofPattern(p).format(date));

outputs (for en_US locale):

Y M d -> 2057 8 11
YY MM d -> 57 08 11
YYY MMM d -> 2057 Aug 11
YYYY MMMM d -> 2057 August 11
YYYYY MMMMM d -> 02057 A 11

whereas

DateTimeFormatter.ofPattern("Y M ddd");

throws

java.lang.IllegalArgumentException: Too many pattern letters: d
475376 (24) [Avatar] Offline
#19
Page 302 third bullet: /u0000 should read \u0000
475376 (24) [Avatar] Offline
#20
Page 302 third from last bullet:
Unlike arrays, you may not specify an initial size to create an ArrayList.

You most certainly may, using the ArrayList(int initialCapacity) constructor. And with arrays, the size specified is what it is -- it's not just an "initial" size.
475376 (24) [Avatar] Offline
#21
Page 308 5th bullet:
You can query whether any of three units of a Period is negative using the methods isNegative and isZero. A Period instance is negative if all three of its units are zero.

should instead read something like,
You can query whether any of three units of a Period is negative using the method isNegative, and whether all three of its units are zero using the method isZero.

475376 (24) [Avatar] Offline
#22
Page 333 line 3: else should be indented four spaces (aligning with the if (score <400) line on the previous page). Ironically, this error is in code following the text "Here's the code with the correct indentation:" but it's still (partially) incorrect.
475376 (24) [Avatar] Offline
#23
Pages 415-416 figures 6.15 through 6.17: All seven lines with
System.out println
should instead have
System.out.println
and in figure 6.15, abstact should read abstract.
475376 (24) [Avatar] Offline
#24
Page 416 Figure 6.16: In all three blocks, the line
Animal lion = new Animal();
should be changed to
Jumpable lion = new Animal();
This change should be instead of
In the rectangle that shows changing of an abstract method to a static method (row 2, column 2), class Animal shouldn't include definition of method maxDistance();
which was added to the errata per post #10.

Figure 6.16 is attempting to illustrate how modifying the interface by changing the abstract method to a default method allows the code to continue to compile, but changing it to a static method can result in compilation failure in calling code. The suggestion by user 428299 to remove the maxDistance() method from the Animal class in the row 2, column 2 code block does result in the marked compilation failure but otherwise doesn't really make sense for the example.

Note also that Figure 6.17 has Jumpable lion rather than Animal lion of Figure 6.16.

mala.gupta wrote:
428299 wrote:Hi,
In page 416, figure 6.16 "What happens when you change an abstract method in an interface to a default or static method", please, read my comment in line 14 of the code.

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
public int maxDistance() {
return 100;
}
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); // ERROR: in the book says that this code "Doesn't compile", but it compiles because we still have the method maxDistance in Animal class.
}
}


The above code compiles. The below code won't compile, because we have removed the method maxDistance() in Animal class. This way:

interface Jumpable {
static int maxDistance() {
return 200;
}
}
class Animal implements Jumpable {}
//Removing this code because the method is static, then it is optional to have the method maxDistance here.
/*public int maxDistance() {
return 100;
}*/ 
}
class Forest {
public static void main(String args[]) {
Animal lion = new Animal();
System.out println(lion.maxDistance()); //Now, because we are refering tho "maxDistance" using the class Animal, the code "Doesn't compile".
}
}


I think the book wanted to explain the second option (showing a compilation error) and it forgot to remove the maxDistance from class Animal.

Please, correct me if I am wrong.

Thanks.



Hi there -

Thanks for reporting this issue.

You are correct. I've added it to the book's errata.

With much respect,
Mala
475376 (24) [Avatar] Offline
#25
Pages 452-453:
You can implement polymorphism by using either classes or interfaces. In the case of polymorphism with classes, the base class can be either an abstract class or a concrete class. The method in question here also need not be an abstract method. When you implement polymorphism using interfaces, you must use an abstract method from the interface.
What about polymorphism with default interface methods (described on pages 444-445)? That last sentence should perhaps instead read something like:
When you implement polymorphism using interfaces, you can use abstract or default methods from the interface.



315595 (3) [Avatar] Offline
#26
Chapter 3.6.2 "Read and write object fields" says
Using constructors to write values to object fields


A constructor can read values from object fields too. This can make sense when an object field was written within the initializer block.

This sample will print "10":
public class Test {

	int i, c;
	
	{
		i = 5;
	}
	
	Test(){
		c = 2*i; // Constructor reads i, which was written inside initializer block
	}
	
	public static void main(String[] args) {
		Test test = new Test();
		System.out.println(test.c);
	}
}

475376 (24) [Avatar] Offline
#27
Page 489 Table 7.1 in second column: File Closing Exception should be I/O Exception
475376 (24) [Avatar] Offline
#28
Pages 499 to 500, last sentence of section 7.4.10:
The simple reason for this rule is that RuntimeExceptions aren't checked exceptions, and they may not be caught or declared to be thrown by your code (exception categories are discussed in detail in section 7.2).
is incorrect as runtime exceptions may indeed be caught or declared, but don't have to be. Perhaps "may not" was intended to read "may or may not".
475376 (24) [Avatar] Offline
#29
Page 502 Twist in the Tale 7.3 (and answer on page 656):

I believe the correct answer, if there is one (VM-dependent?), is c, not b. As an experiment I tried running the code on two different VMs; on both the output matched answer c. And there is no such thing as java.lang.StackOverFlowError; in answer choices b and d that was perhaps meant to read java.lang.StackOverflowError.

Also, the last sentence of the answer explanation on page 656:
For example, error-handling code for StackOverFlowError may execute but (as the name suggests) may not execute for VirtualMachineError.
should perhaps read
For example, error-handling code for StackOverflowError may execute but (as the name suggests) may not execute for all VirtualMachineErrors.
because 1) it's StackOverflowError not StackOverFlowError and 2) StackOverflowError is a VirtualMachineError.
475376 (24) [Avatar] Offline
#30
Page 511 Figure 7.21: The text java.lang.AritmeticException should be java.lang.ArithmeticException
475376 (24) [Avatar] Offline
#31
Page 535 last paragraph of answer explanation of Q7-6:
Option (e) code will compile successfully. If a method declares to throw Exception, it might not actually throw it. This only applies to Exception (because RuntimeException subclasses it), runtime exceptions, and errors.
The last sentence is incorrect. A method can declare throwing any Throwable or subclass thereof (whether checked exception, runtime exception, or error) even if it doesn't actually throw anything.
315595 (3) [Avatar] Offline
#32
4.2.3 indexOf()
4.2.3 says:
"You’ll be pleased to learn that many of the methods defined in the class StringBuilder work exactly like the versions in the class String—for example, methods such as charAt, indexOf, substring, and length."

But there is a difference, which could be on the exam. While the indexOf()-method in String accepts chars and Strings, the indexOf()-method of StringBuilder only accepts Strings. Chars are not allowed.

public class Test {

	public static void main(String[] args) {
		
		String str = new String("Paul");
		StringBuilder sb = new StringBuilder("Paul");

		System.out.println(str.indexOf("a"));
		System.out.println(str.indexOf('a'));
		
		System.out.println(sb.indexOf("a"));
		System.out.println(sb.indexOf('a')); // compile error - chars are not allowed.
	}
}
475376 (24) [Avatar] Offline
#33
Page 585 in the last paragraph of the explanation of the answer to ME-Q12 states
LaserPrinter.myPrinter treats LaserPrinter as a variable, although no variable with this name exists in the question's code.
but LaserPrinter is defined in the code as a class. LaserPrinter.myPrinter treats myPrinter as a static variable belonging to the class LaserPrinter.
475376 (24) [Avatar] Offline
#34
Page 588 explanation of the answer to ME-Q16 begins:
Explanation: x+y%z evaluates to 30; (x+(y%z))and (x+(-y)*(-z)) evaluate to 610.
should read
Explanation: x+y%z evaluates as x+(y%z) to 30; (x+(-y)*(-z)) evaluates to 610.
475376 (24) [Avatar] Offline
#35
Page 594 explanation of the answer to ME-Q22 has several errors.
The inner loop won't execute ++ctr for its second element because c2=='a' returns true and the break statement, and exits the inner loop.
should read along the lines of
The inner loop won't execute ++ctr for its second or subsequent elements because c2=='a' evaluates to true and the break statement executes, exiting the inner loop.
The explanations:
Option (c) is incorrect. Because the inner for loop doesn't use {} to group the lines of code that must execute for it, the code ++ctr isn't a part of the inner for loop.
Option (d) is incorrect. The code ++ctr just executes once, after the completion of the outer and inner for loops, because it isn't a part of the looping constructs.
should read along the lines of
Option (c) is incorrect. Because the inner for loop doesn't use {} to group the lines of code that must execute for it, the code ++ctr isn't a part of the looping constructs and just executes once, after the completion of the outer and inner for loops.
Option (d) is incorrect. The code ++ctr executes 16 times (four times for each of the four times the inner loop executes).
475376 (24) [Avatar] Offline
#36
Page 602 ME-Q31:

class MyExam {
    void question() {
        try {
            question();
        } catch (StackOverflowError e) {
            System.out.println("caught");
        }
    }
    public static void main(String args[]) {
        new MyExam().question();
    }
}


Answer (d) of "The code would print caught if StackOverflowError were a checked exception" is given as being correct. However, if StackOverflowError were a checked exception, the code wouldn't even compile (compilation error on line 5, resolvable by adding throws StackOverflowError to the function definitions on lines 2 and 9).
475376 (24) [Avatar] Offline
#37
Page 624 ME-Q59:

The correct answer to the question as worded is d, not c.

The question specifically asks
Given the following code, which option, if used to replace //INSERT CODE HERE, will enable a reference variable of type Roamable to refer to an object of the Phone class?
Per the book's explanation of the answer,
Option (d) is incorrect because a reference variable of the type Roamable can refer to an object of the class Phone with an explicit cast.
False. Explicit cast or not, a reference variable of the type Roamable cannot refer to an object of the unrelated class Phone. To do so would be a violation of the type system. Explicit casting compiles (because class Phone is not final -- subclasses of Phone implementing Roamable could potentially be defined, and objects of those subclasses successfully cast), but fails at runtime for an object of the class Phone itself as defined. Option (d) is correct.
Note the although option (c) will compile, it will throw a ClassCastException if it's executed.
Indeed, with option (c), ClassCastException is thrown at runtime when attempting to evaluate the expression (Roamable)new Phone() on the right side of the assignment operator. As such, the assignment (of the Phone object to Roamable var) never occurs. The reference variable of type Roamable never refers to the new Phone() object. Option (c) is incorrect. It compiles but fails to provide the specified outcome.
315595 (3) [Avatar] Offline
#38
Page 270 - Method equals() in ArrayList when comparing String-Objects.
Page 270 says:
"By default, objects are considered equal if they are referred to by the same variable (the String class is an exception with its pool of String objects)."

I don't think that the "string constant pool" is the reason why two Strings with the same letters are considered equal when compared with the equals()-method. I think they are equal because the method equals() is already overwritten within the String-class.

import java.util.ArrayList;
public class Test {
	
	public static void main(String[] args) {
		
		System.out.println("3 String tests:");
		System.out.println("Both Strings in constant pool: "
						+ ("x" == "x")); // Prints "true"
		System.out.println("One String in constant pool: "
						+ ("x" == new String ("x"))); // Prints "false"
		System.out.println("No String in constant pool: "
						+ (new String("x") == new String ("x"))); // Prints "false"
		
		System.out.println("\nArrayList:");		
		ArrayList<String> myArrList = new ArrayList<>();
		String s1 = new String("Java"); // s1 is NOT in constant pool
		String s2 = "Eclipse"; // s2 is in constant pool
		myArrList.add(s1);
		myArrList.add(s2);
		
		System.out.println(myArrList.contains("Java")); // true
		System.out.println(myArrList.contains(new String("Java"))); //true
		System.out.println(myArrList.contains("Eclipse")); //true
		System.out.println(myArrList.contains(new String("Eclipse"))); //true
	}
}


Line 6 - 12: Only three String-Test showing, that only ("x" == "x" ) returns true, because both are in the string constant pool.

Line 16 creates variable "s1" NOT in the constant pool.
Line 17 creates variable "s2" WITHIN the constant pool.

Lines 21 - 24 are using contains() searching for the same letters used in s1 and s2.
First with reused Strings from the constant pool, then with newly created String-objects.

Result:
All four searches with contains() are returning "true".
- It doesn't matter if the Strings which are added to the ArrayList are within the constant pool or not.
- It doesn't matter if the Strings handed over to the contains()-method are within the constant pool or not.

So different String-objects with the same letters are considered equal not because of the String Constant Pool. They are considered equal, because the class String has already overwritten then equals()-Method from the class Object.
475376 (24) [Avatar] Offline
#39
Hi 315595,

Great to know there are others here paying attention and hopefully all my posts haven't been too much smilie
I don't think that the "string constant pool" is the reason why two Strings with the same letters are considered equal when compared with the equals()-method. I think they are equal because the method equals() is already overwritten within the String-class.
I'd say it depends. It has to do both with overriding (not overwriting) equals and with pooling. Consider the following snippet:
String x1 = "x";
String x2 = "x";
String x3 = new String("x");

ArrayList<String> myArrList = new ArrayList<>();
myArrList.add(x1);

System.out.println(myArrList.contains(x2));
System.out.println(myArrList.contains(x3));
Even if equals were not overridden in the String class, line 8 would still print true because of pooling; x1 == x2. But line 9 prints true only because equals in the String class is overridden; x1 != x3.

To me the page 270 text was technically okay though perhaps confusing as written. The implementation of equals in the Object class simply applies the == operator, and so that is indeed the "default" (non-overridden) behavior for an object as described. But perhaps also noting there that the String class (among others) overrides the equals method (which is what the indexOf and lastIndexOf methods in ArrayList, and hence also the contains method, use to check equality) would have made things a bit more clear.