Дженерики Java: список, список <объект>, список <?>

Для этого вы можете использовать метод Extent из MagickImage. Ниже приведен пример того, как вы могли бы сделать это.

public bool AddPadding(string filePath)
{
    // Read from file
    using (MagickImage image = new MagickImage(filePath))
    {
        int imageSize = Math.Max(image.Width, image.Height);

        // Add padding
        image.Extent(imageSize, imageSize, Gravity.Center, MagickColors.Purple);

        // Save the result
        image.Write(filePath);
    }
}

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

70
задан H. Pauwelyn 25 January 2017 в 18:35
поделиться

8 ответов

Как другие сообщения отметили, Вы спрашиваете о функции Java, названной дженериками. В C++ это называют шаблонами. Эта функция в Java обычно легче работать с тем, чем это нашло в C++.

Позволяют мне ответить на Ваши вопросы функционально (если это не непослушное слово для обсуждений OO).

Перед дженериками, были реальные классы как Вектор.

Vector V = new Vector();

Векторы содержат любой объект, который Вы даете им.

V.add("This is an element");
V.add(new Integer(2));
v.add(new Hashtable());

Они делают это путем кастинга всех значений, данных ему в Объект (корень всех классов Java). Когда Вы пытаетесь получить значения, сохраненные в Вашем Векторе, необходимо бросить значение назад в исходный класс (если Вы хотите сделать что-либо значимое с ним).

String s = (String) v.get(0);
Integer i = (Integer) v.get(1);
Hashtable h = (Hashtable) v.get(2);

Кастинг становится старым быстро. Больше, чем это, компилятор жалуется Вам о бросках непроверенных. Самая срочная проблема с кастингом как это состоит в том, что потребители Вашего Вектора должны знать классы его значений в [1 112] время компиляции для кастинга правильно. В случаях, где производитель Вектора и потребитель того же полностью изолируются друг от друга (думают сообщения RPC), это может быть фатальной проблемой.

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

ArrayList<String> aList = new ArrayList<String>();
aList.add("One");
String element = aList.get(0); // no cast needed
System.out.println("Got one: " + element); 

Эти Шаблоны разработки книга поощряет читателя думать с точки зрения контрактов, не конкретных типов. Существует мудрость (и повторное использование кода) в разводе с переменными от их класса с реализацией.

Принимая это во внимание, Вы могли бы думать, что все Объекты списка реализаций должны сделать тот же набор вещей: add(), get(), size(), и т.д. С небольшим отражением, можно вообразить много реализаций операций Списка, которые повинуются контракту Списка различными способами (например, ArrayList). Однако тип данных эти объекты соглашение с является ортогональным к действиям, выполненным на них.

Соединенный все это и Вы будет видеть следующие виды кода часто:

List<String> L = new ArrayList<String>();

необходимо считать, что как "L своего рода Список, который имеет дело со Строковыми объектами". Когда Вы начинаете иметь дело с классами Фабрики, очень важно иметь дело с контрактами, а не определенными реализациями. Фабрики производят объекты различных типов во времени выполнения.

Используя дженерики довольно легко (большую часть времени).

Однажды можно решить, что Вы хотите реализовать свой собственный универсальный класс. Возможно, Вы хотите записать новый интерфейс абстракции базы данных, который игнорирует differencesbetween различные хранилища данных. При определении того универсального класса Вы будете использовать <t> в качестве заполнителя для вида объекта, которым будут управлять методы.

, Если Вы все еще смущены, используйте универсальные классы для Списка, пока Вы не удобны. Позже, можно погрузиться в реализацию с немного большей уверенностью. Или можно посмотреть на исходный код для различных классов Списка, которые поставлются с JRE. Открытый исходный код является великим тот путь.

Взглянули на Oracle/Sun документы о дженериках . Аплодисменты.

102
ответ дан jjohn 24 November 2019 в 13:17
поделиться

В моих собственных простых терминах:

Список

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

List< Object>

создаст список, который может содержать любой тип объекта, но может только быть присвоен другой List< Object>

, Например, это не работает;

List<Object> l = new ArrayList<String>();

, Конечно, Вы можете добавить что-либо, но только можете вытянуть Объект.

List<Object> l = new ArrayList<Object>();

