Kotlin_属性自动生成方法所引发问题

在Kotlin中创建一个属性,如果是val,那么会自动生成getter方法,如果是var,那么会自动生成gettersetter方法。

1
2
3
4
class MethodFoo() {
var a: Int = 1
var b: Int = 2
}

生成的class内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class MethodFoo {
private int a = 1;
private int b = 2;

public final int getA() {
return this.a;
}

public final void setA(int var1) {
this.a = var1;
}

public final int getB() {
return this.b;
}

public final void setB(int var1) {
this.b = var1;
}
}

自动生成getset

在开发的时候,经常会用到一些常量,而常量一般放在一个公共的类里面,在Kotlin中,我们是这样写的:

1
2
3
4
5
6
7
8
9
10
11
12
object Constant {
val ACTION_FINDVIEWBYID = "FindViewById"
val ACTION_BUTTERKNIFE = "ButterKnife"
val SELECTED_TEXT_SUFFIX = ".xml"
val PSI_METHOD_BY_ONCREATE = "onCreate"
val PSI_METHOD_BY_ONCREATEVIEW = "onCreateView"
val CREATOR_COMMAND_NAME = "Generate Injections"
val CLASS_TYPE_BY_ACTIVITY = "activity"
val CLASS_TYPE_BY_FRAGMENT = "fragment"
val FIELD_ON_CLICK = "OnClick"
val FIELD_ONCLICK = "onClick"
}

生成的代码是这样的:

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

public final class Constant {
@NotNull
private static final String ACTION_FINDVIEWBYID = "FindViewById";
@NotNull
private static final String ACTION_BUTTERKNIFE = "ButterKnife";
@NotNull
private static final String SELECTED_TEXT_SUFFIX = ".xml";
@NotNull
private static final String PSI_METHOD_BY_ONCREATE = "onCreate";
@NotNull
private static final String PSI_METHOD_BY_ONCREATEVIEW = "onCreateView";
@NotNull
private static final String CREATOR_COMMAND_NAME = "Generate Injections";
@NotNull
private static final String CLASS_TYPE_BY_ACTIVITY = "activity";
@NotNull
private static final String CLASS_TYPE_BY_FRAGMENT = "fragment";
@NotNull
private static final String FIELD_ON_CLICK = "OnClick";
@NotNull
private static final String FIELD_ONCLICK = "onClick";
public static final Constant INSTANCE;

@NotNull
public final String getACTION_FINDVIEWBYID() {
return ACTION_FINDVIEWBYID;
}

@NotNull
public final String getACTION_BUTTERKNIFE() {
return ACTION_BUTTERKNIFE;
}

@NotNull
public final String getSELECTED_TEXT_SUFFIX() {
return SELECTED_TEXT_SUFFIX;
}

@NotNull
public final String getPSI_METHOD_BY_ONCREATE() {
return PSI_METHOD_BY_ONCREATE;
}

@NotNull
public final String getPSI_METHOD_BY_ONCREATEVIEW() {
return PSI_METHOD_BY_ONCREATEVIEW;
}

@NotNull
public final String getCREATOR_COMMAND_NAME() {
return CREATOR_COMMAND_NAME;
}

@NotNull
public final String getCLASS_TYPE_BY_ACTIVITY() {
return CLASS_TYPE_BY_ACTIVITY;
}

@NotNull
public final String getCLASS_TYPE_BY_FRAGMENT() {
return CLASS_TYPE_BY_FRAGMENT;
}

@NotNull
public final String getFIELD_ON_CLICK() {
return FIELD_ON_CLICK;
}

@NotNull
public final String getFIELD_ONCLICK() {
return FIELD_ONCLICK;
}

private Constant() {
INSTANCE = (Constant)this;
ACTION_FINDVIEWBYID = "FindViewById";
ACTION_BUTTERKNIFE = "ButterKnife";
SELECTED_TEXT_SUFFIX = ".xml";
PSI_METHOD_BY_ONCREATE = "onCreate";
PSI_METHOD_BY_ONCREATEVIEW = "onCreateView";
CREATOR_COMMAND_NAME = "Generate Injections";
CLASS_TYPE_BY_ACTIVITY = "activity";
CLASS_TYPE_BY_FRAGMENT = "fragment";
FIELD_ON_CLICK = "OnClick";
FIELD_ONCLICK = "onClick";
}

static {
new Constant();
}
}

这….生成了那么多的get方法,如果我有100个字段,那么就多生成了100个get方法,我只是想要Constant.fieldName这样子调用这个字段而已,根本不需要用到get,这样明显是创建了多余的方法,方法数增多容易报65535错。

如何避免生成

在Kotlin中,可以使用两种方法来停止自动生成getset方法。

