All the Ways Java Uses the Colon Character – Java 使用冒号字符的所有方法

最后修改: 2023年 12月 5日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.导言

Many programming languages use the colon character (:) for various purposes. For example, C++ uses it with access modifiers and class inheritance, and JavaScript uses it with object declarations. The Python language relies on it heavily for things like function definitions, conditional blocks, loops, and more.

许多编程语言都将冒号字符(:)用于各种用途。例如,C++ 在访问修饰符和类继承中使用冒号,JavaScript 在对象声明中使用冒号。Python 语言在函数定义、条件块、循环等方面也非常依赖冒号。

And it turns out Java has a lengthy list of places where the colon character shows up as well. In this tutorial, we’ll look at them all.

而事实证明,Java 有一个很长的列表,其中也包含冒号字符。在本教程中,我们将一一介绍。

2. Enhanced for Loop

2.增强型 for 循环

The for loop is one of the first control statements programmers learn in any language. Here’s its syntax in Java:

在任何语言中,for循环都是程序员最先学会的控制语句之一。下面是它在 Java 中的语法:

for (int i = 0; i < 10; i++) {
    // do something
}

Among other things, this control structure is perfect for iterating through the items in a collection or an array. In fact, this use case is so common that in Java 1.5, the language introduced a more compact form known as the for-each loop.

除其他外,这种控制结构非常适合遍历集合或数组中的项目。事实上,这种使用情况非常普遍,以至于在 Java 1.5 中,该语言引入了一种更紧凑的形式,称为 for-each 循环

Below is an example of iterating through an array using the for-each syntax:

下面是一个使用 for-each 语法遍历数组的示例:

int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i : numbers) {
    // do something
}

Here we can notice the colon character. We should read this as “in”. Thus, the loop above can be thought of as “for every integer i in numbers”.

在这里,我们可以注意到冒号字符。我们应该将其理解为 “in”。因此,上面的循环可以理解为 “对于 numbers 中的每一个整数 i”。

In addition to arrays, this syntax can also be used for Lists and Sets:

除数组外,该语法还可用于 Lists 和 Sets :

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
for (Integer i : numbers) {
    // do something
}

The goal of the for-each loop is to eliminate the boilerplate associated with standard for loops and, thus, the chance of error that comes with it. However, it does so by sacrificing some functionality like skipping indices, reverse iterating, and more.

for-each 循环的目标是消除与标准 for 循环相关的模板,从而减少出错的机会。但是,这样做会牺牲一些功能,如跳过索引、反向迭代等。

3. switch Statement

3.开关声明

The next place we find the colon character in Java is in a switch statement. The switch statement is a more readable, and often more compact, form of if/else blocks.

我们在 Java 中发现冒号字符的下一个地方是 switch 语句开关语句是 if/else 块的一种可读性更强、通常也更紧凑的形式

Let’s take a look at an example:

让我们来看一个例子:

void printAnimalSound(String animal) {
    if (animal.equals("cat")) {
        System.out.println("meow");
    }
    else if (animal.equals("lion")) {
        System.out.println("roar");
    }
    else if (animal.equals("dog") || animal.equals("seal")) {
        System.out.println("bark");
    }
    else {
        System.out.println("unknown");
    }
}

This same set of statements can be written using a switch statement:

同样的语句集可以使用 switch 语句编写:

void printAnimalSound(String animal) {
    switch(animal) {
        case "cat":
            System.out.println("meow");
            break;
        case "lion":
            System.out.println("roar");
            break;
        case "dog":
        case "seal":
            System.out.println("bark");
            break;
        default:
            System.out.println("unknown");
    }
}

In this case, the colon character appears at the end of each case. However, this is only true for traditional switch statements. In Java 12, the language added an expanded form of switch that uses expressions. In that case, we use the arrow operator (->) instead of the colon.

在这种情况下,冒号字符会出现在每个 case 的末尾。但是,这只适用于传统的 switch 语句。在 Java 12 中,该语言添加了使用表达式的 switch 扩展形式。在这种情况下,我们使用箭头操作符 (->) 代替冒号

4. Labels

4.标签

One of the often-forgotten features of Java is labels. While some programmers may have bad memories of labels and their association with goto statements, in Java, labels have a very important use.

标签是 Java 中经常被遗忘的功能之一。一些程序员可能对标签及其与 goto 语句的关联记忆犹新,但在 Java 中,标签却有非常重要的用途。

Let’s consider a series of nested loops:

让我们来看看一系列嵌套循环:

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (checkSomeCondition()) {
            break;
        }
    }
}

In this case, the break keyword causes the inner loop to stop executing and return control to the outer loop. This is because, by default, the break statement returns control to the end of the nearest control block. In this case, that means the loop with the j variable. Let’s see how we can change the behavior with labels.

在这种情况下,break 关键字将导致内循环停止执行,并将控制权返回给外循环。这是因为,默认情况下,break 语句会将控制返回到最近的控制块的末尾。在本例中,这意味着带有 j 变量的循环。让我们看看如何通过标签来改变这种行为。

First, we need to rewrite our loops with labels:

首先,我们需要重写带有标签的循环:

outerLoop: for (int i = 0; i < 10; i++) {
    innerLoop: for (int j = 0; j < 10; j++) {
        if (checkSomeCondition()) {
            break outerLoop;
        }
    }
}

We have the same two loops, but each one now has a label:. One is named outerLoop, and the other is named innerLoop. We can notice that the break statement now has a label name following it. This instructs the JVM to transfer control to the end of that labeled statement rather than the default behavior. The result is that the break statement exits the loop with the i variable, effectively ending both loops.

