2016-02-17 3 views
1

Я хочу задать способ, который определяет его тип, как это:Как определить метод ограниченного типа для другого ограниченного типа?

List<R> toList(JsArray<T> array)

, что Т ограничен таким образом, что она является одновременно:

  • T extends SomeClass и
  • T extends R

Я пробовал такие вещи, безрезультатно:

<R, T extends R & SomeClass> List<R> toList(JsArray<T> array)

(Для любопытных, это должно быть в состоянии использовать GWT Overlay Types with Interfaces)

+0

em ... так что R будет иметь ограничение как интерфейс только неявно. Я не думаю, что система типа java может быть такой умной. – HuStmpHrrr

+0

также, если вы расширяете класс, он должен появиться на первом месте: https://docs.oracle.com/javase/tutorial/java/generics/bounded.html – HuStmpHrrr

+0

На основе комментария HuStmpHrrr, если только 'R' - это интерфейс это невозможно. Java не поддерживает множественное наследование, т. Е. Класс Java не может напрямую расширяться из нескольких классов (но он может расширять класс и реализовывать интерфейс). – TNT

ответ

1

Я боюсь, что это не сработает. Правильный синтаксис будет

<R, T extends R & SomeClass> List<R> toList(JsArray<T> array) 

Но это даст вам следующее сообщение об ошибке

Невозможно указать любую дополнительную грань SomeClass, когда первая оценка является параметром типа

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

+0

Боюсь, что вы правы. Просто невозможно, кроме использования какого-либо непроверенного кода. – Ben

2

Как насчет этого?

<T extends SomeClass> List<? super T> toList(JsArray<T> array) 

EDIT:

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

Но вы на самом деле ничего не передаете, чтобы рассказать о методе создания. Поскольку я всегда мог вызывать toList() с R = T, единственное, что вы могли бы сделать всегда всегда (для всех R super T) - вернуть List<T>, что делает ненужным параметр R ... но это не то, что вы хотите.

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

<R, T extends SomeClass> List<R> toList(JsArray<T> array, Class<R> cls) 

и назвать его как

toList(arrayIHave, WhatIWant.class) 

Теперь это будет работать, но вы будете жаловаться, что у него есть условия ошибки, потому что ограничение «T extends R» не улавливается , Но на самом деле, даже если вы добавите ограничение, вы все равно будете иметь ошибки.

можно использовать произвольный интерфейс для R, сделав T, который расширяет SomeClass и R реализует. Нельзя каким-либо образом создать экземпляр произвольного интерфейса, поэтому для многих пар R,T, которые удовлетворяют вашим ограничениям, вам придется возвращать null или выдавать исключение или что-то в этом роде.

Нет сомнения нет некоторых правило, которое диктует, которое R вы будете возвращаться, но не существует никакого способа даже думать об указании общих ограничений, которые фиксируют, что править, так что будет быть непроверенным преобразование где-то. Если вы используете такую ​​подпись, по крайней мере, вы можете поместить ее внутри метода, вместо того чтобы иметь предупреждения или аннотации везде, где вы его используете.

+0

Nope - я хочу вернуть список некоторого _other_ интерфейса, а не супертип T. – Ben

+0

Он возвращает список некоторого супертипа T, например R. Вы хотите * указать * R? Ну, может быть, вы это сделаете, но из-за стирания стилей он не может иметь никакого эффекта. –

+0

Да, моя цель состояла в том, чтобы указать R. Я думаю, я не указал это в вопросе. Одна работа вокруг - это удалить «? super T', и просто нести вокруг «extends SomeInterface» нисходящие дженерики ... но этого я и старался избежать. – Ben

Смежные вопросы