Search code examples
javaeffective-java

Are raw types always bad?


Item 23 ( Don't use raw types in new code ) of Effective Java claims that using raw types in java code is always dangerous

For instance, it claims that the following method is dangerous and unsafe

// Use of raw type for unknown element type - don't do this!
static int numElementsInCommon(Set s1, Set s2) {
    int result = 0;
    for (Object o1 : s1)
        if (s2.contains(o1))
            result++;
    return result;
}

Although, I can see that doing any kind of write operation or class cast operation on s1 and s2 can lead to all kinds of exceptions, I dont understand why the above method is unsafe. Author Joshua Bloch goes on to recommend the following method instead.

// Unbounded wildcard type - typesafe and flexible
static int numElementsInCommon(Set<?> s1, Set<?> s2){
  int result = 0;
  for (Object o1 : s1)
    if (s2.contains(o1))
        result++;
  return result;
}

In other words, if a method only uses the methods of Object.Class and does not do any modifications to the parameters that are passed, why is it bad?


Solution

  • It is bad in the sense that it prevents the compiler from type-checking more of your code.

    Of course you can write good and safe code without it. People do it in Perl and Javascript every day. And even in Java, there is no difference between using raw types and using typed collections at runtime. But there is something to be said for having a compiler check as much as possible for you.

    So, with a method like in your example, use wildcard types (Set<?>) instead of raw types. That way, if you do write "dangerous" code like s1.addAll(s2); the compiler will shout at you.