编译检查(switch-case)
使用IDE时,可以自动检查是否漏写了break语句和default语句,方法是打开IDE的编译检查:
在Eclipse中,选择Preferences - Java - Compiler - Errors/Warnings - Potential programming problems,将以下检查标记为Warning:
'switch' is missing 'default' case
'switch' case fall-through
在Idea中,选择Preferences - Editor - Inspections - Java - Control flow issues,将以下检查标记为Warning:
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
当switch语句存在问题时,即可在IDE中获得警告提示。
Java12_switch改进
使用switch时,如果遗漏了break,就会造成严重的逻辑错误,而且不易在源代码中发现错误。从Java 12开始,switch语句升级为更简洁的表达式语法,使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break语句:
ps:注意新语法使用->,如果有多条语句,需要用{}括起来。不要写break语句,因为新语法只会执行匹配的语句,没有穿透效应。
public class Main { //output:Selected apple
public static void main(String[] args) {
String fruit = "apple";
switch (fruit) {
case "apple" -> System.out.println("Selected apple");
case "pear" -> System.out.println("Selected pear");
case "mango" -> {
System.out.println("Selected mango");
System.out.println("Good choice!");
}
default -> System.out.println("No fruit selected");
}
}
}
很多时候,我们还可能用switch语句给某个变量赋值。
int opt;
switch (fruit) {
case "apple":
opt = 1;
break;
case "pear":
case "mango":
opt = 2;
break;
default:
opt = 0;
break;
}
使用新的switch语法,不但不需要break,还可以直接返回值。
public class Main {
public static void main(String[] args) {
String fruit = "apple";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> 0;
}; // 注意赋值语句要以;结束
System.out.println("opt = " + opt);
}
}
还可以使用yield:
大多数时候,在switch表达式内部,我们会返回简单的值。
但是,如果需要复杂的语句,我们也可以写很多语句,放到{}里,然后,用yield返回一个值作为switch语句的返回值。
public class Main {
public static void main(String[] args) {
String fruit = "orange";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> {
int code = fruit.hashCode();
yield code; // switch语句返回值
}
};
System.out.println("opt = " + opt);
}
}
for each循环
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
}
}
和for循环相比,for each循环的变量n不再是计数器,而是直接对应到数组的每个元素。for each循环的写法也更简洁。但是,for each循环无法指定遍历顺序,也无法获取数组的索引。
除了数组外,for each循环**能够遍历所有“可迭代”**的数据类型,包括List、Map等。
字符编码
在早期的计算机系统中,为了给字符编码,制定了一套英文字母、数字和常用符号的编码,它占用一个字节,编码范围从0到127,最高位始终为0,称为ASCII编码。例如,字符’A’的编码是0x41,字符’1’的编码是0x31。
全球统一码联盟发布了Unicode编码,它把世界上主要语言都纳入同一个编码,这样,语言之间就不会冲突。
Unicode编码需要两个或者更多字节表示,我们可以比较中英文字符在ASCII、GB2312和Unicode的编码:
英文字符’A’的ASCII编码和Unicode编码:

中文字符’中’的GB2312编码和Unicode编码:

UTF-8又是什么编码呢?
因为英文字符的Unicode编码高字节总是00,包含大量英文的文本会浪费空间,所以,出现了UTF-8编码,它是一种变长编码,用来把固定长度的Unicode编码变成1~4字节的变长编码。通过UTF-8编码,英文字符’A’的UTF-8编码变为0x41,正好和ASCII码一致,而中文’中’的UTF-8编码为3字节0xe4b8ad。
UTF-8编码的另一个好处是容错能力强。如果传输过程中某些字符出错,不会影响后续字符,因为UTF-8编码依靠高字节位来确定一个字符究竟是几个字节,它经常用来作为传输编码。
Java的String和char在内存中总是以Unicode编码表示。
本文介绍了Java 12中switch语句的改进,包括使用新表达式语法、省略break、返回值赋值以及yield的使用。同时涵盖了foreach循环和字符编码基础知识。
938

被折叠的 条评论
为什么被折叠?