l.add( new Employee() );
l.add( new String() );

Object o = l.get( 0 );
Object o2 = l.get( 1 );

Наконец

List<?>

позволит Вам присвоить любой тип, включая [1 122]

List <?> l = new ArrayList(); 
List <?> l2 = new ArrayList<String>();

Это назвали бы набором неизвестный и так как общий знаменатель неизвестный является Объектом, Вы сможете выбрать Объекты (совпадение)

, важность [1 110] неизвестный прибывает когда его используемый с разделением на подклассы:

List<? extends Collection> l = new ArrayList<TreeSet>(); // compiles

List<? extends Collection> l = new ArrayList<String>(); // doesn't,
// because String is not part of *Collection* inheritance tree. 

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

различие здесь, то, что l является набором [1 111], не знают , который принадлежит Набор иерархия.

40
ответ дан OscarRyz 24 November 2019 в 13:17
поделиться

Я отсылаю Вас к превосходному учебное руководство по Дженерикам Java, и "усовершенствованное" учебное руководство по Дженерикам, оба доступные от Sun Microsystems. Другой большой ресурс Дженерики Java и Наборы книга.

15
ответ дан Fabian Steeg 24 November 2019 в 13:17
поделиться

Самое простое объяснение, которое не является "прочитайте руководство":

List

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

List<Object>

, В то время как:

List<?>

в основном означает что-то универсальное, но Вы не знаете, каков универсальный тип. Его великое для того, чтобы избавиться от предупреждений компилятора, когда Вы наклоняетесь, изменяет типы возврата других вещей, которые просто возвратили Список. Ее намного более полезное в форме:

List<? extends SomeOtherThing>
4
ответ дан John Gardner 24 November 2019 в 13:17
поделиться

Самое короткое объяснение: второй объект является списком, который может содержать любой тип, и можно добавить объекты к нему:

List<Object>

первый объект, который Вы перечисляете, рассматривают, поскольку чрезвычайно эквивалентный этому, кроме Вас получит предупреждения компилятора, потому что это - "необработанный тип".

List

третьим является список, который может содержать любой тип, но Вы ничего не можете добавить к нему:

List<?> 

В основном, Вы используете вторую форму (List<Object>), когда у Вас действительно есть список, который может содержать любой объект, и Вы хотите смочь добавить элементы к списку. Вы используете третью форму (List<?>), когда Вы получите список как возвращаемое значение метода, и Вы выполните итерации по списку, но никогда не добавлять, что что-либо к нему Никогда не использует первую форму (List) в новой компиляции кода под Java 5 или позже.

3
ответ дан Eddie 24 November 2019 в 13:17
поделиться

Я поместил его этот путь: В то время как List и List<Object> может содержать любой тип объектов, List<?> содержит элементы неизвестного типа, но после того как тот тип получен, он может только содержать элементы того типа. Который является, почему это - единственный безопасный с точки зрения типов вариант тех трех, и поэтому обычно предпочтительный.

1
ответ дан Fabian Steeg 24 November 2019 в 13:17
поделиться

Для дополнения учебных руководств, упомянутых Rob вот, wikibook объяснение темы:
http://en.wikibooks.org/wiki/Java_Programming/Generics

<час>

Редактирование:

  1. Никакие ограничения на тип объектов в списке

  2. Объекты в списке должны расширить Объект

  3. Подстановочный знак, используемый отдельно, таким образом, он соответствует чему-нибудь

, было бы наивно из меня прийти к заключению в этой точке, что существует едва какое-либо/нет различие вообще?

0
ответ дан Tim 24 November 2019 в 13:17
поделиться

, Когда был бы, я хочу использовать

public void CanYouGiveMeAnAnswer( List l ){}

, Когда Вы наклоняетесь, чтобы сделать весь кастинг Ваш сам.

, Когда был бы, я хочу использовать

public void CanYouGiveMeAnAnswer( List l<Object> ){}

, Когда Вы хотите ограничить тип Списка. Например, это было бы недействительным аргументом.

 new ArrayList<String>();

, Когда был бы, я хочу использовать

public void CanYouGiveMeAnAnswer( List l<?> ){}

Главным образом никогда.

0
ответ дан OscarRyz 24 November 2019 в 13:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: