Effective Java (2nd Edition)

Author: Joshua Bloch
4.4
All Stack Overflow 213
This Year Stack Overflow 16
This Month Stack Overflow 1

Comments

by Jon Skeet   2019-01-13

I usually go with something like the implementation given in Josh Bloch's fabulous Effective Java. It's fast and creates a pretty good hash which is unlikely to cause collisions. Pick two different prime numbers, e.g. 17 and 23, and do:

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 17;
        // Suitable nullity checks etc, of course :)
        hash = hash * 23 + field1.GetHashCode();
        hash = hash * 23 + field2.GetHashCode();
        hash = hash * 23 + field3.GetHashCode();
        return hash;
    }
}

As noted in comments, you may find it's better to pick a large prime to multiply by instead. Apparently 486187739 is good... and although most examples I've seen with small numbers tend to use primes, there are at least similar algorithms where non-prime numbers are often used. In the not-quite-FNV example later, for example, I've used numbers which apparently work well - but the initial value isn't a prime. (The multiplication constant is prime though. I don't know quite how important that is.)

This is better than the common practice of XORing hashcodes for two main reasons. Suppose we have a type with two int fields:

XorHash(x, x) == XorHash(y, y) == 0 for all x, y
XorHash(x, y) == XorHash(y, x) for all x, y

By the way, the earlier algorithm is the one currently used by the C# compiler for anonymous types.

This page gives quite a few options. I think for most cases the above is "good enough" and it's incredibly easy to remember and get right. The FNV alternative is similarly simple, but uses different constants and XOR instead of ADD as a combining operation. It looks something like the code below, but the normal FNV algorithm operates on individual bytes, so this would require modifying to perform one iteration per byte, instead of per 32-bit hash value. FNV is also designed for variable lengths of data, whereas the way we're using it here is always for the same number of field values. Comments on this answer suggest that the code here doesn't actually work as well (in the sample case tested) as the addition approach above.

// Note: Not quite FNV!
public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = (int) 2166136261;
        // Suitable nullity checks etc, of course :)
        hash = (hash * 16777619) ^ field1.GetHashCode();
        hash = (hash * 16777619) ^ field2.GetHashCode();
        hash = (hash * 16777619) ^ field3.GetHashCode();
        return hash;
    }
}

Note that one thing to be aware of is that ideally you should prevent your equality-sensitive (and thus hashcode-sensitive) state from changing after adding it to a collection that depends on the hash code.

As per the documentation:

You can override GetHashCode for immutable reference types. In general, for mutable reference types, you should override GetHashCode only if:

  • You can compute the hash code from fields that are not mutable; or
  • You can ensure that the hash code of a mutable object does not change while the object is contained in a collection that relies on its hash code.
by anonymous   2019-01-13

It is a common naming convention used for static factory methods.

Joshua Bloch mentions the following about the pattern and associated naming conventions in Effective Java (2nd Edition), Item 1: Consider static factory methods instead of constructors (emphasis added):

... (a) disadvantage of static factory methods is that they are not readily distinguishable from other static methods. They do not stand out in API documentation in the way that constructors do, so it can be difficult to figure out how to instantiate a class that provides static factory methods instead of constructors. The Javadoc tool may someday draw attention to static factory methods. In the meantime, you can reduce this disadvantage by drawing attention to static factories in class or interface comments, and by adhering to common naming conventions. Here are some common names for static factory methods:

  • valueOf—Returns an instance that has, loosely speaking, the same value as its parameters. Such static factories are effectively type-conversion methods.

  • of—A concise alternative to valueOf, popularized by EnumSet (Item 32).

...

So, as others have pointed out, "of" means the English word "of", and is not an abbreviation. But one of the reasons for using this convention is to make it easier to find out if a class provides a factory method because static factories don't show in a separate section in the JavaDocs (compared to constructors).

An added benefit, in my opinion, with using concisely and desciptively named static factories, is that it makes the code read like prose, which isn't the case if it's littered with new constructor calls.

by anonymous   2019-01-13

On the left hand side you're declaring the type of the variable, lst. Since lst's type is List you can only access methods of a List, even if the object lst points to is really a LinkedList. There's an inherent tradeoff between declaring a variable of a concrete type like LinkedList (access to more methods / behavior) vs. a more abstract interface (safer, better compartmentalized code).

This is a big topic, and there isn't one simple answer for when to do one vs. the other (though there's lots of advice out there about it!) - you'll need to figure out which is appropriate for your use case.

Effective Java - Item 52: Refer to objects by their interfaces is a pretty canonical citation for this issue, and as the title implies suggest preferring List rather than LinkedList.

by anonymous   2019-01-13

only let classes implement Serializable that have to be passed by value over the network.

Your professor is suggesting you minimize your use of Serializable to areas where it's strictly needed.

This is because serialization is a strong candidate for leaking implementation. Implementing Serializable shows intent of serialization (even if the object is never actually serialized), which imposes the idea that developers should take caution when modifying those classes to avoid breaking software.


Joshua Bloch covers this in his book Effective Java.

The moment you serialize an object, the class that it was instantiated from can no longer be modified without special treatment. If you modify the class, the binary representation will no longer match the objects already serialized. Thus deserialization of any objects serialized before modifying the class will fail.

If a type implements Serializable, it has the potential to be serialized. If an instance of that type was serialized, you may break code by modifying it's implementation.

Since there's no easy way of knowing for sure that an instance of a serializable type has been serialized (albeit you may not intend for objects to be serialized), developers take strong caution when modifying implementations of those types.


- This could be avoided by properly versioning your serializable types, but due to the potential of versioning a type that had no contract change (with no compile time error handling support to notify you), it's best to keep explicit versioning minimal to avoid adding excess complexity to your design.

by anonymous   2019-01-13

In Joshua Bloch's Effective Java, Item 5: "Avoid creating unnecessary objects", he posts the following code example:

public static void main(String[] args) {
    Long sum = 0L; // uses Long, not long
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}

and it takes 43 seconds to run. Taking the Long into the primitive brings it down to 6.8 seconds... If that's any indication why we use primitives.

The lack of native value equality is also a concern (.equals() is fairly verbose compared to ==)

for biziclop:

class Biziclop {

    public static void main(String[] args) {
        System.out.println(new Integer(5) == new Integer(5));
        System.out.println(new Integer(500) == new Integer(500));

        System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
        System.out.println(Integer.valueOf(500) == Integer.valueOf(500));
    }
}

Results in:

false
false
true
false

EDIT Why does (3) return true and (4) return false?

Because they are two different objects. The 256 integers closest to zero [-128; 127] are cached by the JVM, so they return the same object for those. Beyond that range, though, they aren't cached, so a new object is created. To make things more complicated, the JLS demands that at least 256 flyweights be cached. JVM implementers may add more if they desire, meaning this could run on a system where the nearest 1024 are cached and all of them return true... #awkward

by anonymous   2019-01-13

It is very true.

Because setters are always public methods. And if you class is not final then there is issue of alien method call. Which is not thread safe i.e. it is known as escaping of this reference. So from a constructor if you are calling a method it should be final or private. Else safe initialization of object will not happen which causes many bugs in real systems.

Apart from the above we should never call public method from the constructor because if the class is intended for inheritance than Constructors must not invoke overridable methods, directly or indirectly.

If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.

source.

by cletus   2019-01-13

You're not trying to implement Joshua Bloch's typesafe hetereogeneous container pattern are you? Basically:

public class Favorites {
  private Map<Class<?>, Object> favorites =
    new HashMap<Class<?>, Object>();

  public <T> void setFavorite(Class<T> klass, T thing) {
    favorites.put(klass, thing);
  }

  public <T> T getFavorite(Class<T> klass) {
    return klass.cast(favorites.get(klass));
  }

  public static void main(String[] args) {
    Favorites f = new Favorites();
    f.setFavorite(String.class, "Java");
    f.setFavorite(Integer.class, 0xcafebabe);
    String s = f.getFavorite(String.class);
    int i = f.getFavorite(Integer.class);
  }
}

From Effective Java (2nd edition) and this presentation.

by anonymous   2018-03-19

I would say both NumberFormatException and MyBusinessException are useful but in different cases.

They usually appear at different levels of class hierarchy: for example NumberFormatException is a lower-level exception and you might not want to expose it at a higher level (e.g. user interface) if the user of it has no power to recover from it. In this case it is more elegant to just throw MyBusinessException and display an informative message that explains for example that something in a previous step was badly supplied or some internal processing error occurred and he/she needs to restart the process.

On the other hand, if your function is used at an intermediate-level (e.g. API) and the developer has the means to recover from the exceptional behavior, NumberFormatException is more useful, as it can be dealt with programmatically and the flow of the application might continue with minimal interruption (e.g. supply a default valid number). Alternatively, this can indicate a flaw/bug in the code that should be fixed.

