2

What's the use of generic in Callable interface?

Consider this code which I copied from https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6:

import java.util.\*;
import java.util.concurrent.\*;

public class CallableExample {

  public static class WordLengthCallable
        implements Callable {
    private String word;
    public WordLengthCallable(String word) {
      this.word = word;
    }
    public Integer call() {
      return Integer.valueOf(word.length());
    }
  }

  public static void main(String args[]) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<Integer>> set = new HashSet<Future<Integer>>();
    for (String word: args) {
      Callable<Integer> callable = new WordLengthCallable(word);
      Future<Integer> future = pool.submit(callable);
      set.add(future);
    }
    int sum = 0;
    for (Future<Integer> future : set) {
      sum += future.get();
    }
    System.out.printf("The sum of lengths is %s%n", sum);
    System.exit(sum);
  }
}

Integer in Callable<Integer> and Future<Integer> is not being used. It could be anything else as well like Callable<String> and Future<String> and code will still work.

I understand usage of Generics and appreciates its usage specially in collections.

Thanks.

1
  • 2
    It's so that get will return an Integer rather than an Object, or am I wrong? Commented Aug 6, 2014 at 20:36

2 Answers 2

6

The point of Callable vs Runnable is the ability in Callable to return a value (retrievable via Future if using an ExecutorService). They could have coded it to just return Object and make the code cast but then there would be absolutely no compile-time checking. Seems logical to make Callable generic to specify the return type so that you don't need the explicit cast and you have compile-time checking.

Of course, due to type-erasure this all goes away at run-time but that does not reduce its value WRT intent and compile-time.

4
  • And, the fact it avoid you to catch checked exceptions Commented Aug 6, 2014 at 20:38
  • My bad, it's same logic as it's in collections, somehow I was not able to understand it before. Thanks for answering. Commented Aug 6, 2014 at 21:05
  • So why does Runnable also carry generics? Commented Dec 6, 2020 at 22:29
  • @BasilBourque Runnable is not generic. Notice that in the java doc it is Runnable not Runnable<T>. As comparison Callable
    – John B
    Commented Dec 8, 2020 at 14:27
3

John has a given a correct answer. Just adding the importance of not ignoring compiler warnings. While compiling your current code the compiler warns you for unchecked conversion.

$ javac -Xlint:unchecked CallableExample.java
CallableExample.java:22: warning: [unchecked] unchecked conversion
found   : CallableExample.WordLengthCallable
required: java.util.concurrent.Callable<java.lang.Integer>
            Callable<Integer> callable = new WordLengthCallable(word);
                                         ^
1 warning

Integer in Callable<Integer> and Future<Integer> is not being used. It could be anything else as well like Callable<String> and Future<String> and code will still work.

Change your class to use implements Callable<Integer>

The compiler becomes happy and your code won't work if you start using Callable<String> and Future<String> everywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.