Can I use nested generics (aka higher kinded types) in Java?
I was trying to do something like:
public class MyClass <A, B, C <A, B> > {
...
}
But Eclipse highlights "B," and says "unexpected , expected extends". What gives? Are nested generics not allowed?
It's because you haven't defined C
as a type that is itself typed with 2 type parameters.
Try something like this:
public class MyClass <A, B, C extends Map<A, B>> {
// This compiles
}
If your template parameters don't share share a class hierarchy, you can use an interface.
For example:
interface IConverter<TFrom, TTo>
{
TTo convert(TFrom from);
}
class IntToStringConverter implements IConverter<Integer, String>
{
public String convert(Integer from)
{
return "This is a string: " + from.toString();
}
}
class ConverterUser<TConverter extends IConverter<TFrom, TTo>, TFrom, TTo>
{
public ConverterUser()
{
}
private List<TConverter> _converter2;
private TConverter _converter;
public void replaceConverter(TConverter converter)
{
_converter = converter;
}
public TTo convert(TFrom from)
{
return _converter.convert(from);
}
}
class Test
{
public static void main(String[] args)
{
ConverterUser<IntToStringConverter, Integer, String> converterUser =
new ConverterUser<IntToStringConverter, Integer, String>();
converterUser.replaceConverter(new IntToStringConverter());
System.out.println(converterUser.convert(328));
}
}
This is not possible in Java. See the Type Variables section of the language definition along with Generic Classes and Type Parameters. I recently saw (somewhere) a mention that Java is incapable of this but Scala can do it. This is confirmed by S4.4 of the Scala Language Specification.
This is also somewhat confirmed by the following code compiling successfully.
class MyClass [A, B, C [A, B]] {
}
Compiling in java yielded the follwing answers.
MyClass.java:1: > expected
class MyClass <A, B, C<A, B>> {
^
MyClass.java:1: <identifier> expected
class MyClass <A, B, C<A, B>> {
^
MyClass.java:1: ';' expected
class MyClass <A, B, C<A, B>> {
^
MyClass.java:2: reached end of file while parsing
}
^
4 errors
I would guess that there is an easier solution to your problem however, as this is somewhat unusual.
You don't have to declare nested types like that. Simply
class MyClass<A, B, C> {}
And when you create a MyClass, you could do something like
MyClass<List<String>, Set<Date>, Map<Integer, Long>> instance;