For details about how to follow best practice in using exceptions, read Item 61 - Throw exceptions appropriate to the abstraction from Effective Java by Joshua Bloch.

by anonymous   2018-03-19

The book Effective Java gives two more reasons for "memory leaks":

  • Once you put object reference in Cache and forget that it's there. The reference remains in cache long before becoming irrelevant. Solution is to represent cache as a WeakHashMap
  • in an API where clients register callbacks and don't re-register them explicitly. Solution is to store only weak references to them.
by anonymous   2017-08-20

The best approach is Long.valueOf(str) as it relies on Long.valueOf(long) which uses an internal cache making it more efficient since it will reuse if needed the cached instances of Long going from -128 to 127 included.

Returns a Long instance representing the specified long value. If a new Long instance is not required, this method should generally be used in preference to the constructor Long(long), as this method is likely to yield significantly better space and time performance by caching frequently requested values. Note that unlike the corresponding method in the Integer class, this method is not required to cache values within a particular range.

Generally speaking, it is a good practice to use the static factory method valueOf(str) of a wrapper class like Integer, Boolean, Long, ... since most of them reuse instances whenever it is possible making them potentially more efficient in term of memory footprint than the corresponding parse methods or constructors.


Excerpt from Effective Java Item 1 written by Joshua Bloch:

You can often avoid creating unnecessary objects by using static factory methods (Item 1) in preference to constructors on immutable classes that provide both. For example, the static factory method Boolean.valueOf(String) is almost always preferable to the constructor Boolean(String). The constructor creates a new object each time it’s called, while the static factory method is never required to do so and won’t in practice.

by anonymous   2017-08-20

You should probably use String.hashCode().

If you really want to implement hashCode yourself:

Do not be tempted to exclude significant parts of an object from the hash code computation to improve performance -- Joshua Bloch, Effective Java

Using only the first five characters is a bad idea. Think about hierarchical names, such as URLs: they will all have the same hash code (because they all start with "http://", which means that they are stored under the same bucket in a hash map, exhibiting terrible performance.

Here's a war story paraphrased on the String hashCode from "Effective Java":

The String hash function implemented in all releases prior to 1.2 examined at most sixteen characters, evenly spaced throughout the string, starting with the first character. For large collections of hierarchical names, such as URLs, this hash function displayed terrible behavior.

by anonymous   2017-08-20

It's extremely bad practice to let equals() or hashCode() throw exceptions (I'd encourage you to read Effective Java for the details).

Also, your methods are unnecessarily complex. Ever since Java 7, this is pretty much the canonical way of writing these methods:

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }else if (o instanceof MyClass) {
        // some will argue that the line above should have a
        // .getClass() check instead of an instanceof check.
        // those people also need to read Effective Java :-)
        MyClass that = (MyClass) o;
        return Objects.equals(this.classA, that.classA)
            && Objects.equals(this.classB, that.classB)
    } else {
        return false;
    } 
}

@Override
public int hashCode() {
    return Objects.hash(classA, classB);
}
by anonymous   2017-08-20

1. What you should be more concerned with here, is not efficiency, but scope. Generally, you should strive to keep your variables as locally scoped as possible. This means, if you only need x within the loop, you should define it within the loop.

You get a number of benefits with keeping your variables as locally scoped as possible:

  • Your code will be much more readable to someone else
  • You won't accidentally assign to, or use the value of a variable you defined further up in your code that is still in scope, thus minimizing errors in your program
  • Most importantly, the garbage collector will free up any memory used by the variable as soon as it goes out of scope, keeping your program's performance high, and memory usage low.

You can read up more on variable scope and best practices from Josh Bloch's excellent book, "Effective Java" (scope is discussed in items 13 and 45). You might also want to read item 55, which discusses why it is important to optimize judiciously.

2. For the second part of your question, see The Skeet's answer here.

Here's an example:

public static void main(String[] args) {
    for(int i=0; i<getSize(); i++) {
        System.out.println("i: " + i);
    }
}

private static int getSize() {
    int size = new Random().nextInt(10);
    System.out.println("size: " + size);
    return size;
}

This outputs:

size: 2
i: 0
size: 4
i: 1
size: 4
i: 2
size: 8
i: 3
size: 0

Notice how getSize() is called for every iteration of the loop. In your example, calling .length won't make a huge difference, as the JIT runtime will know how to optimize this call. But imagine getSize() was a more complex operation, like counting the number of rows in a database table. Your code will be super slow as every iteration of the loop will call getSize(), resulting in a database roundtrip.

