Re: Effective Java 4th Edition Pdf Free Download

0 views
Skip to first unread message
Message has been deleted

Outi Foote

unread,
Jul 15, 2024, 3:20:21 PM7/15/24
to royroplicom

Joshua Bloch, Google's chief Java architect, is a former Distinguished Engineer at Sun Microsystems, where he led the design and implementation of numerous Java platform features, including JDK 5.0 language enhancements and the award-winning Java Collections Framework. He holds a Ph.D. in computer science from Carnegie-Mellon University.

Bloch won the prestigious Jolt Award from Software Development Magazine for the first edition of his 2001 book, Effective Java Programming Language Guide , known to many developers as Effective Java , and he is also the coauthor (with Neal Gafter) of the highly regarded book Java Puzzlers.

effective java 4th edition pdf free download


DOWNLOAD https://tinurll.com/2yN5Bj



Q: In the preface to the new edition of Effective Java , you described moving to Google in 2004 and wrote: "I've also had the pleasure of using the Java platform to develop libraries for use within Google. Now I know what it feels like to be a user." How did your experience as a user inform the new edition of the book?

A: Well, for one thing, it reinforced my feeling that it's critical to get API designs right. For example, I found myself wanting to provide an alternative FileChannel implementation for the Google File System, but I couldn't, because FileChannel is a concrete class rather than an interface. Similarly, I wanted to implement a growable ByteBuffer. These are the sort of frustrations that ordinary developers feel every day.

Q: You have said that a common fault among Java developers is the natural tendency to optimize code, resulting in slower code that is needlessly complicated. Why do developers mistakenly optimize code?

"It's easy to feel like the general warnings about premature optimization don't apply to you, because you just know which code is time-critical and how to make it fast. But no one can determine this without measuring before and after each attempted optimization."

A: To be a software developer, you have to be an optimist -- otherwise, it would feel like a losing battle. Generally, this is a good thing, but it has a downside: Optimism can lead to overconfidence. It's easy to feel like the general warnings about premature optimization don't apply to you, because you just know which code is time-critical and how to make it fast. But no one can determine this without measuring before and after each attempted optimization.

A: Two reasons: By far the most common reason is that the developer doesn't know the library exists. I feel for that developer, because there are so many libraries out there that it's impossible to keep track of them all. That said, it's so hard to get some of these facilities right that it's worth making the effort to find out if a library exists.

This is particularly true where concurrency is involved. It's not uncommon for experts to spend literally months writing apparently modest concurrency utilities. When faced with a need for this sort of functionality, the wise developer will do whatever it takes to find an appropriate library. It's so easy to get nontrivial concurrent code wrong, and the resulting bugs can be nearly impossible to detect.

The second reason that developers tend to reinvent the wheel is the same reason they tend to optimize prematurely: In order to stay sane, most developers have a can-do attitude, and some take it too far. They say to themselves, "Yes, there's a library, but I can do better." Maybe you can, but that doesn't mean you should. Use the standard library unless it's profoundly unsuited to your needs.

"In order to stay sane, most developers have a can-do attitude, and some take it too far. They say to themselves, 'Yes, there's a library, but I can do better.' Maybe you can, but that doesn't mean you should."

Q: George Orwell famously presented five rules of good writing -- and then added a sixth: "Break any of these rules sooner than say anything outright barbarous." Effective Java now consists of 78 items with titles consisting of short rules like "Favor generic methods" or "Consider using a custom serialized form," to choose two at random. Do you have any favorite rules? And when should developers break the rules?

A: First, I should point out that I shamelessly stole Orwell's admonition. In the introduction to Effective Java, it says, "You should not slavishly follow these rules, but violate them only occasionally and with good reason."

I can be somewhat fickle, so my favorite rules might change if you ask me on another day, but today I'll go with Item 13, "Minimize the accessibility of classes and members," and Item 15, "Minimize mutability." Both of these rules transcend any particular programming language.

The first tells you to hide information to the maximum extent feasible. This principle, due originally to David Parnas, is one of the most fundamental tenets of good programming. If you hide information, you are free to change it without risking harm to the system. Information hiding decouples the components of the system, allowing them to be developed, tested, optimized, used, understood, and modified in isolation.

