Как обеспечить, чтобы аргументы метода имели один и тот же тип с помощью Generics? [Дубликат]

Набор ссылок, которые добавляются в новый проект, определяется конкретным шаблоном проекта. Шаблоны проектов - довольно общая концепция, и нет возможности контролировать такие элементы, как набор ссылок.

Что вы можете сделать, это создать новый шаблон проекта, который является зеркалом обычного шаблона и удалить эти ссылки из файла проекта. Просто скопируйте шаблон из его местоположения по умолчанию (в папке ProjectTemplatesCache в Visual Studio) в папку, определенную пользователем в разделе «Visual Studio 2008» в «Мои документы». Вы также захотите переименовать его в отдельном окне. После этого новый шаблон начнет отображаться в новом диалоговом окне проекта.

7
задан alkedr 24 October 2014 в 00:32
поделиться

3 ответа

Причина, по которой этот компилятор состоит в том, что Java выведет наиболее специфичный супертип переданных аргументов, в этом случае Object Serializable & Comparable<? extends Serializable & Comparable<? extends Comparable<?>>>, после того как 1 помечен в поле Integer и "1" как String.

Без генерик:

private static void method(Number arg1, Number arg2) {

Даже без дженериков вы можете передать Integer и Double.

Только если тип, о котором идет речь, final, вы можете сделать это без дженериков:

private static void method(String arg1, String arg2) {
    // Yes, they're both Strings, guaranteed.

Существует один краевой случай с дженериками, о котором я могу думать, чтобы убедиться, что они являются точным типом. Если у вас есть класс final, и вы помещаете верхнюю границу, вы можете ограничить его тем же классом.

public <T extends MyFinalClass> void method(T arg1, T arg2) {
    // Yes, they're both MyFinalClasses
}

Но тогда вы могли бы сделать то же самое без дженериков.

public void method(MyFinalClass arg1, MyFinalClass arg2) {
    // Yes, they're both MyFinalClasses
}
7
ответ дан rgettman 15 August 2018 в 19:18
поделиться
  • 1
    В этом случае Java фактически вводит супертип Serializable & Comparable<? extends Serializable & Comparable<? extends Comparable<?>>>. – August 24 October 2014 в 00:23

Вы можете добавить класс в качестве дополнительного параметра.

private static <T> void method(T arg1, T arg2, Class<T> type) {
    // ...
}

Теперь вам нужно указать общий тип.

Вы все равно можете вызвать method(1, "1", Object.class);, но по крайней мере вы явно относятся к общему типу.

4
ответ дан Max Fichtelmann 15 August 2018 в 19:18
поделиться

Это невозможно. Или посмотреть на это по-другому, два опорных аргумента всегда «одного типа» - Object - любые аргументы ссылочного типа всегда являются экземплярами Object.

T всегда может be Object и взять любые два контрольных аргумента. Даже с <T, U extends T> void method(T arg1, U arg2) оба T и U могут быть Object и, следовательно, снова принимать любые два аргумента.

Основная причина этого заключается в том, что нет причин для безопасности типа имеют такое ограничение. Одна из основных точек наследования заключается в том, что должно быть возможно безопасно обрабатывать экземпляры подкласса, такие как суперкласс. Тип ссылки суперкласса может указывать на экземпляр этого класса или подкласса свободно. Поэтому две ссылочные переменные, которые имеют один и тот же тип времени компиляции, всегда могут безошибочно указывать на время выполнения на экземпляры разных типов подклассов. Поэтому во время компиляции вы никогда не сможете сделать какое-либо утверждение о соотношении фактических классов времени выполнения двух экземпляров, кроме того, что они являются подклассами типа времени компиляции. Поскольку для двух аргументов безопасно быть экземплярами разных классов во время выполнения, не менее безопасно фактически передавать два аргумента разных типов времени компиляции.

1
ответ дан newacct 15 August 2018 в 19:18
поделиться
Другие вопросы по тегам:

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