This is when you would be better off evaluating the value before hand. You can do this and still retain minimal scope for size, like this:

public static void main(String[] args) {
    for(int size = getSize(), i=0; i<size; i++) {
        System.out.println("i: " + i);
    }
}


private static int getSize() {
    int size = new Random().nextInt(10);
    System.out.println("size: " + size);
    return size;
}

size: 5
i: 0
i: 1
i: 2
i: 3
i: 4

Notice how getSize() is only called once, and also, the size variable is only available inside the loop and goes out of scope as soon as the loop completes.

by anonymous   2017-08-20

In recent years, inheritance is often treated like code-smell, because it can lead to different problems: https://dzone.com/articles/is-inheritance-dead

If we talk in pure performance term, an empty array takes about 8 bytes in RAM (4 bytes store length and 4 bytes a reference, but it is a little platform-dependent: How much space array occupies). So, even if you have a thousand of such objects, one array field will take approximately 1_000 * 8 bytes ~ 8 KBytes in RAM.

As you probably know, nowadays phones usually contain > 1 GByte of RAM. However, don't forget that your app usually can take from 60 to 192 MBytes of RAM (Detect application heap size in Android).

In any case, it is more than enough not to count every little field that you are adding to your class.

However, going back to my first statement, I suggest you to think about solving the problem using composition instead of inheritance, as it is suggested in Effective Java

Update
About performance, I would suggest you to read this topic: The performance impact of using instanceof in Java Are you sure that you need such type of premature optimization? Or is it more a theoretical question than practical?

by anonymous   2017-08-20

If you throw exceptions that are too low-level catch them few calls above, and pack as more general and meaningful exception with user friendly message what went wrong, and throw them once again to highest possible level, where you stop your app and view them somehow (e.g. on label) to user.

from Effective Java (item 61):

It is disconcerting when a method throws an exception that has no apparent connection to the task that it performs. This often happens when a method propagates an exception thrown by a lower-level abstraction. Not only is this disconcerting, but it pollutes the API of the higher layer with implementation details. If the implementation of the higher layer changes in a subsequent release, the exceptions that it throws will change too, potentially breaking existing client programs.

To avoid this problem, higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction. This idiom is known as exception translation:

// Exception Translation
try {
   // Use lower-level abstraction to do our bidding
   ...
} catch(LowerLevelException e) {
   throw new HigherLevelException(...);
}

While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused. Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. Sometimes you can do this by checking the validity of the higher-level method’s parameters before passing them on to lower layers.

If it is impossible to prevent exceptions from lower layers, the next best thing is to have the higher layer silently work around these exceptions, insulating the caller of the higher-level method from lower-level problems. Under these circumstances, it may be appropriate to log the exception using some appropriate logging facility such as java.util.logging. This allows an administrator to investigate the problem, while insulating the client code and the end user from it.

In summary, if it isn’t feasible to prevent or to handle exceptions from lower layers, use exception translation, unless the lower-level method happens to guarantee that all of its exceptions are appropriate to the higher level. Chaining provides the best of both worlds: it allows you to throw an appropriate higher-level exception, while capturing the underlying cause for failure analysis (Item 63).

by anonymous   2017-08-20

The use of try/catch blocks in normal program flow incurs a performance hit. It's better to use the if/then statements in the first example.

https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why

This is mentioned in Effective Java. Exceptions are, as their name implies, to be used only for exceptional conditions; they should never be used for ordinary control flow.

by anonymous   2017-08-20

As far as I can tell there is nothing special here, is just classical constructor chaining and polymorphism applied to virtual method invocations.

When you instantiate your anonymous class, it will automatically invoke its default constructor (which is automatically given by the compiler), before its default constructor succeeds it must first invoke its parent class default constructor, which in turn will invoke the init() method, which, since it has been overridden by your anonymous class, polymorphically, ends up calling the init method in the child class, which initializes the model to your SubModel instance.

Joshua Bloch has a few interesting arguments against this pattern in his famous book Effective Java, in the section "Item 17: Design and document for inheritance or else prohibit" he wrote:

“There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will get invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected. To make this concrete, here's a class that violates this rule:”

He then proceeds to give an example which you would do well to study:

“Here's a subclass that overrides the overrideMe, method which is erroneously invoked by Super's sole constructor:”

public class Super {
    // Broken - constructor invokes an overridable method
    public Super() {
        overrideMe();
    }

