Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I restrict accepting only one type in my generic method?

I have a generic function foo, which accepts any type and prints them out.

public static <T> T foo(T... arg) {
    List<T> foo = Arrays.asList(arg);
    for (T t : foo) {
      System.out.println(t);
    }
    return null;
  }

How do I make sure that the arguments received are of only 1 type. For example, {1,'a',3} should be invalid. It should either be all numbers or all characters. I want to accept either ALL integers or ALL Characters.

like image 927
unj2 Avatar asked May 13 '10 04:05

unj2


1 Answers

You can in fact do something like this:

static <T extends Comparable<T>> void f(T... args) {
    System.out.println(java.util.Arrays.toString(args));
}
public static void main(String[] args) {
    // all one type -- all of these compile!
    f(1, 2, 3); // prints "[1, 2, 3]"
    f('a', 'b', 'c'); // prints "[a, b, c]"
    f("a", "b", "c"); // prints "[a, b, c]"
    f(1D, 2D, 3D); // prints "[1.0, 2.0, 3.0]"

    // this is not preventable
    f(1, (int)'a', 3); // prints "[1, 97, 3]"

    // mixture of types -- none of these compile!
    //f(1, 'a', 3); // compilation error!
    //f(1, '2', "3"); // compilation error!
    //f("a", "b", 'c'); // compilation error!
    //f(1, 2, 3D); // compilation error!
}

This takes advantage of the fact that:

  • Integer implements Comparable<Integer>
  • Character implements Comparable<Character>
  • String implements Comparable<String>
  • Double implements Comparable<Double>

So to match those types (and possibly others), we bound T as follows:

  • T extends Comparable<T>

This does include things e.g. java.util.Date, which implements Comparable<Date>, and countless many other types, but is probably the best that you can do if you also want to allow Integer and Character.


Nonetheless, do keep in mind that Integer, Character, String, are all Object, so in fact a bunch of those mixed together IS a list of one type: Object.

Thankfully, it's NOT the case that Object implements Comparable<Object>; otherwise the above solution wouldn't work.

like image 146
polygenelubricants Avatar answered Sep 29 '22 16:09

polygenelubricants