Очевидные преимущества, такие как «безопасность типов» и «отсутствие кастинга», уже упоминались, поэтому, возможно, я могу рассказать о некоторых других «преимуществах», которые, я надеюсь, помогут.
Прежде всего, дженерики - это независимая от языка концепция, и, IMO, это может иметь больше смысла, если вы одновременно думаете о регулярном (во время выполнения) полиморфизме.
Например, полиморфизм, как мы знаем из объектно-ориентированного проектирования, имеет понятие времени выполнения, в котором объект вызывающего объекта определяется во время выполнения по мере выполнения программы, и соответствующий метод вызывается соответствующим образом в зависимости от типа времени выполнения. В общем, идея несколько похожа, но все происходит во время компиляции. Что это значит и как вы этим пользуетесь?
(Давайте придерживаться универсальных методов, чтобы сохранить его компактность) Это означает, что вы все еще можете использовать один и тот же метод в отдельных классах (как вы делали ранее в полиморфных классах), но на этот раз они автоматически генерируются компилятором, зависит от типы, установленные во время компиляции. Вы настраиваете ваши методы на тип, который вы даете во время компиляции. Таким образом, вместо того, чтобы писать методы с нуля для каждого типа , который есть у вас, как при полиморфизме во время выполнения (переопределение метода), вы позволяете компилятору выполнять работу во время компиляции. Это имеет очевидное преимущество, поскольку вам не нужно выводить все возможные типы, которые могут использоваться в вашей системе, что делает ее гораздо более масштабируемой без изменения кода.
Классы работают примерно так же. Вы параметризуете тип, и код генерируется компилятором.
Как только вы получите представление о «времени компиляции», вы можете использовать «ограниченные» типы и ограничивать то, что может передаваться как параметризованный тип через классы / методы. Таким образом, вы можете контролировать то, что будет проходить, что является мощной вещью, особенно если вы используете фреймворк для других людей.
public interface Foo<T extends MyObject> extends Hoo<T>{
...
}
Никто не может установить что-либо, кроме MyObject.
Кроме того, вы можете «навязывать» ограничения типа для аргументов вашего метода, что означает, что вы можете убедиться, что оба аргумента метода будут зависеть от одного и того же типа.
public <T extends MyObject> foo(T t1, T t2){
...
}
Надеюсь, все это имеет смысл.