做百度移动网站快速,萍乡公司做网站,邢台做网站的那好,沈阳seo优化排名公司作者 | 王磊来源 | Java中文社群#xff08;ID#xff1a;javacn666#xff09;转载请联系授权#xff08;微信ID#xff1a;GG_Stone#xff09;在很久很久以前#xff0c;我们写代码时要慎重的考虑变量的数据类型#xff0c;比如下面这些#xff1a;枚举#xff1a… 作者 | 王磊来源 | Java中文社群IDjavacn666转载请联系授权微信IDGG_Stone在很久很久以前我们写代码时要慎重的考虑变量的数据类型比如下面这些枚举尽管在 JDK 5 中增加了枚举类型但是 Class 文件常量池的 CONSTANT_Class_info 类型常量并没有发生任何语义变化仍然是代表一个类或接口的符号引用没有加入枚举也没有增加过“CONSTANT_Enum_info”之类的“枚举符号引用”常量。所以使用 enum 关键字定义常量尽管从 Java 语法上看起来与使用 class 关键字定义类、使用 interface 关键字定义接口是同一层次的但实际上这是由 Javac 编译器做出来的假象从字节码的角度来看枚举仅仅是一个继承于 java.lang.Enum、自动生成了 values() 和 valueOf() 方法的普通 Java 类而已因此枚举也归为引用类型了。然而到了 JDK 10 时我们就有了新的选择JDK 10 中新增了 var 局部变量推断的功能使用它我们可以很 happy 的忘记数据类型这件事了那它是如何使用的呢接下来我们一起来看。1、使用对比接下来我们就使用对比的方式来体会一下 var 的作用。场景一定义字符串旧写法String str Hello, Java.;
新写法var s Hello, Java.;
PS这里的旧写法指的是 JDK 10 之前的版本而新写法指的是 JDK 10 以后包含 JDK 10的版本。场景二数值相加旧写法int num1 111;
double num2 555.666d;
double num3 num1 num2;
System.out.println(num3);
PS当遇到不同类型相加时int double会发生数据类型向上转型因此 num3 就会升级为 double 类型。新写法var n1 111L;
var n2 555.666;
var n3 n1 n2;
System.out.println(n3);
场景三集合旧写法ListObject list new ArrayList();
list.add(Hello);
list.add(Java);
新写法var list new ArrayList();
list.add(Hello);
list.add(Java);
场景四循环旧写法for (Object item : list) {System.out.println(item: item);
}
for (int i 0; i 10; i) {// do something...
}
新写法for (var item : list) {System.out.println(item: item);
}
for (var i 0; i 10; i) {// do something...
}
场景五配合 Lambda 使用旧写法ListObject flist list.stream().filter(v -v.equals(Java)).collect(Collectors.toList());
System.out.println(flist);
新写法var flist list.stream().filter(v -v.equals(Java)).collect(Collectors.toList());
System.out.println(flist);
2、优点分析通过上面的示例我们可以看出 var 具备两个明显的优点提高了代码的可读性和命名对齐。① 提高了可读性我们在没有使用 var 之前如果类型的名称很长就会出现下面的这种情况InternationalCustomerOrderProcessorAnonymousCustomer, SimpleOrderBook orderProcessor createInternationalOrderProcessor(customer, order);
当限定每行不能超过 150 个字符的话变量名就会被推到下一行显示这样整个代码的可读性就变得很低。但当我们使用了 var 之后代码就变成了这样var orderProcessor createInternationalOrderProcessor(customer, order);
从上述的代码可以看出当类型越长时var可读性的价值就越大。② 命名对齐在不使用 var 时当遇到下面这种情况代码就是这样的// 显式类型
No no new No();
AmountIncreaseBigDecimal more new BigDecimalAmountIncrease();
HorizontalConnectionLinePosition, LinePosition jumping new HorizontalLinePositionConnection();
Variable variable new Constant(6);
ListString names List.of(Java, 中文社群);
在使用了 var 之后代码是这样的var no new No();
var more new BigDecimalAmountIncrease();
var jumping new HorizontalLinePositionConnection();
var variable new Constant(6);
var names List.of(Java, 中文社群);
从上述代码可以看出使用了 var 之后命名对齐了整个代码也变得更优雅了。3、使用规则 反例var 的实现来自于 JEP 286 (改善提议 286详情地址 http://openjdk.java.net/jeps/286从 JEP 286 的标题“局部变量类型推断”可以看出var 只能用于局部变量声明也就是说 var 必须满足以下条件它只能用于局部变量上声明时必须初始化不能用作方法参数和全局变量类变量。PS因为 var 的实现必须根据等会右边的代码进行类型推断因此它不能被赋值 null 或不被初始化。反例一未初始化和赋值 null反例二中途类型更改反例三全局变量反例四作为返回值4、原理分析经过前面的使用我们对 var 已经有了初步的认识但 var 的实现原理是什么呢为了搞清楚它的原理我们对下面的代码进行了编译使用命令 javac MainTest.java然后我们再用反编译工具打开被编译的类发现var 竟然被替换成一个个确定的数据类型了如下图所示由此我们可以得出结论var 关键字的实现和它的名字密切相关 var 只是局部类型推断它只会在 Java 编码期和编译期有效当类被编译为 class 文件时var 就会变成一个个确定的数据类型通过推断得出。 所以我们可以把 var 通俗的理解为 Java 的语法糖使用它可以让我们快速优雅的实现业务代码但 var 在字节码层面是不存在的。总结本文我们介绍了 var局部类型推断的使用它可以用在局部变量、 for、 Lambda 的变量声明中但不能用在全局变量的声明中也不能用它作为方法的返回值并且在声明时一定要进行初始化也不能赋值为 null。使用 var 可以有效的提高代码的可读性和命名对齐它的实现原理是在编译期通过等号右侧的代码进行类型推断然后再将 var 替换成确定的数据类型。
往期推荐
多图证明Java到底是值传递还是引用传递URL 去重的 6 种方案(附详细代码)JDK15正式发布新增功能预览关注下方二维码收获更多干货