Working Through Java Software Solutions 2nd Edition Without Losing Your Mind
I spent about three years working with CS1 and CS2 instructors who used this book, and I have a sense of what actually works versus what just looks good on paper. The second edition is a step up from the first in terms of how it handles object-oriented design, but it still trips up people who treat it like a novel instead of a lab manual. The book is structured around progressive complexity, which sounds nice until you hit the chapter on encapsulation and realize the author assumes you already understand why you need access modifiers in the first place. Here is the practical approach: work through the chapters in order, but do every single exercise at the end. The examples in the chapters are illustrative. The exercises are where you actually learn anything. I encountered a specific issue that came up repeatedly with students in the inheritance chapter. The book walks through creating a superclass and subclass relationship using shapes and rectangles, but it glosses over what happens when you try to instantiate a subclass and call a method that overrides the parent. The compiler will not complain, but the output is often counterintuitive if you have not internalized how method resolution works at runtime. My workaround was having students write out the actual method resolution chain by hand before compiling anything. It takes about ten minutes but prevents hours of confusion later.
The book covers standard topics: primitives, control flow, arrays, classes and objects, inheritance, interfaces, generics, collections, exception handling, and basic I/O. The coverage is solid but not exhaustive. If you need to know about concurrency, the book does not go there. If you need to understand JVM memory management in any depth, you will need a different resource alongside it. One thing most beginners miss about this material: the difference between composition and inheritance is not just a theoretical distinction. It affects how your code breaks when requirements change. The book mentions this in passing but does not hammer it home hard enough. In my experience, the people who struggle most in later semesters are the ones who treated inheritance as the default tool for code reuse rather than a specific mechanism for "is a" relationships. Composition is almost always the better answer when you are building something that needs to change independently. There is also a practical limitation worth noting upfront. The second edition uses Eclipse-style project setups as examples throughout the book. If you are working in IntelliJ, VS Code, or any IDE with a different project structure, you will spend extra time mapping the instructions to your environment. This is not a flaw in the book itself, but it is a real friction point. The workaround is straightforward: create a new Java project, set up the package structure exactly as shown in the book's example output, and paste the code into files matching the package declaration. It adds roughly fifteen minutes per chapter at the start but saves you from chasing compilation errors that are actually just path issues.
Another counter-intuitive point: the chapter on generics comes relatively late in the book. Most students encounter ArrayList in the collections chapter before they fully grasp why generic type parameters exist. When the generics chapter finally arrives, it feels abstract because you do not yet have enough concrete problems where raw types would be painful. Try jumping ahead to the collections chapter, skim it, then return to generics with the context of having actually tried to store objects in lists without type safety. The concept lands much better that way. The book also has a decent section on debugging and testing, but it understates how important it is to learn to read stack traces early. I have watched people spend days stuck on NullPointerException because they refused to look past the first line of the error. The stack trace tells you exactly where the problem is. The book does not emphasize this enough for self-learners who do not have an instructor to walk them through their first dozen exceptions. If you are using this as a primary resource, pair it with actual coding practice. Reading the chapters passively gives you the illusion of understanding. The material only sticks when you write the code, break it, fix it, and refactor it. The exercises are non-negotiable. Do them all. The ones marked with stars are worth prioritizing if you are short on time, but even the basic ones teach something.
Get the Full Details

The book is available through most academic retailers and the publisher's website. If you are a student, check your campus bookstore first. The digital version is usually cheaper and searchable, which matters when you are trying to find a specific example about a week later and cannot remember which chapter it was in. The paperback is fine if you prefer writing notes in margins, which is what most of my students ended up doing anyway.