    public void overrideMe() {
    }
}

public final class Sub extends Super {
    private final Date date; // Blank final, set by constructor

    Sub() {
        date = new Date();
    }

    // Overriding method invoked by superclass constructor
    @Override public void overrideMe() {
        System.out.println(date);
    }

    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.overrideMe();
    }
}

“You might expect this program to print out the date twice, but it prints out null the first time, because the overrideMe method is invoked by the Super constructor before the Sub constructor has a chance to initialize the date field. Note that this program observes a final field in two different states! Note also that if overrideMe had invoked any method on date, the invocation would have thrown a NullPointerException when the Super constructor invoked overrideMe. The only reason this program doesn't throw a NullPointerException as it stands is that the println method has special provisions for dealing with a null argument.”

So, as you can see, and as Joshua Bloch explained so well, the risks lurk in the shadows: in the possibilities of what you can do in the overridden method, where you have license to touch instance variables that the constructor chain has not yet had a chance to initialize. The point is that you should not be allowed to touch the object state until it has been fully initialized by the constructor chain.

You might say that in your particular case that does not happen, since you are not illegally altering state and your overridden method is protected, not public, but the problem is that any person touching this code needs a very clear understanding of all these things happening under the hood, happening in places other than your current code. During maintenance it is easy to make a serious mistake, particularly when you or some other developer, comes back here to make changes, possibly months or even years after this was originally defined, and having lost context of all these dangers somebody introduces a bug that will be really hard to find and fix.

by anonymous   2017-08-20

clone() was designed with several mistakes (see this question), so it's best to avoid it.

From Effective Java 2nd Edition, Item 11: Override clone judiciously

Given all of the problems associated with Cloneable, it’s safe to say that other interfaces should not extend it, and that classes designed for inheritance (Item 17) should not implement it. Because of its many shortcomings, some expert programmers simply choose never to override the clone method and never to invoke it except, perhaps, to copy arrays. If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.

This book also describes the many advantages copy constructors have over Cloneable/clone.

  • They don't rely on a risk-prone extralinguistic object creation mechanism
  • They don't demand unenforceable adherence to thinly documented conventions
  • They don't conflict with the proper use of final fields
  • They don't throw unnecessary checked exceptions
  • They don't require casts.

All standard collections have copy constructors. Use them.

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
by anonymous   2017-08-20

Assert will throw a runtime error (AssertionError) if its condition is false. Asserts give you a streamlined way of documenting, checking, and enforcing correctness criteria for your code. The benefits are a language-level hook for defining and manipulating these correctness conditions. To the extent that you wish to enable or disable them (there are arguments about whether or not this is a good idea) you can do so from the JVM command-line. Some commenters below note that assertions are disabled by default unless running in debug mode; my practice is to add "-ea" (enable assertions) in my wrapper scripts at all times. Even in performance sensitive code, for me the tradeoff weighs in favor of the security/correctness confidence I get from assertions. Assertions at Oracle and API Description for AssertionError

Note the distinction between expected or unexpected failures (exceptions), which may be outside your control, and assertion failures -- assertion failures document programmer assumptions, and indicate an incorrect program rather than an unexpected external condition or expected exceptional condition. If an assertion failure occurs, the interpretation is that the programmer has misunderstood or incorrectly expressed the program, rather than other sources of error or failure.

In practice, I use it to document obvious or non-obvious assumptions I make and invariants which I want to enforce as I produce (particularly private/internal) code, making it clear to myself and others why these assumptions are made, where they are made, and whether or not they are validated. Much better than comments to the same effect. This is a (small) step toward Design by Contract.

Effective Java item #38 "Check Parameters for Validity" (Google Books, Amazon.com) provides a useful presentation of the distinction between parameter checking and appropriate use of assertions.

Related on SO: (Enabling assertions in netbeans), (Assertions vs. Exceptions), (Near duplicate, asking for examples), (Badly named, but very similar content)

by anonymous   2017-08-20

The term utility function was used by Joshua Bloch in the book Effective Java to describe the methods on classes such as Arrays, Objects and Math.

The approach predates Java, and is defined by Wikipedia - Utility Class as a set of methods that perform common, often reused functions. I would go on to also point out that the functions tend to require no Object level state, that is they tend to be global functions. And that is why, in Java they tend to become implemented as static methods on a container class. As that way there is no need to instantiate the class first, and it implies through convention that the method should not have any side effects. Of course counter examples of this probably exist, but not to my knowledge within the Java Core libraries.