我们有同样的两个循环,但现在每个循环都有一个标签:。一个名为 outerLoop, ,另一个名为 innerLoop。我们可以注意到,break 语句后面现在有一个标签名称。这指示 JVM 将控制权转移到该标签语句的末尾,而不是默认行为。结果是,break 语句带着 i 变量退出了循环,有效地结束了两个循环。

5. Ternary Operator

5.三元运算符

The Java ternary operator is a shorthand for simple if/else statements. Let’s say we have the following code:

Java 三元运算符是简单的 if/else 语句的简写。假设我们有以下代码:

int x;
if (checkSomeCondition()) {
    x = 1;
}
else {
    x = 2;
}

Using the ternary operator, we can shorten the same code:

使用三元运算符,我们可以缩短相同的代码:

x = checkSomeCondition() ? 1 : 2;

Additionally, the ternary operator works well alongside other statements to make our code more readable:

此外,三元运算符还能与其他语句配合使用,使我们的代码更加易读:

boolean remoteCallResult = callRemoteApi();
LOG.info(String.format(
  "The result of the remote API call %s successful",
  remoteCallResult ? "was" : "was not"
));

This saves us the extra step of assigning the result of the ternary operator to a separate variable, making our code more compact and easier to understand.

这样就省去了将三元运算符的结果赋值给一个单独变量的额外步骤,使我们的代码更紧凑,更容易理解。

6. Method References

6.方法参考

Introduced in Java 8 as part of the lambda project, method references also use the colon character. Method references show up in several places throughout Java, most notably with streams. Let’s see a few examples.

作为 lambda 项目的一部分,方法引用在 Java 8 中也使用了冒号字符。方法引用出现在 Java 中的多个地方,其中最明显的是 streams 。让我们来看几个示例。

Let’s say we have a list of names and want to capitalize each one. Prior to lambdas and method references, we might use a traditional for loop:

比方说,我们有一个名称列表,并希望将每个名称大写。在使用 lambdas 和方法引用之前,我们可能会使用传统的 for 循环:

List<String> names = Arrays.asList("ross", "joey", "chandler");
List<String> upperCaseNames = new ArrayList<>();
for (String name : names) {
  upperCaseNames.add(name.toUpperCase());
}

We can simplify this with a stream and method reference:

我们可以通过流和方法引用来简化这一过程:

List<String> names = Arrays.asList("ross", "joey", "chandler");
List<String> upperCaseNames = names
  .stream()
  .map(String::toUpperCase)
  .collect(Collectors.toList());

In this case, we’re using a reference to the toUpperCase() instance method in the String class as part of a map() operation.

在本例中,我们使用了对 String 类中 toUpperCase() 实例方法的引用,作为 map() 操作的一部分。

Method references are useful for filter() operations as well, where a method takes a single argument and returns a boolean:

方法引用对于过滤()操作也很有用,在这种操作中,方法接收一个参数并返回一个布尔值

List<Animal> pets = Arrays.asList(new Cat(), new Dog(), new Parrot());
List<Animal> onlyDogs = pets
  .stream()
  .filter(Dog.class::isInstance)
  .collect(Collectors.toList());

In this case, we’re filtering a list of different animal types using a method reference to the isInstance() method available for all classes.

在本例中,我们使用所有类都可用的 isInstance() 方法引用来筛选不同动物类型的列表。

Finally, we can also use constructors with method references. We do this by combining the new operator with the class name and method reference:

最后,我们还可以使用带有方法引用的构造函数。我们可以将 new 操作符与类名和方法引用结合起来使用:

List<Animal> pets = Arrays.asList(new Cat(), new Dog(), new Parrot());
Set<Animal> onlyDogs = pets
  .stream()
  .filter(Dog.class::isInstance)
  .collect(Collectors.toCollection(TreeSet::new));

In this case, we’re collecting the filtered animals into a new TreeSet instead of a List.

在这种情况下,我们将过滤后的动物收集到一个新的 TreeSet 中,而不是 List 中。

7. Assertions

7.断言

Another often overlooked feature of the Java language is assertions. Introduced in Java 1.4, the assert keyword is used to test a condition. If that condition is false, it throws an error.

Java 语言的另一个经常被忽视的功能是 断言。在 Java 1.4 中引入的 assert 关键字用于测试一个条件。如果该条件为 false,则会抛出错误。

Let’s look at an example:

我们来看一个例子:

void verifyConditions() {
    assert getConnection() != null : "Connection is null";
}

In this example, if the return value of the method getConnection() is null, the JVM throws an AssertionError. The String after the colon is optional. It allows us to provide a message as part of the error that gets thrown when the condition is false.

在此示例中,如果方法 getConnection() 的返回值为 ,JVM 将抛出 断言错误冒号后面的 String 是可选的。它允许我们在条件为false时抛出的错误中提供一条信息。

We should keep in mind assertions are disabled by default. To use them, we must enable them using the -ea command line argument.

我们应该记住,断言默认是禁用的。要使用断言,我们必须使用 -ea 命令行参数启用断言。

8. Conclusion

8.结论

In this article, we learned how Java uses the colon character in a variety of different ways. Specifically, we saw how the colon character is used with enhanced for loops, switch statements, labels, ternary operators, method references, and assertions.

在本文中,我们了解了 Java 如何以各种不同的方式使用冒号字符。具体来说,我们了解了冒号字符如何与增强型 for 循环、切换 语句、标签、三元运算符、方法引用和断言一起使用。

Many of these features have been around since the early days of Java, but several have been added as the language has changed and added new features.

其中许多功能在 Java 诞生之初就已存在,但随着语言的变化和新功能的增加,又增加了一些功能。

As always, the code examples above can be found over on GitHub.

与往常一样,您可以在 GitHub 上找到上述代码示例