By Developers, For Developers

Historical errata for Java by Comparison

PDF PgPaper PgTypeDescriptionFixed onComments
75SUGGEST

if (0 > speedKmh || speedKmh > SPEED_LIMIT) {
I think
speedKmh < 0 (speed less than 0)
reads better in english than
0 > speedKmh (0 greater than the speed)

2018-01-06Thanks! Indeed swapping this makes it more fluent!
XiiTYPO

Might be intentional but the FizzBuzz interface is for counting between two arbitrary numbers while the main program shall count from 1 to max.

2017-12-21Dear Lennart, \nThe FizzBuzz interface should allow several different implementations of the hame. It's a common anti-pattern having a one-to-one mapping betweens classes and interfaces. Instead, you probably shouldn't create a interface if there is only one class implementing it. \n \nCheers,
4TYPO

The text says the methods return boolean but they return Analysis.

2017-12-21Good catch, Thanks!
41ERROR

A minor issue: in the “Version Control Systems” box you mention GitHub as one example of a provider offering free private repositories.

According to github.com/pricing GitHub is “free to use for public and open source projects”. Private repositories are only included in their paid plans (and their academic research discount).

Alternatives are GitLab and BitBucket which offer private repositories even in their free plans.

2018-01-09Added bitbucket and gitlab as free alternatives.
14SUGGEST

You do not need the explanation “accidentally pasted one line twice”. To match the switch version, the second grantAccess call should be below the isCommander test. If you do it like that, you can illustrate how the problem can easily occur without accidents. An added bonus is that the problem becomes even worse, granting admin access to anyone.

2018-01-19Really good suggestion. We incorporated it. :-)
121TYPO

“The problem is that toVenus and toMars point to the same object.” -> toVenus is should be changed toVenusViaMars.

2018-04-21Yes, you are correct. Thanks for the hint. We'll fix this in the next release.
33ERROR

Of course, I may have done something dumb, but this code gives me an error when I try to run it… It’s the “Mission” example from the General section. If I got it wrong, please let me know… zornhau99 — at — gmail — dot — com

