在使用var时,多态仍然有效。在继承的世界中,var类型的子类型可以像平常一样赋值给超类型的var类型,如下所示:
import javax.swing.* var password = new JPasswordField("Password text") String.valueOf(password.getPassword()) // // 将密码的字符数组转换成字符串 var textField = new JTextField("Hello text") textField = password textField.getText()但不能将超类型var赋值给子类型var,如下所示:
password = textField这是因为JPasswordField是JTextField的子类。
var和编译时安全性如果出现错误的赋值操作会怎样?不兼容的变量类型不能相互赋值。一旦编译器推断出实际类型的var,就不能将错误的值赋值给它,如下所示:
var number = 10 number = "InfoQ"这里发生了什么?编译器将“var number = 10”替换为“int number = 10”,所以仍然可以保证安全性。
var与集合和泛型现在让我们来看看var与集合和泛型一起使用时如何进行类型推断。我们先从集合开始。在下面的情况中,编译器可以推断出集合元素的类型是什么:
var list = List.of(10);这里没有必要进行类型转换,因为编译器已经推断出正确的元素类型为int。
int i = list.get(0); //等效于: var i = list.get(0);下面的情况就不一样了,编译器只会将其作为对象集合(而不是整数),因为在使用菱形运算符时,Java需要LHS(左侧)的类型来推断RHS的类型:
var list2 = new ArrayList<>(); list2.add(10); list2 int i = list2.get(0) //编译错误 int i = (int) list2.get(0) //需要进行转换,获得int对于泛型,最好在RHS使用特定类型(而不是菱形运算符),如下所示:
var list3 = new ArrayList<Integer>(); list3.add(10); System.out.println(list3) int i = list3.get(0) for循环中的var类型让我们先来看看基于索引的For循环:
for (var x = 1; x <= 5; x++) { var m = x * 2; //等效于: int m = x * 2; System.out.println(m); }下面是在For Each循环中:
var list = Arrays.asList(1,2,3,4,5,6,7,8,9,10) for (var item : list) { var m = item + 2; System.out.println(m); }现在我有一个问题,var是否适用于Java 8 Stream?让我们看看下面的例子:
var list = List.of(1, 2, 3, 4, 5, 6, 7) var stream = list.stream() stream.filter(x -> x % 2 == 0).forEach(System.out::println) var类型和三元运算符