В RegEx {i,f}
означает, что «между i
и f
соответствует». Давайте посмотрим на следующие примеры:
{3,7}
означает от 3 до 7 соответствий {,10}
означает до 10 совпадений без нижнего предела (т.е. нижний предел равен 0) {3,}
означает не менее 3 совпадений без верхнего предела (т.е. верхний предел бесконечен) {,}
означает, что верхний предел или нижний предел для количество совпадений (т. е. нижний предел равен 0, а верхний предел бесконечен) {5}
означает ровно 4 Большинство хороших языков содержат сокращения, RegEx:
+
является сокращением для {1,}
*
является сокращением для {,}
?
является сокращенное значение для {,1}
Это означает, что +
требует не менее 1 совпадения, в то время как *
принимает любое количество совпадений или не имеет совпадений вообще, а ?
принимает не более 1 совпадающие или нулевые.
Кредит: Codecademy.com
CharSequence
- interface
. Поэтому, даже если SomeClass
не реализует CharSequence
, было бы вполне возможно создать класс
class SubClass extends SomeClass implements CharSequence
. Поэтому вы можете написать
SomeClass c = getCharSequence();
, потому что предполагаемый тип X
является типом пересечения SomeClass & CharSequence
.
Это немного странно в случае Integer
, потому что Integer
является окончательным, но final
не играет никакой роли в этих правилах. Например, вы можете написать
<T extends Integer & CharSequence>
. С другой стороны, String
не является interface
, поэтому было бы невозможно расширить SomeClass
, чтобы получить подтип String
, потому что java не поддерживает множественное наследование для классов.
С примером List
вам нужно помнить, что дженерики не являются ни ковариантными, ни контравариантными. Это означает, что если X
является подтипом Y
, List<X>
не является ни подтипом, ни супертипом List<Y>
. Поскольку Integer
не реализует CharSequence
, вы не можете использовать List<Integer>
в своем методе doCharSequence
.
Вы можете, однако, получить это, чтобы скомпилировать
<T extends Integer & CharSequence> void foo(List<T> list) {
doCharSequence(list);
}
Если у вас есть метод, который возвращает a List<T>
следующим образом:
static <T extends CharSequence> List<T> foo()
вы можете сделать
List<? extends Integer> list = foo();
Опять же, это потому, что выведенные type Integer & CharSequence
, и это подтип Integer
.
Типы пересечений возникают неявно, когда вы указываете несколько границ (например, <T extends SomeClass & CharSequence>
).
Для получения дополнительной информации здесь является частью JLS, где объясняется, как работают ограничения типов. Вы можете включить несколько интерфейсов, например
<T extends String & CharSequence & List & Comparator>
, но только первая оценка может быть неинтерфейсом.
Тип, который выводится вашим компилятором до назначения для X
, - Integer & CharSequence
. Этот тип чувствует странным, потому что Integer
является окончательным, но он является вполне допустимым типом в Java. Затем он переключается на Integer
, что совершенно нормально.
Существует только одно возможное значение для типа Integer & CharSequence
: null
. С помощью следующей реализации:
<X extends CharSequence> X getCharSequence() {
return null;
}
Следующее назначение будет работать:
Integer x = getCharSequence();
Из-за этого возможного значения нет причин, по которым назначение должно быть неправильным, даже если оно очевидно бесполезно. Предупреждение было бы полезно.
. На самом деле, я недавно написал блог об этом API-шаблоне API . Вы должны (почти) никогда не разрабатывать общий метод для возврата произвольных типов, потому что вы можете (почти) никогда не гарантировать, что выводимый тип будет доставлен. Исключением являются такие методы, как Collections.emptyList()
, в случае которых пустота списка (и стирание родового типа) является причиной того, что любой вывод для <T>
будет работать:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
&
в общее определение. +1 – flakes 4 April 2016 в 12:52<T extends String & List & Comparator>
в порядке, но<T extends String & Integer>
нет, потому чтоInteger
не является интерфейсом. – Paul Boddington 4 April 2016 в 12:53Collections.emptyList()
, а такжеOptional.empty()
. Эти возвратные реализации общего интерфейса, но ничего не хранить. – Stefan Dollase 4 April 2016 в 13:36final
будетfinal
во время выполнения. – Holger 4 April 2016 в 15:25getCharSequence()
обещает вернуть все, чтоX
требует вызывающего, включая возврат типа расширенияInteger
и реализацииCharSequence
, если вызывающий абонент нуждается в этом и в соответствии с этим обещанием, правильно разрешить присвоение результатаInteger
. Это методgetCharSequence()
, который сломан, поскольку он не выполняет свое обещание, но это не ошибка компилятора. – Holger 4 April 2016 в 15:45