К сожалению, это 2015 год, а white-space-collapse
все еще не реализовано.
Пока давайте родительский элемент font-size: 0;
и установите font-size
для детей. Это должно сделать трюк
Разница заключается в возвращаемом типе, особенно под влиянием вывода , причем тип может быть типом иерархически между типами Comparable и типом List. Позвольте мне привести пример:
class Top {
}
class Middle extends Top implements Comparable<Top> {
@Override
public int compareTo(Top o) {
//
}
}
class Bottom extends Middle {
}
Используя подпись, которую вы предоставили:
public static <T extends Comparable<? super T>> T max(List<? extends T> list)
, мы можем закодировать это без ошибок, предупреждений или (что важно) приведения:
List<Bottom> list;
Middle max = max(list); // T inferred to be Middle
И если вы нуждаетесь в результате Middle
, без вывода, вы можете явно ввести вызов в Middle
:
Comparable<Top> max = MyClass.<Middle>max(list); // No cast
или перейти к методу, который принимает Middle
(где вывод не будет работать)
someGenericMethodThatExpectsGenericBoundedToMiddle(MyClass.<Middle>max(list));
Я не знаю, помогает ли это, но чтобы проиллюстрировать типы компилятора как разрешенные / предположим, подпись будет выглядеть так (не это, конечно, компилируется):
public static <Middle extends Comparable<Top>> Middle max(List<Bottom> list)
Нелегко, но я постараюсь быть как можно более конкретным:
в T max(Collection<? extends T> coll)
вы могли бы передать такой аргумент List<Animal> or List<Cat> or List<Dog>
, а в T wrongMax(Collection<T> xs)
, где T Животное, которое вы не можете передать как аргумент List<Dog>, List<Cat>
, конечно, в Runtime вы могли бы добавить объекты Cat или Dog в List<Animal>
, но во время компиляции вы не смогли бы передать подкласс Animal в Тип списка с другой стороны, в методе max
, который вы могли бы передать в качестве аргумента в методе wrongMax
. Извините за мой английский, я все еще его изучаю :), С уважением.
Разница между
T max(Collection<? extends T> coll)
и
T wrongMax(Collection<T> xs)
заключается в том, что возвращаемый тип второй версии в точности совпадает с типом элемента коллекции T
, тогда как в первой версии T
может быть супер тип типа элемента.
Второй вопрос: причина для T extends Object
гарантирует, что T
является классом, а не интерфейсом.
Обновление: немного более «естественная» демонстрация разницы: предположим, вы определяете эти два метода:
static void happy(ColoredPoint p, Point q) {}
static void happy(Point p, ColoredPoint q) {}
И назовите первый из них следующим образом:
happy(coloredPoint, min(points));
happy(coloredPoint, wrongMin(points));
Механизм вывода типа мог бы вывести, что в первом вызове тип возврата min
должен быть Point
, и код будет скомпилирован. Второй вызов не смог скомпилировать, поскольку вызов happy
неоднозначен.
К сожалению, механизм вывода типа не достаточно мощный, по крайней мере, на Java 7, поэтому на самом деле оба вызова не скомпилируются. Разница в том, что первый вызов можно зафиксировать, указав параметр типа, как в Algorithms.<Point>min
, тогда как для фиксации второго вызова потребуется явное литье.