0. 好记性不如烂笔头
工作这些年,没有很好的整理java相关知识点,从今天开始陆续整理。
1. switch支持使用字符串
jdk7之前switch语句只能使用Integer及与之兼容的类型做分支判断,比如char,short,byte,和对应的包装类Character,Short,Byte;而jdk7则支持使用字符串,如:
public class StringSwitch {
public static Integer getCode(String name) {
Integer code;
switch (name) {
case "苹果":
code = 1;
break;
case "香蕉":
code = 2;
break;
default:
code = 0;
}
return code;
}
public static void main(String[] args){
System.out.println(getCode("苹果"));
System.out.println(getCode("香蕉"));
System.out.println(getCode("梨子"));
}
}
这一特性是在编译器层面实现的,我们可以通过IDEA反编译看到,其实编译器使用String的hashCode做为判断条件,再加上String的equals:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
public class StringSwitch {
public StringSwitch() {
}
public static Integer getCode(String name) {
byte var3 = -1;
switch(name.hashCode()) {
case 1065923:
if (name.equals("苹果")) {
var3 = 0;
}
break;
case 1253072:
if (name.equals("香蕉")) {
var3 = 1;
}
}
Integer code;
switch(var3) {
case 0:
code = 1;
break;
case 1:
code = 2;
break;
default:
code = 0;
}
return code;
}
public static void main(String[] args) {
System.out.println(getCode("苹果"));
System.out.println(getCode("香蕉"));
System.out.println(getCode("梨子"));
}
}
另,代码中的魔法值,应该使用enum来维护。
2. 数值字面量增强
jdk7之前紧支持十、十六、八进制,而jdk7增加了二进制的支持,并且允许在数值之前增加下划线“_”分隔,这样便于阅读,注意:不能添加在前后,如果在前面添加下划线,那就会歧义,如:_123表示为数值还是为一变量。
public class NumericLiteral {
public static void main(String[] args) {
System.out.println(123_456_789);
System.out.println(0123_456_7);
System.out.println(0xa23_456);
System.out.println(0b100__010_0010);
}
}
3. 异常处理优化
3.1 一个catch子句能捕获多个异常
public class CatchMutiException {
public static void main(String[] args) {
try {
System.out.println(1 / 0);
} catch (ArithmeticException | NullPointerException | NumberFormatException ex) {
// ex = null; // 会编译错误
ex.printStackTrace();
}
}
}
捕获的异常多余1个时,ex变量就隐式为final的变量,不能再重新赋值。并且多个异常间不能有父子类关系,其实也可以理解,如若为父子类关系,那其实可以去掉子类异常的捕获了。
3.2 重新抛出异常精准检查
重新捕获异常时,会检查该异常是否能被抛出,而jdk7之前是不会检查的。
如下的代码会编译失败,因为从throwException方法的声明不会抛出CloneNotSupportedException 异常,但可能会抛出NumberFormatException,虽然没有声明,这也就是说只会对受检异常做分析,而非受检异常是无法分析出是否会抛出的。
public class MultiExceptionTypeChecking {
public static void throwException() throws IOException, ClassNotFoundException {
}
public static void main(String[] args) {
try {
throwException();
} catch (CloneNotSupportedException | NumberFormatException | IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3.3 Throwable增加addSuppressed、getSuppressed
public class ReadFile {
public void read(String filename) throws IOException {
FileInputStream input = null;
IOException readException = null;
try {
input = new FileInputStream(filename);
} catch (IOException ex) {
readException = ex;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException ex) {
if (readException != null) {
readException.addSuppressed(ex);
}
else {
readException = ex;
}
}
}
if (readException != null) {
throw readException;
}
}
}
}
4. try-catch-resouces
jdk7之前需要在finally语句对socket、文件、数据库连接等资源关闭,jdk7后,只有继承AutoCloseable接口就能使用try-catch-resouces语句自动关闭。
public class ResourceBasicUsage {
public String readFile(String path) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(String.format("%n"));
}
return builder.toString();
}
}
}
如果使用资源和close都抛异常时,则抛出的是使用资源的异常,并对close的异常addSuppressed;若只有close抛出异常时,则捕获到的是close的异常,这会影响整体的业务受继续执行,所以一般情况,只记录close时的异常,而不抛出,如:
public class ReadFile {
public void read(String filename) throws BaseException {
FileInputStream input = null;
IOException readException = null;
try {
input = new FileInputStream(filename);
} catch (IOException ex) {
readException = ex;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException ex) {
if (readException == null) {
ex.printStackTrace(); // 打印异常
}else{
readException.addSuppressed(ex);
}
}
}
if (readException != null) {
throw new BaseException(readException);
}
}
}
}
5. 泛型初始化语句推测
Map<String, List<String>> map = new HashMap<>();
网友评论