Подтвердить что ты не робот

Могу ли я использовать вложенные дженерики в Java?

Я пытался сделать что-то вроде:


public class MyClass <A, B, C <A, B> > {
  ...
}

Но Eclipse выделяет "B" и говорит "неожиданные, ожидаемые расширения". Что дает? Не разрешены ли вложенные дженерики?

4b9b3361

Ответ 1

Это потому, что вы не определили C как тип, который сам вводится с параметрами типа 2.
Попробуйте что-то вроде этого:

public class MyClass <A, B, C extends Map<A, B>> {
    // This compiles
}

Ответ 2

Если ваши параметры шаблона не разделяют общую иерархию классов, вы можете использовать интерфейс.

Например:

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

Ответ 3

Это невозможно в Java. См. Раздел Тип переменных в определении языка наряду с Общие классы и параметры типа. Недавно я заметил (где-то) упоминание о том, что Java неспособен на это, но Scala может это сделать. Это подтверждается S4.4 Scala Спецификация языка.

Это также несколько подтверждается успешной компиляцией кода.

class MyClass [A, B, C [A, B]] {
}

Компиляция в java дала ответные ответы.

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

Я бы предположил, что есть более легкое решение вашей проблемы, поскольку это несколько необычно.

Ответ 4

Вам не нужно объявлять такие вложенные типы. Просто

class MyClass<A, B, C> {}

И когда вы создаете MyClass, вы можете сделать что-то вроде

MyClass<List<String>, Set<Date>, Map<Integer, Long>> instance;

Ответ 5

Я предполагаю, что вы хотите, чтобы MyClass был родовым классом с параметрами типа A, B и C. Кроме того, вы хотите, чтобы C был универсальным классом с параметрами типа A и B.

Чтобы я мог написать

  • MyClass < String , Date , Map < String , Date > >
  • MyClass < String , Date , Hashtable < String , Date > > но не
  • MyClass < String , Date , ElementVsitor < Date , String > >

Тогда я не думаю, что вы можете это сделать.