Idea 使用小技巧

从一开始的Eclipse,到MyEclipse,最后到idea,大致是我使用Java IDE的一个轨迹,而现在基本上是只有在使用idea进行Java开发了。作为一个IDE,无论是界面,还是代码提示和修改,亦或是对各种框架和工具的支持,方方面面,它都带给我特别多惊喜。故而在这里总结记录分享一点在使用idea时用到的特性和技巧。

区域折叠(Region Folding)

上学的时候接触过C#,它有三个特性给我留下了深刻印象。一个是Accessor,一个是patial class,还有一个就是#region指令。

region指令给出一段代码的描述,并且使我们可以在IDE中把它折叠起来!多棒的特性啊,提升代码可读性,让代码变得清晰美观,方便进行开发。

到了现在,工作中主要开发语言是Java,我经常遇到这样一些情况:

  1. 简单对象

    根据业务的不同,开发过程中可能出现POJOEntityPOVODTO等各种类。不管这些词的严格定义是什么,他们一定都是用于承载数据的。所以这个特点决定了它可能会拥有大量的属性,所以同时会有大量的getter/setter,可能也会有很多不同的constructor。此外还会有重载的toStringhashCodeequals函数。这些函数在完成以后,几乎很少再去浏览他们,浏览最多的还是类的属性,注解以及一些自定义的转换函数。

  2. 工具类

    一个工具类中,可能会有大量函数。而很多函数功能/目的/类型一样。就比如一个StringUtils里,可能会有一些函数是用来进行字符串替换的。而另一部分可能是用来处理不同字符集的。

  3. 复杂函数

    不管怎么强调单一职责,面对一些复杂的业务场景,或者复杂的算法计算时,一个函数还是可能会变得非常冗长,导致代码可读性和开发效率降低。

而区域折叠,则可以解决这些问题!

idea中,选中一段代码,右键->Folding->Folding Selection/Remove region,这段代码就被折叠起来了。和其他被折叠的函数和类一样,鼠标悬浮就能看到折叠的内容。并且idea在行号出添加了一个小+按钮,之后可以通过按钮来进行代码折叠/展开。

这个操作的默认快捷键应该是Ctrl-.

链式Setter

记得第一次接触到链式调用,是在大学的Android课。犹记得是一段属性设置的代码,直接inst.afoo(a).bfoo(b).cfoo(c1, c2)...就完成了,让我只能用一个字描述,那就是爽!

idea能够直接生成这样的setter:

如上图,在Template中直接选择Builder即可。对于上面的这几个属性,生成的setter如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public HeatTemp setLng(float lng) {
this.lng = lng;
return this;
}

public HeatTemp setLat(float lat) {
this.lat = lat;
return this;
}

public HeatTemp setCount(int count) {
this.count = count;
return this;
}

这样我们就可以一set到底了。

自定义Getter/Setter

虽然idea自带了链式setter的模板,但是还是不能让我满意。

一直我都不太喜欢所谓的JavaBeanName规范。所以,在一些不会引起冲突和错误的地方,我会优先使用自己习惯的命名方式:

1
2
3
4
5
// in class A
private int value; // property
public int value(); // getter
public int value(int v); // setter
public A value(int v); // chain setter

还好,idea在很多地方能够自定义模板,这也包括了getter/setter的生成。

在生成getter/setter时,点击Template后方按钮,可以进行自定义模板。

我的Getter模板如下:

1
2
3
4
5
6
7
8
#if($field.modifierStatic)
static ##
#end
$field.type ##
${field.name}##
() {
return $field.name;
}

Setter模板如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#set($paramName = $helper.getParamName($field, $project))
public ##
#if($field.modifierStatic)
static ##
void ##
#else
${class.name} ##
#end
$paramName($field.type $paramName) {##
#if ($field.name == $paramName)
#if (!$field.modifierStatic)
this.##
#else
$classname.##
#end
#end
$field.name = $paramName;
#if(!$field.modifierStatic)
return this;
#end
}

生成的代码大致是这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class Sample {
long id;
String name;
Color color;
Point location;
static Double threshold;

public long id() {
return id;
}

public Sample id(long id) {
this.id = id;
return this;
}

public String name() {
return name;
}

public Sample name(String name) {
this.name = name;
return this;
}

public Color color() {
return color;
}

public Sample color(Color color) {
this.color = color;
return this;
}

public Point location() {
return location;
}

public Sample location(Point location) {
this.location = location;
return this;
}

public static Double threshold() {
return threshold;
}

public static void threshold(Double threshold) {
Sample.threshold = threshold;
}
}