使用const关键字

1
2
3
4
5
6
7
8
9
10
11
12
object Constant {
const val ACTION_FINDVIEWBYID = "FindViewById"
const val ACTION_BUTTERKNIFE = "ButterKnife"
const val SELECTED_TEXT_SUFFIX = ".xml"
const val PSI_METHOD_BY_ONCREATE = "onCreate"
const val PSI_METHOD_BY_ONCREATEVIEW = "onCreateView"
const val CREATOR_COMMAND_NAME = "Generate Injections"
const val CLASS_TYPE_BY_ACTIVITY = "activity"
const val CLASS_TYPE_BY_FRAGMENT = "fragment"
const val FIELD_ON_CLICK = "OnClick"
const val FIELD_ONCLICK = "onClick"
}

来看一下编译后的内容

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
public final class Constant {
@NotNull
public static final String ACTION_FINDVIEWBYID = "FindViewById";
@NotNull
public static final String ACTION_BUTTERKNIFE = "ButterKnife";
@NotNull
public static final String SELECTED_TEXT_SUFFIX = ".xml";
@NotNull
public static final String PSI_METHOD_BY_ONCREATE = "onCreate";
@NotNull
public static final String PSI_METHOD_BY_ONCREATEVIEW = "onCreateView";
@NotNull
public static final String CREATOR_COMMAND_NAME = "Generate Injections";
@NotNull
public static final String CLASS_TYPE_BY_ACTIVITY = "activity";
@NotNull
public static final String CLASS_TYPE_BY_FRAGMENT = "fragment";
@NotNull
public static final String FIELD_ON_CLICK = "OnClick";
@NotNull
public static final String FIELD_ONCLICK = "onClick";
public static final Constant INSTANCE;

private Constant() {
INSTANCE = (Constant)this;
}

static {
new Constant();
}
}

使用@JvmField注解

1
2
3
4
5
6
7
8
9
10
11
12
object Constant {
@JvmField val ACTION_FINDVIEWBYID = "FindViewById"
@JvmField val ACTION_BUTTERKNIFE = "ButterKnife"
@JvmField val SELECTED_TEXT_SUFFIX = ".xml"
@JvmField val PSI_METHOD_BY_ONCREATE = "onCreate"
@JvmField val PSI_METHOD_BY_ONCREATEVIEW = "onCreateView"
@JvmField val CREATOR_COMMAND_NAME = "Generate Injections"
@JvmField val CLASS_TYPE_BY_ACTIVITY = "activity"
@JvmField val CLASS_TYPE_BY_FRAGMENT = "fragment"
@JvmField val FIELD_ON_CLICK = "OnClick"
@JvmField val FIELD_ONCLICK = "onClick"
}

来看一下编译后的内容

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
public final class Constant {
@JvmField
@NotNull
public static final String ACTION_FINDVIEWBYID = "FindViewById";
@JvmField
@NotNull
public static final String ACTION_BUTTERKNIFE = "ButterKnife";
@JvmField
@NotNull
public static final String SELECTED_TEXT_SUFFIX = ".xml";
@JvmField
@NotNull
public static final String PSI_METHOD_BY_ONCREATE = "onCreate";
@JvmField
@NotNull
public static final String PSI_METHOD_BY_ONCREATEVIEW = "onCreateView";
@JvmField
@NotNull
public static final String CREATOR_COMMAND_NAME = "Generate Injections";
@JvmField
@NotNull
public static final String CLASS_TYPE_BY_ACTIVITY = "activity";
@JvmField
@NotNull
public static final String CLASS_TYPE_BY_FRAGMENT = "fragment";
@JvmField
@NotNull
public static final String FIELD_ON_CLICK = "OnClick";
@JvmField
@NotNull
public static final String FIELD_ONCLICK = "onClick";
public static final Constant INSTANCE;

private Constant() {
INSTANCE = (Constant)this;
ACTION_FINDVIEWBYID = "FindViewById";
ACTION_BUTTERKNIFE = "ButterKnife";
SELECTED_TEXT_SUFFIX = ".xml";
PSI_METHOD_BY_ONCREATE = "onCreate";
PSI_METHOD_BY_ONCREATEVIEW = "onCreateView";
CREATOR_COMMAND_NAME = "Generate Injections";
CLASS_TYPE_BY_ACTIVITY = "activity";
CLASS_TYPE_BY_FRAGMENT = "fragment";
FIELD_ON_CLICK = "OnClick";
FIELD_ONCLICK = "onClick";
}

static {
new Constant();
}
}

后记

当我们使用Kotlin定义大量的公共字段的时候,一定要这样写来避免方法数过多。

感谢Kotlin属性引发的方法数问题