Item 15 tells you to keep the state space of each object as simple as possible. If an object is immutable, it can be in only one state, and you win big. You never have to worry about what state the object is in, and you can share it freely, with no need for synchronization. If you can't make an object immutable, at least minimize the amount of mutation that is possible. This makes it easier to use the object correctly.

As an extreme example of what not to do, consider the case of java.util.Calendar . Very few people understand its state-space -- I certainly don't -- and it's been a constant source of bugs for years.

So when should you break the rules? To paraphrase Orwell, you should break them when they'd result in code that is "outright barbarous." As a simple example, Item 25 says, "Prefer lists to arrays." So why does the values method present on every enum type return an array? Because the most common use of this method is to iterate over the elements of its return value, and it's much cheaper to iterate over an array than any List implementation. With the for-each construct, the code to iterate is the same either way:

You might think this was premature optimization on the part of the enum designers, but it wasn't. This isn't just inner loop code, it is the (inner) loop. Of course, we (the JSR 201 expert group) did extensive performance measurements before making this decision, and I'm satisfied that we made the right decision.

Another time that you should break the rules is when two of the rules would drive you to opposite decisions. In such cases, you're forced to violate at least one of the rules, and you have to choose which is more important, which can be very difficult.

When faced with such decisions, I typically discuss it with someone else for a sanity check. There's no shame in doing this, and it's arguably a best practice. Contrary to popular belief, software design is not -- or should not be -- a solitary occupation.

At first, this may seem like needless verbiage, but it's not. By telling the compiler what kind of elements the list contains, you enable it to find many errors at compile time that would otherwise cause a ClassCastException at runtime. You also eliminate ugly casts from your program.

For enums, the sound bite is "Always use enums in place of int constants" (Item 30). Enums provide so many advantages: compile-time type safety, the ability to add or remove values without breaking clients, meaningful printed values, the ability to associate methods and fields with the values, and so on. Since we have EnumSet, this advice applies equally to bit fields, which should be considered obsolete.

For annotations, the sound bite is "Don't define your own unless you have a very good reason, but do use the standard ones for your environment." For many programmers, the only ones that matter will be @Override (Item 36) and @SuppressWarnings (Item 24). Using the @Override annotation is an easy way to save yourself from errors that would otherwise be very hard to detect. Notably, it is not uncommon to accidentally overload the equals method when you intend to override it, causing subtle, pernicious errors:

This idiom is almost magical. There's synchronization going on, but it's invisible. The Java Runtime Environment does it for you, behind the scenes. And many VMs actually patch the code to eliminate the synchronization once it's no longer necessary, so this idiom is extremely fast.

If you need high-performance lazy initializing of an instance field, use the double-check idiom with a volatile field. This idiom wasn't guaranteed to work until release 5.0, when the platform got a new memory model. The idiom is very fast but also complicated and delicate, so don't be tempted to modify it in any way. Just copy and paste -- normally not a good idea, but appropriate here:

A: I'm proud that I was able to preserve the feel of the book, even as the language grew. One reason the first edition was so successful is that it was small and approachable. The addition of all the new language and library features made the platform larger and more complex. Inevitably, the book grew (from 57 items to 78), but I tried really hard to keep it short and clear. Based on early feedback, I think I was largely successful.

A: Ooh, good question... I'm going to say that the strangest thing about the Java platform is that the byte type is signed. I've never heard an explanation for this. It's quite counterintuitive and causes all sorts of errors. For example, what do you think this program does?

Q: Java Champion Dr. Heinz Kabutz finds that failure to unit test is a big problem among Java developers. He reports, "At conferences, I ask, 'How many of you have unit tests for your code?' Almost no one raises their hands -- and these are experienced professionals." Your reaction?

A: I'm really sorry to hear it. Unit tests are essential! If you don't have them, you don't know whether your code works. Having a good set of unit tests gives you much more confidence that your code works in the first place and that you don't introduce bugs as you maintain it. Inevitably, you will introduce bugs, but your unit tests will often let you find the bugs as soon as you introduce them, so you can fix them before they cause any damage.

b1e95dc632
Reply all
Reply to author
Forward
0 new messages