Дженерики Java, расширяющие тип возврата методов

Смотрите на эти три класса. Minatchi позволяет себе быть расширенным так, чтобы тип возврата его методов мог быть расширен также. Для иллюстрирования я использовал статический метод.

public class Minatchi<T extends Minatchi<?>>{

  static public <T extends Minatchi<?>>
    List<T> listAll(){
      return
        (List<T>) query();
  }
}

И таким образом, я разделяю Minatchi на подклассы в Леди

public class Lady
extends Minatchi<Lady>{

}

Это - то, где сомнительное поведение происходит.

public class HelloMinatchi{

  private void listA(){
    List<Lady> uvs = Lady.listAll();
    for (Lady uv: uvs){
      logger.info(uv.getName() );
    }
  }

  private void listB(){
    for (Lady uv: Lady.listAll()){
      logger.info(uv.getName() );
    }
  }
}

Методы Листа и listB являются по существу тем же. Листа помещает список в промежуточную переменную uvs, тогда как listB непосредственно помещает listAll в заголовок для цикла.

Однако для listB, компилятор жалуется, не Может преобразовать Minatchi<?> в Леди.

Таким образом, этот вопрос о целостности дизайна дженериков Java. Еще одно схватывание дженериков.

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

Или состоит в том эта моя персональная проблема, что я не знаю лучший способ объявить дженерики? Если так, скажите мне как.

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

5
задан Bozho 14 January 2010 в 13:45
поделиться

4 ответа

Вы смотрели на jsyn ? Я не думаю, что ядные библиотеки Java могут делать то, что вы хотите.

-121--2296633-

Статический метод не принимает определение общего типа из класса. I.E. Метод Listall () метод не знает о даме продлевает Minatchi ).

Тип возврата определяется левой стороны выражения:

  • в LISTA () Левая сторона определяет, что он ожидает, что он ожидает
  • В Listb () LOOP FORACH выглядит так же, как следует ожидать, что дама , но кажется, что компилятор не правильно проинструктирован с помощью петли FORACH.

Способ сделать LISTB () Работа - это сказать, какой универсальный тип использовать:

for (Lady uv : Lady.<Lady>listAll()) {..}
5
ответ дан 14 December 2019 в 04:38
поделиться

Это происходит из-за типа стирания.

Из Java-универсального учебного пособия

при создании общего типа, Компилятор переводит эти типы Техника под названием Type Strasure - A процесс, где компилятор удаляет все Информация, связанная с типовыми параметрами и введите аргументы в классе или метод.

Поскольку Call Lady.listall выполняется на Minatchi Shar Minatchi, компилятор не может знать, что конкретный тип является Minatchi

Type Surasure был использован для генеральных средств, так что общие типы будут совместимы с компиляцией библиотек Java До того, как дженерики были добавлены в библиотеку. То есть некоторые усилия, чтобы приложить , добавленную в Java , но это не на дорожной карте для Java 7.

1
ответ дан 14 December 2019 в 04:38
поделиться

Ваша проблема заключается в том, что вы позволите компилятору вывести общие аргументы в метод Listall, и в первом случае он активирует то, что вы хотите, потому что вы храните результат в переменной, и это может просто посмотреть на тип переменной. Во-вторых, он не может выводить тип «правильный» тип автоматически, поэтому вам нужно указать его самостоятельно:

for (Lady uv: Lady.<Lady>listAll()){
    logger.info(uv.getName() );
}

Обратите внимание, что в этом примере нет причин для класса Minatchi, как это не влияет на статический метод вообще.

Пожалуйста, обратите внимание, что вызов Lady.listall точно такой же, как вызов minatchi.listall (то есть не влияет на то, какие типы компилятор могли или выводят в качестве общих аргументов).

1
ответ дан 14 December 2019 в 04:38
поделиться

Используйте параметр errorPlacement (см. документацию здесь: http://docs.jquery.com/Plugins/Validation/validate#toptions )

$('#RegisterForm').validate({
        rules: {
            Country:{required: true},
            State:{required: true}
        },
        messages: {
            Country:{required: "Select Country"},
            State:{required: "Select State"}
        },
        errorPlacement: function(error, element) {
            error.appendTo( element.parent("td").next("td") );
        }
    });

Конечно, вам придется адаптировать код к ситуации.

-121--3126715-

При использовании ActionMailer во время тестов все сообщения помещаются в большой массив, называемый доставками . То, что вы в основном делаете (и это в основном достаточно), это проверка наличия электронной почты в массиве. Но если вы хотите проверить определенное сообщение электронной почты, вы должны знать, что на самом деле хранится в массиве. К счастью, сами сообщения электронной почты хранятся, поэтому вы можете выполнять итерацию через массив и проверять каждое сообщение электронной почты.

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

  • получатели : Берет один или несколько адресов электронной почты. На эти адреса будет доставлена ваша электронная почта. Устанавливает заголовок To:.
  • Тема : Тема вашего электронного письма. Задает заголовок Тема:.
-121--1110398-

К сожалению, как я упомянул в другом вопросе: Почему неявный вывод типа работает только в назначении? , неявный вывод типа в Java работает только в назначении.

Я до сих пор не знаю причину. Но для меня это все еще кажется глупым.

1
ответ дан 14 December 2019 в 04:38
поделиться
Другие вопросы по тегам:

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