Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics (template) specialization possible (overriding template types with specific types)

Tags:

java

generics

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.

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.

Merely providing a type-specific overload of a method produces a "method is ambiguous" error:

e.g.:

public class Hacking {    public static void main(String[] args) {     Bar<Integer> barInt = new Bar<Integer>();     Bar<String> barString = new Bar<String>();      // OK, returns null     System.out.println(barInt.get(new Integer(4)));      // ERROR: The method get(String) is ambiguous for the type Bar<String>     System.out.println(barString.get(new String("foo")));   }    public static class Bar<T> {      public T get(T x) {       return null;     }      public String get(String x) {       return "";     }     } } 

Is the only option to subclass the generic class with a specific type (see StringBar in the following example?

  public static void main(String[] args) {     Bar<Integer> barInt = new Bar<Integer>();     StringBar barString2 = new StringBar();      // OK, returns null     System.out.println(barInt.get());      // OK, returns ""     System.out.println(barString2.get());   }    public static class Bar<T> {      public T get() {       return null;     }   }    public static class StringBar extends Bar<String> {     public String get() {       return "";     }   } } 

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.

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; }

However I've been taught to avoid instanceof and use polymorphism when possible.

like image 866
Ash Avatar asked Oct 21 '10 13:10

Ash


People also ask

What is the difference between generics and templates?

Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.

What is generic template in Java?

Generics in Java are similar to templates in C++. For example, classes like HashSet, ArrayList, HashMap, etc., use generics very well. There are some fundamental differences between the two approaches to generic types.

What are generics which are the differences between Java generics and C++ templates?

A C++ template gets reproduced and re-compiled entirely whenever a template is instantiated with a new class. The main difference is that Java generics are encapsulated. The errors are flagged when they occur and not later when the corresponding classes are used/instantiated.

Which types can be used as arguments of generics?

The actual type arguments of a generic type are. reference types, wildcards, or. parameterized types (i.e. instantiations of other generic types).


1 Answers

All things considered, the concensus appears to be that the StringBar method mentioned in the question is the only way to go.

  public static class StringBar extends Bar<String> {     public String get() {       return "";     }   } 
like image 51
Ash Avatar answered Sep 20 '22 03:09

Ash