title: Java generics (template) specialization possible (overriding template types with specific types)
body: <p>I'm wondering what are the options to specialize generic types in Java, i.e. in a templated class to have specific overrides for certain types.</p>
  
  <p>In my case I was a generic class (of type T) to return null usually, but return "" (the empty string), when T is the String type, or 0 (zero) when its the Integer type, etc.</p>
  
  <p>Merely providing a type-specific overload of a method produces a "method is ambiguous" error:</p>
  
  <p>e.g.:</p>
  
  <pre><code>public class Hacking {
  
    public static void main(String[] args) {
      Bar&lt;Integer&gt; barInt = new Bar&lt;Integer&gt;();
      Bar&lt;String&gt; barString = new Bar&lt;String&gt;();
  
      // OK, returns null
      System.out.println(barInt.get(new Integer(4)));
  
      // ERROR: The method get(String) is ambiguous for the type Bar&lt;String&gt;
      System.out.println(barString.get(new String("foo")));
    }
  
    public static class Bar&lt;T&gt; {
  
      public T get(T x) {
        return null;
      }
  
      public String get(String x) {
        return "";
      }  
    }
  }
  </code></pre>
  
  <p>Is the only option to subclass the generic class with a specific type (see StringBar in the following example? </p>
  
  <pre><code>  public static void main(String[] args) {
      Bar&lt;Integer&gt; barInt = new Bar&lt;Integer&gt;();
      StringBar barString2 = new StringBar();
  
      // OK, returns null
      System.out.println(barInt.get());
  
      // OK, returns ""
      System.out.println(barString2.get());
    }
  
    public static class Bar&lt;T&gt; {
  
      public T get() {
        return null;
      }
    }
  
    public static class StringBar extends Bar&lt;String&gt; {
      public String get() {
        return "";
      }
    }
  }
  </code></pre>
  
  <p>Is this is the only way, it's a bit of a pain to have to create a subclass for every type I want to specialize instead of an overload of get() in the Bar class.</p>
  
  <p>I'm guessing I could check the instanceof in the Bar.get() method, e.g.
        T get(T t) {
           if (t instanceof String) return "";
           if (t instanceof Integer) return 0;
           else return null;
        }</p>
  
  <p>However I've been taught to avoid instanceof and use polymorphism when possible.</p>