Вы можете сгенерировать все значения, используя выражение генератора, сохранить первое, а затем распечатать все.
import itertools
ss = 2.8 * 57 * 480
distances = (ss / h*3.6 for _, _, _, h in faces)
saved_distance = next(distances, None) # the None prevents an error if `faces` is empty
for distance in itertools.chain([saved_distance], distances):
print(f"Distance = {distance}")
Причина состоит в том, что Test.class имеет тип Class< Test>. Вы не можете присвоить ссылку типа Class< Test> к переменной типа Class< T> поскольку они не то же самое. Это, однако, работает:
Class<? extends Test> testType = type == null ? Test.class : type;
подстановочный знак позволяет обоим Class< T> и Class< Test> ссылки, которые будут присвоены testType.
существует тонна информации о поведении дженериков Java в [1 125] дженерики FAQ Java Angelika Langer. Я обеспечу пример на основе части информации там, которая использует Number
базовый API Java иерархии класса.
Рассматривают следующий метод:
public <T extends Number> void testNumber(final Class<T> type)
Это должно позволить, чтобы следующие утверждения были успешно компиляцией:
testNumber(Integer.class);
testNumber(Number.class);
, Но следующее не скомпилирует:
testNumber(String.class);
Теперь рассматривают эти операторы:
Class<Number> numberClass = Number.class;
Class<Integer> integerClass = numberClass;
вторая строка не удается скомпилировать и производит эту ошибку Type mismatch: cannot convert from Class<Number> to Class<Integer>
. Но Integer
расширяется Number
, итак, почему это перестало работать? Посмотрите на эти следующие два оператора для наблюдения почему:
Number anumber = new Long(0);
Integer another = anumber;
довольно легко видеть, почему 2-я строка не компилирует здесь. Вы не можете присвоить экземпляр [1 111] к переменной типа Integer
, потому что нет никакого способа гарантировать, что Number
экземпляр имеет совместимый тип. В этом примере эти Number
на самом деле Long
, который, конечно, не может быть присвоен Integer
. На самом деле ошибка является также несоответствием типов: Type mismatch: cannot convert from Number to Integer
.
правило состоит в том, что экземпляр не может быть присвоен переменной, которая является подклассом типа экземпляра, поскольку нет никакой гарантии, которая является, совместимо.
Дженерики ведут себя подобным образом. В подписи общего метода, T
просто заполнитель для указания на то, что метод позволяет компилятору. Когда компилятор встречается testNumber(Integer.class)
, он по существу заменяет T
[1 121].
Подстановочные знаки добавляют дополнительную гибкость, поскольку следующее скомпилирует:
Class<? extends Number> wildcard = numberClass;
С тех пор Class<? extends Number>
указывает на любой тип, который является Number
или подкласс [1 124], это совершенно законно и потенциально полезно при многих обстоятельствах.
Предположим, что я расширяю Тест:
public class SubTest extends Test {
public static void main(String args[]) {
Test t = new Test();
t.testT(new SubTest());
}
}
Теперь, когда я вызвал testT
, параметр типа <T>
SubTest
, что означает, что переменная testType
Class<SubTest>
. Test.class
имеет тип Class<Test>
, который не является присваиваемым переменной типа Class<SubTest>
.
, Объявляя переменную testType
, поскольку Class<? extends Test>
правильное решение; кастинг к [1 111] скрывает настоящую проблему.
Удалите условное выражение, и ошибка немного более хороша...
public class Test {
public static void main(String args[]) {
Test t = new Test();
t.testT(null);
}
public <T extends Test> void testT(Class<T> type) {
Class<T> testClass = Test.class;
System.out.println(testClass);
}
}
Test.java:10: incompatible types
found : java.lang.Class<Test>
required: java.lang.Class<T>
Class<T> testClass = Test.class;