Search code examples
javagenericstype-inferencenested-generics

Can java infer the generic type from a class defined on top of generics?


I've borrowed the code from this other answer

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

My question has to do with this piece of code

    ConverterUser<IntToStringConverter, Integer, String> converterUser =
        new ConverterUser<IntToStringConverter, Integer, String>();

As IntToStringConverter is implementing IConverter<Integer, String> , Integer and String type are known, doesn't java have an inference system to avoid typing new ConverterUser<IntToStringConverter, Integer, String>() and type just new ConverterUser<IntToStringConverter>() ?


Solution

  • No.

    In the ConverterUser class definition, the TFrom and TTo type parameters have be to introduced somewhere, so that they are used in the TConverter extends IConverter<TFrom, TTo> type definition.

    This is why the ConverterUser results with three type parameters.

    Note that you can still get rid of the second and the third type parameters, but only if you define the first one to be exactly a sub-type of IntToStringConverter. However, I wouldn't advice you to do so, because this way the ConverterUser class will be doomed to convert only from Integer to String:

    class ConverterUser<TConverter extends IntToStringConverter> {
        public ConverterUser() { ... }
    
        private TConverter _converter;
    
        public String convert(Integer from)
        {
            return _converter.convert(from);
        }
    }