Общие сведения о дженериках Java. Условные обозначения типов

Наиболее часто используемые имена параметров типа:

E - Element (широко используется Framework коллекций Java)

K - Ключ

N - Число

T - Тип

V - Значение

S, U, V и т.д. - 2-й, 3-й, 4-й типы

Я, кажется, не совсем понимаю, что именно соответствует каждой букве. Я понимаю, что каждая буква представляет собой просто конвенцию, но что означает второй, третий и четвертый типы? Когда мне следует использовать что? На официальном веб-сайте он не дает дополнительной информации.

Ответы

Ответ 1

Некоторые примеры:

  • Map<K, V>: Карта обычно присваивает V для K eys. Это специальные типы типов, поэтому они используются здесь.
  • List<E>: список содержит E lements. Это соглашение, что они называются элементами. С другой стороны, T также будет приемлемым здесь.
  • Formatter<T>: форматтер может форматировать любой T ype. Это не элемент, ни ключ, ни значение, поэтому T является правильной буквой здесь.
  • Triplet<T, U, V>: триплет для произвольных типов. Поскольку определение типа ничего не знает о типах, которые будут заполнены позже, он использует только T для первого типа, за которым следуют следующие буквы в алфавитном порядке.

Ответ 2

Я настоятельно рекомендую более длинные имена, особенно если у вас есть несколько параметров типа.

public class MyMap<Key, Value> {...}

Если вы настаиваете на соглашении, вы можете добавить "Тип" в конец имени, например

public class MyMap<KeyType, ValueType> {...}

(Хотя я предпочитаю просто иметь имя без суффикса. Имя должно быть UpperCamelCase)

Ответ 3

Как вы знаете, буквы ничего не означают сами по себе и являются просто соглашениями, которые облегчают чтение кода. Бит "2-й, 3-й и 4-й типы" означает, что когда у вас есть параметризованный тип с несколькими аргументами, вы должны вызывать эти аргументы S, T, U, V и т.д. Например

class MyClass<S, T, U> {
}

- это класс с тремя параметрами типа.

Очевидно, вам не нужно использовать S, T и U. Если можно использовать более содержательное соглашение, вы должны сделать это, например

class Car<W, E, P> {
}

может быть классом автомобилей, параметризованным по типу колеса, двигателя и краски.

РЕДАКТИРОВАТЬ: Как указывал другой ответ, еще лучше:

class Car<WheelType, EngineType, PaintType> {
}

Ответ 4

Я, кажется, не совсем понимаю, что именно соответствует каждой букве. Я понимаю, что каждая буква представляет собой просто конвенцию, но что означает второй, третий и четвертый типы?

Причина, по которой вы не "понимаете, что именно соответствует каждой букве", заключается в том, что использование имен параметров типа одной буквы является неофициальным соглашением. Письма не имеют и не могут иметь фиксированных значений. Вы должны прочитать javadocs (и, если необходимо, код), чтобы выяснить, что означают буквы в контексте классов. В большинстве случаев существует какой-то смысл, предназначенный для автора кода. Просто объясните это.

Когда я должен использовать что?

Если вы следуете стандарту кодирования, который говорит что-то по этому вопросу, тогда сделайте то, что он говорит. В противном случае:

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

На официальном веб-сайте руководства он не дает дополнительной информации.

Это правильно.

"Официальный" документ руководства по стилю Java не обновлялся в течение ~ 10 лет. С одной стороны, стыдно, что Sun/Oracle больше не воспринимают формальные соглашения стилей как свою роль. С другой стороны, я могу понять, почему они этого не делают. (Для Sun нет "ценности", и потенциальное обострение для вовлеченных людей просто не стоит. Если вы были в одном из тех бессмысленных дебатов о "правильном" месте, чтобы положить фигурные скобки, пробелы и т.д., и дальше, и дальше, вы поймете, что я имею в виду.)

Ответ 5

Я обычно просто представляю общий тип, как если бы это было имя класса:

abstract class DAO<Entity, Id> {
   abstract Entity findById(Id id);
}

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

abstract class DAO<E, I> {
   abstract E findById(I id);
}

Если все остальное просто не подходит, просто назовите его, что это такое.