Java開發(fā)過程中往往需要編寫固定格式的代碼,比如聲明私有變量、logger或者bean等。對于這種小規(guī)模的代碼生成,我們可以使用IDEA提供的Live Templates功能。
1 背景
Java開發(fā)過程中往往需要編寫固定格式的代碼,比如聲明私有變量、logger或者bean等。對于這種小規(guī)模的代碼生成,我們可以使用IDEA提供的Live Templates功能。一開始我以為它只是一個簡單的Code Snippet,后來發(fā)現(xiàn)它支持變量函數(shù)配置,可以支持非常復雜的代碼生成。下面介紹一下Live Templates的用法。
2 基本使用
IDEA自帶很多常用的動態(tài)模板,在Java代碼中輸入fori,回車會出現(xiàn):
for (int i = 0; i < ; i++) {
}
按 T?ab 跳入每個空白并手動填寫值。

更多 IDEA 操作如下:
public class Example {
// geti 生成單例語句
public static Example getInstance() {
return new Example();
}
// prsf 生成 private static final
private static final ...;
// psf 生成 public static final
public static final ...;
// psfi 生成 public static final int
public static final int ...;
// psfs 生成 public static final String
public static final String ...;
// main 或者 psvm 生成 main 函數(shù)
public static void main(String[] args) {
// fori 生成 for 循環(huán)
for (int i = 0; i < 10; i++) {
}
// C 生成 Callable
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
}
};
// I 生成遍歷語句
for (Object o :) {
}
// ifn 生成 if null 語句
if (callable == null) {
}
// inn 生成 if not null 語句
if (callable != null) {
}
// inst 生成 instanceof 語句
if (callable instanceof Object) {
Object o = (Object) callable;
}
// itar 生成數(shù)組遍歷語句
for (int i = 0; i < args.length; i++) {
String arg = args[i];
}
// itco 生成 java.util.Collection 遍歷語句
for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) {
Object next = iterator.next();
}
// iten 生成 java.util.Enumeration 遍歷語句
while (enumeration.hasMoreElements()) {
Object nextElement = enumeration.nextElement();
}
// iter 生成 Iterable 或 數(shù)組 遍歷語句
for (String arg : args) {
}
// itit 生成 java.util.Iterator 遍歷語句
while (iterator.hasNext()) {
Object next = iterator.next();
}
// itli 生成 java.util.List 遍歷語句
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
}
// ittok 生成遍歷 token 的語句
for (StringTokenizer stringTokenizer = new StringTokenizer(); stringTokenizer.hasMoreTokens(); ) {
String s = stringTokenizer.nextToken();
}
// lazy 生成延遲初始化語句
if (callable == null) {
callable = new Callable<Object>();
}
// lst 生成獲取數(shù)組最后一個元素語句
args[args.length - 1];
// mn 生成 Math.min
min = Math.min(min, max);
// mx 生成 Math.max
max = Math.max(max, min);
// ritar 生成降序遍歷數(shù)組的語句
for (int i = args.length - 1; i >= 0; i--) {
String arg = args[i];
}
// RL 生成 ReadWriteLock.readLock()
ReadWriteLock.readLock().lock();
try {
} finally {
ReadWriteLock.readLock().unlock();
}
// serr 生成 System.err.println()
System.err.println();
// serrc 生成 System.err::println
System.err::println;
// souf 生成 System.out.printf("")
System.out.printf("");
// sout 生成 System.out.println()
System.out.println();
// soutc 生成 System.out::println
System.out::println;
// soutm 生成打印當前類和方法的語句
System.out.println("Example.main");
// soutp 生成打印當前方法的參數(shù)名字和值
System.out.println("args = " + Arrays.deepToString(args));
// soutv 生成打印一個值的語句
System.out.println("callable = " + callable);
// St 生成 String
String ;
// thr 生成 throw new
throw new;
// toar 生成 java.util.Collection 元素到數(shù)組的語句
.toArray(new Object[0]);
// WL 生成 WriteLock.writeLock() 語句
ReentrantReadWriteLock.WriteLock.writeLock().lock();
try {
} finally {
ReentrantReadWriteLock.WriteLock.writeLock().unlock();
}
}
}
3 自定義模板
畢竟官方內(nèi)置的模板不能滿足我們個人編碼風格的需求。Live Templates 提供了可變函數(shù)供我們自定義。
簡單用法
添加自定義模板,首先需要填寫觸發(fā)詞(即Abbreviation),描述可選,然后定義模板的上下文,點擊define選擇Java,這樣編輯Java的時候就會觸發(fā)當前模板,定義好上下文后,就可以填寫模板了。

比如定義一個私有變量:

通過輸入 privateField 就可以輸出以下代碼:
/**
* $COMMENT$
*/
@Getter
@Setter
private $TYPE$ $NAME$;
模板支持定義變量,$$包圍的字符代表一個變量。$END$ 是一個特殊的預定義變量,表示光標最后跳轉(zhuǎn)的位置。每個變量的位置都可以跳轉(zhuǎn)到。
4 進階用法
如果你用過vim的Code Sinppet插件,你會發(fā)現(xiàn)函數(shù)可以在模板中執(zhí)行,當然強大的Live Templates也支持,IDEA可以感知代碼的語義,比如參數(shù)當前編輯的功能。但這就是讓我們玩得開心的原因。我們從易到難探索模板函數(shù)的功能。

前面我們提到的變量可以綁定到函數(shù)上,配置方法如上圖所示。
聲明變量是一個常見的操作,尤其是需要聲明需要注解的變量時。注釋的時候,這些代碼寫起來很枯燥。這是我定義的模板:

聲明 logger 也是一個常見的操作?,F(xiàn)在我們使用一個函數(shù) className() 來實現(xiàn)。顧名思義,它的作用就是返回當前的類名。

5 總結(jié)
上面我們簡單介紹了常用的模板函數(shù)。其實IDEA還有很多其他的模板函數(shù)。有關(guān)詳細信息,請參閱創(chuàng)建和編輯模板變量。IDEA 是一個非常強大的工具。善用工具可以大大提高工作效率,把精力集中在關(guān)鍵的事情上,而不是把時間浪費在寫重復的代碼上。一些更高級的用法還有待發(fā)現(xiàn)。好好利用它,也可以省下很多重復寫代碼的時間。