Java 中一个典型的枚举类型,看似字符串值,但包含一些附加的信息,包括排序以及附加的方法可以获取枚举值的信息。
下面是一个基本的枚举类型:
- public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
可增加附加信息,例如私有构造器、私有属性等,如下:
- public enum Numbers {
- One(1), Two(2), Three(3);
-
- private Numbers(int value)
- {
- this.value = value;
- }
-
- public int getValue()
- {
- return this.value;
- }
-
- private int value;
- }
在上面的例子中,我们引入了 getValue() 方法,这便是枚举的行为定义。
接下来我们要做的是枚举类型对接口的继承以及实际的用途。
为了显示工作过程,我们首先做一个接口,用来实现类和数据库表的一个映射:
- public interface DatabaseMapping {
- public String getType();
- public boolean isKey();
- public boolean isNullable();
- //public String name();
- }
name() 方法这个时候被注释掉,待会我们会取消注释。
接下来我们创建一个新的 Java 类用以定义和数据库之间的映射关系:
- public class Person {
- public String getFirstname() {
- return firstname;
- }
- public void setFirstname(String firstname) {
- this.firstname = firstname;
- }
- public String getLastname() {
- return lastname;
- }
- public void setLastname(String lastname) {
- this.lastname = lastname;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- private String firstname;
- private String lastname;
- private int age;
- }
然后我意识到了,其实有更好的方法来映射一个类到数据库表,上面这个例子很做作。当我们定义了映射到表的类时,我们需要定义一个独立的映射类,但实际上用枚举更好,数据库表中的字段可以是枚举的成员。
例如下面这样写不是更简单吗?
- public enum PersonMapping {
- personId, firstname, lastname, age;
- }
而且我们可以通过给枚举类型附加一些方法来实现数据库映射的细节:
- public enum PersonMapping {
- personId("INTEGER", true, false),
- firstname("TEXT", false, false),
- lastname("TEXT", false, false),
- age("INTEGER", false, false);
- private PersonMapping(String type, boolean key, boolean nullable )
- {
- this.type = type;
- this.key = key;
- this.nullable = nullable;
- }
- public String getType() {
- return type;
- }
- public boolean isKey() {
- return key;
- }
- public boolean isNullable() {
- return nullable;
- }
- private final String type;
- private final boolean key;
- private final boolean nullable;
- }
现在我们可以使用这个枚举来迭代所有字段并创建相应的表:
- public String dbTableCreate(String tableName) {
- StringBuilder builder = new StringBuilder("Create table ");
- builder.append(tableName);
- builder.append("(");
- for (PersonMapping column : PersonMapping.values()) {
- builder.append(column.name());
- builder.append(" ");
- builder.append(column.getType());
- builder.append(column.isKey() ? " primary key" : "");
- builder.append(", ");
- }
- builder = new StringBuilder(builder.substring(0, builder.length() - 2));
- builder.append(");");
- return builder.toString();
- }
这个 PersonMapping 枚举类型看起来不错,但是它不允许我们使用不同的类到数据库的映射,因此我们需要抽象,需要接口。从上面的代码看,我们需要枚举类型两个通过的方法:name() 和 values(),第一个方法返回当前枚举值的名字,第二个就是列出所有的枚举值。
首先,我们为枚举添加一个接口:
- public enum PersonMapping implements MappingEnum{
- ....
- }
然后注释掉我们前面提到的 name() 方法:
- public interface MappingEnum {
- public String getType();
- public boolean isKey();
- public boolean isNullable();
- public String name();
- }
最后我们编写一个 dbTableCreate() 方法来让其他的枚举类型可重用这个方法:
- dbTableCreate("tableName", PersonMapping.values()));
完整的方法:
- public String dbTableCreate(String tableName, MappingEnum[] values) {
- StringBuilder builder = new StringBuilder("Create table ");
- builder.append(tableName);
- builder.append("(");
- for (MappingEnum column : values) {
- builder.append(column.name());
- builder.append(" ");
- builder.append(column.getType());
- builder.append(column.isKey() ? " primary key" : "");
- builder.append(", ");
- }
- builder = new StringBuilder(builder.substring(0, builder.length() - 2));
- builder.append(");");
- return builder.toString();
- }
讲解就到此结束,我们得出了一些结论:
- 枚举类型可以存储附加的数据和方法
- 枚举类型可通过接口来定义行为
- 枚举类型的项行为可通过接口来访问,跟正常的 Java 类无异
- values() 方法可用来返回接口中的一个数组
总而言之,你可以像使用普通 Java 类一样来使用枚举类型。