Является ли S extends ArrayList of S полезной конструкцией языка или просто побочным эффектом грамматики?

Можно ли добавить к этому s1 что-нибудь кроме нуля? (и быть безопасно назначенным для temp )

Is

<S extends ArrayList<S>>

полезная конструкция в языке или просто побочный эффект грамматики? Правильно ли я интерпретирую S как ArrayList, который может содержать только объекты, которые являются ArrayLists из ArrayLists из ArrayLists и т. д.?

public class Foo{
    public static <S extends ArrayList<S>> void f1() {
        S s1 = (S) new ArrayList<S>();

        // s1.add( ???? );  // can anything be added here other than null?
        S temp = s1.get(0);
    }
}

person Gonen I    schedule 02.02.2017    source источник
comment
Возможно, проблема XY?   -  person Hovercraft Full Of Eels    schedule 03.02.2017
comment
Вы сказали Java, что S является подклассом ArrayList здесь: <S extends ArrayList<S>>   -  person Jason    schedule 03.02.2017
comment
Я не спрашиваю о том, на что знаю ответ, если вы это имеете в виду. Null - это все, что я нашел, что работает до сих пор. И я знаю, что рассказал Java, что такое S. Я имею в виду, кто технически предоставляет параметр, поскольку main не вызывается явно.   -  person Gonen I    schedule 03.02.2017
comment
Но что вы пытаетесь сделать? Вы спрашиваете из академического интереса или это проблема, которую вы пытаетесь решить?   -  person Hulk    schedule 03.02.2017
comment
Это было обнаружено в рамках отдельной задачи, а теперь просто любопытно. Теперь это не проблема, которую я пытаюсь решить. Циклическая ссылка была реальной, и это самая интересная часть здесь. Я не совсем понимаю, как к этому относится java.   -  person Gonen I    schedule 03.02.2017


Ответы (1)


Вы можете добавить к нему только s1 и null без приведения s1 или других объектов к S:

s1.add(s1);
s1.add(s1.get(0));

Вы не знаете никаких других объектов в области, которые удовлетворяют ограничению S extends ArrayList<S>, поскольку параметр типа S объявлен только в этой области. По этой причине считается плохой практикой определять параметр универсального типа для метода в случае, если вы не используете его более чем в одном месте в сигнатуре метода.

person Calculator    schedule 02.02.2017
comment
Интересно. Является ли эта конструкция S extends ArrayList‹S› полезной в любом случае или просто побочным эффектом грамматики? - person Gonen I; 03.02.2017
comment
@user889742 user889742 Существуют варианты использования - обычно не с коллекциями - больше вещей, подобных тем, которые обсуждаются в этом вопросе - Что ‹R расширяет TableRecord‹ R›› значит на Java? - person Hulk; 03.02.2017
comment
Насчет кастинга тоже неплохо. Уточню в вопросе. Очевидно, вы можете добавить к нему что угодно, поместив его в необработанную ссылку ArrayList. - person Gonen I; 03.02.2017
comment
@user889742 параметры саморекурсивного типа часто используются в параметризованных классах. Известный пример: Enum - person Calculator; 03.02.2017
comment
и я также могу добавить другие новые объекты типа ArrayList‹S› в s1, а не просто добавить s1 к самому себе. - person Gonen I; 03.02.2017
comment
@user889742 user889742 Нет, вы можете добавлять только объекты типа S. Вам нужно будет преобразовать новый ArrayList<S> в S, чтобы иметь возможность добавить его в s1. - person Calculator; 03.02.2017
comment
Верно, но в этом случае приведение правильное и будет поддерживаться во время поиска во время выполнения, поэтому я считаю его действительным. Обратите внимание, что именно так создается сам s1. Приведение там совершенно необходимо, но правильно. - person Gonen I; 03.02.2017