/*
* Excerpted from “Java By Comparison”,
* published by The Pragmatic Bookshelf.
* Copyrights apply to this code. It may not be used to create training material,
* courses, books, articles, and the like. Contact us if you are in doubt.
* We make no guarantees that this code is fit for any purpose.
*
package favor_format_over_concatenation.solution;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

import general.favor_format_over_concatenation.Logbook;

class Mission {

Logbook logbook;
LocalDate start; //This is where the problem is? “start” never gets a value?

void update(String author, String message) {
final LocalDate today = LocalDate.now();
String entry = String.format(“%S: [tm-<te-%<tY](Day %d)> %s%n”,
author, today,
ChronoUnit.DAYS.between(start, today) + 1, message);
logbook.write(entry);
}
}

class Usage {
public static void main(String[] args) {
new Mission().update(“LInUS”, “message”);
}
}

I tried to run it because I couldn’t see where “start” could ever get a value… and the error message is:

objc[93201]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/bin/java (0x10063f4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1006cb4e0). One of the two will be used. Which one is undefined.
Exception in thread “main” java.lang.NullPointerException
\tat java.time.temporal.ChronoUnit.between(ChronoUnit.java:272)
\tat favor_format_over_concatenation.solution.Mission.update(Mission.java:25)
\tat favor_format_over_concatenation.solution.Usage.main(Mission.java:32)

Process finished with exit code 1

2018-04-21It can't just run on its own. You need to set both, the start and the logbook field. We will delete the usage class for the next edition, it shouldn't be there... \n \nUse this to try out the code: \n \nclass Usage { \n public static void main(String[] args) { \n Mission mission = new Mission(); \n mission.start = LocalDate.of(2011,3,4); \n mission.logbook = new Logbook(); \n mission.update("LInUS", "message"); \n } \n}
4723ERROR

Code is completely incorrect. Braces make no sense whatsoever.

I (Simon) checked the solution (right-hand page) of the item "Favor Enums Over Integer Constants" and can't find an issue with the braces - it compiles and reads as expected. I probably have failed to understand your comment. Can you please elaborate a little bit more what you mean? Thanks for your help!
83SUGGEST

TransmissionParse.parse() throws NullPointerException if it gets called with null parameter. The reason is that rawMessage is not properly validated before used in line 11.

This is strange, as I feel that the book kind of “builds up” and this example violates the idea presented earlier in “Avoid NullPointerExceptions in Conditionals” rule.

39SUGGEST

In the context presented, the null check for supplies is superfluous as the variable is initialized during object creation.

87ERROR

The books says: “Actually, try with resources is just syntactic sugar …” This is not entirely true, since it helps a bit more, especially when close() throws an exceptions as well. Effective Java 3rd Edition explains this issue in item 9 and its not simple at all: “It may be hard to believe, but even good programmers got this wrong most of the time. For starters, I got it wrong on page 88 of Java Puzzlers [Bloch05], and no one noticed for years. In fact, two-thirds of the uses of the close method in the Java libraries were wrong in 2007.”

10TYPO

Reads: “…because we check for message.equals(”“) first”. Should read: “…because message.trim().equals() is evaluated first”, or something like that. (You forgot about the “trim()” method.)

11ERROR

The following block of code on this page is intended to check the validity of the given file location

if (location == null || Files.isDirectory(location)) {
throw new IllegalArgumentException(“The path is invalid!”);
}

However the second expression in the parenthesis should be negated since the isDirectory method will return true if the path is valid.

xviiTYPO

The word “asses” in the statement “you can use the book as a reference when you asses student code” should probably be “assess”.

147TYPO

I believe I have found a typo on the bottom of page 147, and think that
.map(Connection::isFree) should be .filter(Connection::isFree)

0SUGGEST

The Javadoc example comment in “Document Using Examples” looks great in the source code, but not so much when rendered as Javadocs… Suggestion: Either add markup for paragraphs and code samples (either … or {@code …}), or else convert the Javadoc comment into a regular multiline comment (/ -> /*).

34SUGGEST

This is a comment about the enum DistanceUnit, as well as the enum SmallDistanceUnit later in the book.

The getConversionRate() method has this if condition in it:
if (this MILES && unit KILOMETERS)
However, as far as I can tell, it really only needs to be:
if ( unit == KILOMETERS)

There are only 2 enum values, and identity was previously checked for in this method. So there is no need to check both this and the unit. Only one is required, and I think unit, as the parameter, makes more sense to use.

I will add that while using both may seem to provide clarifying information, or future proof the method if other enum values are added, the else section doesn’t use an if to check the opposite (this KILOMETERS && unit MILES), so it already relies on the fact that there are only 2 enum values.

83SUGGEST

This is regards to the TransmissionParser class and is a reiteration of Tuomas Granlund comment about the parse() method. This class occurs numerous times, and not only on page 87.

86TYPO

Text mentions writeToCaptianLog() instead of writeToCaptainLog().

61SUGGEST

Without further explanation you will not see the difference between camelCase and CamelCase. Using the terms lowerCamelCase and UpperCamelCase or PascalCase would make the distinction easier.

63SUGGEST

Hi there,
I believe the Astronaut’s constructors’ semantics is not consistent. new Astronaut() does not initializes this.name while new Astronaut(“God is an Astronaut”); does.
I think it’s good practice to have many constructors which all call this(DEFAULT_NAME); in Astronaut().
Moreover, I recommend initializing all fields in a constructor. Thus, this.retired = False; should explicitly be set.

131ERROR

In the second last line, you state that ‘Note that the braces are only optional for a single parameter …’
I suggest to use ‘parentheses’ instead of ‘braces’. Thus, ‘Note that parentheses are optional for a single parameter’

134TYPO

‘error-prone’ instead of ‘error prone’?

60ERROR

“We consistently named everything in CamelCase: no spaces, and all words start
with a capital letter. As long as we’re consistent, we can choose any way of
naming, can’t we?”

That is not camel case, but ````````_`pascal case_.
Camel case starts with a lower letter, than all the other words are capitalized, e.g.: camelCaseVariableName
Pascal case has every word capitalized, even the first one, e.g.: PascalCaseVariableName

Someone talks about lower camel case and upper camel case, even if I prefer camelcase and PascalCase.

In the end, I think we can be a little bit more clear in that paragraph :)

see wikipedia.org Camel_case

Categories: