1.语法糖

程序员喜欢将一些复杂的代码或逻辑写成几行,使代码紧凑和可读。编程语言的创造者有时会为此提供帮助。

一种可以让您走捷径(少写代码)的灵活语言功能称为句法糖。但是,老实说,在 Java 中几乎没有。

Java 的创建者竭尽所能消除 Java 中的任何冗余。如果 C++ 允许您以 20 种方式做某事,那么 Java 只允许您以一种方式做。

但是 Java 程序员和 Java 的创造者都不喜欢缺乏自由。有时糖会让像你我这样的普通人的生活更轻松。

顺便说一下,您已经遇到了一些语法糖:自动装箱拆箱。让我们比较一下:

长码 代码紧凑
Integer a = new Integer(5);
int b = a.intValue();
Integer a = 5;
int b = a;
int b = 5;
Integer c = new Integer(b);
int b = 5;
Integer c = b;
Integer a = new Integer(1);
int b = 1;
if (a.intValue() == b)
{
   ...
}
Integer a = 1;
int b = 1;
if (a == b)
{
   ...
}

您可以在右侧编写更紧凑的代码,而不是左侧的长代码。智能Java 编译器将根据简短版本的代码生成详细版本的代码。这正是语法糖。


2.变量类型的推断:var关键字

在 Java 11 中,编译器变得更加智能,现在可以根据分配给它的值的类型来确定声明变量的类型。在代码中,它看起来像这样:

var name = value;

其中name是新变量的名称,value是它的初始值,var是用来声明变量的关键字。名称变量的类型将与分配给它的值的类型相同。

例子:

我们如何看待代码 编译器看到了什么
var i = 1;
int i = 1;
var s = "Hello";
String s = "Hello";
var console = new Scanner(System.in);
Scanner console = new Scanner(System.in);
var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
var data = new int[]{1, 2, 3};
int[] data = new int[]{1, 2, 3};

编译器本身根据分配给它的值来确定或推断变量的类型。

程序员们就是否要在语言中添加这样的特性展开了激烈的争论。许多人担心它var会被滥用,从而影响代码的可读性。

这有一定的道理,所以最好var在它增加代码可读性的地方使用。例如,这些在两种情况下:

Case 1: 看变量赋值,变量类型一目了然

代码 解释
var stream = url.getInputStream();
变量是一个InputStream
var name = person.getFullName();
变量是String

在这些情况下,您不应该使用var. 那么,变量的类型是什么?

代码 解释
var result = task.execute();
很难确定变量的类型
var status = person.getStatus();
很难确定变量的类型

情况 2:变量的类型对于理解代码并不重要

代码通常不需要调用变量的方法,例如,当变量仅用于临时存储某些内容时。在这种情况下,使用var绝对不会降低代码的可读性:

长码 代码紧凑
var data = stream.getMetaData();
storage.save(data)
我们从流中获取元数据stream并将其保存在storage存储库中。变量data的特定类型并不重要。

中庸之道

现在我将给出三种编写相同代码的方法。使用var将是最好的选择。

代码 笔记
dest.writeHeaderInfo(src.getFileMetaInfo());
太紧凑
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
正好
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
太详细了

从 1 行版本转移到 2 行版本,我们通过使用变量名 ( ) 使代码更具可读性headerInfo。现在很明显,该方法不仅返回元信息,还返回标头信息。

第三个版本过于冗长。从方法中已经很清楚headerInfois的事实。元信息的用途更有趣。FileMetaInfogetFileMetaInfo()



3.用菱形运算符省略类型:<>

甚至在var运算符出现之前,就有人尝试教编译器如何推断集合类型。你会同意这个符号看起来有点多余:

ArrayList<String> list = new ArrayList<String>();

从Java第七版开始,在写集合类型时,如果声明变量时指定了集合元素的类型,则可以省略。也就是说,上面的代码可以写成稍微简化的形式:

ArrayList<String> list = new ArrayList<>();

如您所见,您不再需要第二次编写 String。不像 var 运算符那么酷,但在当时看来是进步了。

集合类型中的空尖括号被称为菱形运算符,因为两个尖括号隐约类似于菱形。

同时使用var关键字和菱形运算符 是不可取的:

var list = new ArrayList<>();

根本没有关于集合中存储的元素类型的信息,集合类型将ArrayList <Object> 。



4.双花括号

还记得快速数组初始化吗?

我们只是在大括号中列出了值,如下所示:

例子
int[] data = new int[] {1, 2, 3, 4, 5, 6, 7};
int[] data = {1, 2, 3, 4, 5, 6, 7};

Java 的创造者喜欢使用花括号来简化数组元素的编写的想法。但是集合呢?

Java 的创造者对集合也有足够的创造性思维,允许他们使用双花括号的技巧。

加糖 不加糖
var list = new ArrayList<String>()
{{
   add("Hello");
   add("How's");
   add("Life?");
}};
var list = new ArrayList<String>();

list.add("Hello");
list.add("How's");
list.add("Life?");

如果编译器遇到左侧示例中的代码,则会将其转换为右侧的代码。

代码并没有变得更紧凑。这里的节省是微不足道的:您不必list每次都写。如果变量名很长,这会很有帮助。

但是,如果您在项目中遇到这样的代码,请不要感到惊讶 🙂