本文整理一些Java开发中常用的惯用法。

instanceof测试类型实例

双目运算符,obj instanceof Type 测试它左边的对象是否是它右边的类的实例

if (list instanceof ArrayList) {
    //...
}

关于Comparable和Comparator

Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些 类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。

class Person implements Comparable<Person> {
  String firstName;
  String lastName;
  int birthdate;
  
  // Compare by firstName, break ties by lastName,
  // finally break ties by birthdate
  public int compareTo(Person other) {
    if (firstName.compareTo(other.firstName) != 0)
      return firstName.compareTo(other.firstName);
    else if (lastName.compareTo(other.lastName) != 0)
      return lastName.compareTo(other.lastName);
    else if (birthdate < other.birthdate)
      return -1;
    else if (birthdate > other.birthdate)
      return 1;
    else
      return 0;
  }
}

Comparator可以认为是是一个外比较器,有两种情况可以使用实现Comparator接口的方式:

  1. 一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较。
  2. 一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式。

Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

  1. o1大于o2,返回正整数
  2. o1等于o2,返回0
  3. o1小于o3,返回负整数
public class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person g1, Person g2) {
        return g1.getBirthdate() - g2.getBirthdate();
    }    
}

使用try-finally

如果try语句块里面的语句抛出异常,那么程序的运行就会跳到finally语句块里执行尽可能多的语句,然后跳出这个方法(除非这个方法还有另一个外围的finally语句块)。

// IO
void writeStuff() throws IOException {
  OutputStream out = new FileOutputStream(...);
  try {
    out.write(...);
  } finally {
    out.close();
  }
}

// 锁
void doWithLock(Lock lock) {
  lock.acquire();
  try {
    ...
  } finally {
    lock.release();
  }
}

流数据读写

从输入流里读取字节数据

read()方法要么返回下一次从流里读取的字节数(0到255,包括0和255),要么在达到流的末端时返回-1。

InputStream in = (...);
try {
  while (true) {
    int b = in.read();
    if (b == -1)
      break;
    (... process b ...)
  }
} finally {
  in.close();
}

从输入流里读取块数据

read()方法不一定会填满整个buf,所以你必须在处理逻辑中考虑返回的长度。

InputStream in = (...);
try {
  byte[] buf = new byte[100];
  while (true) {
    int n = in.read(buf);
    if (n == -1)
      break;
    (... process buf with offset=0 and length=n ...)
  }
} finally {
  in.close();
}

从文件里读取文本

BufferedReader in = new BufferedReader(
    new InputStreamReader(new FileInputStream(...), "UTF-8"));
try {
  while (true) {
    String line = in.readLine();
    if (line == null)
      break;
    (... process line ...)
  }
} finally {
  in.close();
}

向文件里写文本

PrintWriter out = new PrintWriter(
    new OutputStreamWriter(new FileOutputStream(...), "UTF-8"));
try {
  out.print("Hello ");
  out.print(42);
  out.println(" world!");
} finally {
  out.close();
}

参考