Общие сведения о дженериках 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);
}
Если все остальное просто не подходит, просто назовите его, что это такое.