引入
什么是Java常量?
参考:
常量
常量的声明是每一个项目中不可或缺的,常量的统一定义一直是一个java框架的关键所在,一个好的常量管理更有利于提高程序的开发效率和可维护性。
参考:
阿里Java编码规范
使用
在Java中如何创建常量?
- 通过interface来创建,接口默认创建的变量会被static、final修饰
- 在普通类中,通过static 、final修饰的变量
- 通过Enum来创建
接口常量
JDK1.5之前,没有枚举类,有的用的接口来实现系统中的常量,例如Java的swing中的SwingConstant:
/**
* A collection of constants generally used for positioning and orienting
* components on the screen.
*
* @author Jeff Dinkins
* @author Ralph Kar (orientation support)
*/
public interface SwingConstants {
/**
* The central position in an area. Used for
* both compass-direction constants (NORTH, etc.)
* and box-orientation constants (TOP, etc.).
*/
public static final int CENTER = 0;
//
// Box-orientation constant used to specify locations in a box.
//
/**
* Box-orientation constant used to specify the top of a box.
*/
public static final int TOP = 1;
/**
* Box-orientation constant used to specify the left side of a box.
*/
public static final int LEFT = 2;
/**
* Box-orientation constant used to specify the bottom of a box.
*/
public static final int BOTTOM = 3;
/**
* Box-orientation constant used to specify the right side of a box.
*/
public static final int RIGHT = 4;
//...
}
接口常量写起来方便,看着简介,但是想要让别人能知道每个常量的含义,就必须要写注释。如果常量很多的话,把所有的常量放到同一个接口里面也并不是很油耗。所以在接口里面定义静态内部类把不同的功能常量类进一步分类
public interface Route {
/**
* Tenant
*/
public static class Tenant {
public static final String EDIT = "/tenant/edit";
}
/**
* Machine
*/
public static class Machine {
public static final String EDIT = "/machine/edit";
public static final String CREAT = "/machine/create";
}
/**
* Project
*/
public static class Project {
public static final String EDIT = "/project/edit";
public static final String CREAT = "/project/create";
}
}
使用了接口的内部类分类以后,调用的时候更简单明确:
Route.Tenant.EDIT
Route.Poject.CREATE
常量类
public class ResponseCode {
/** 系统处理正常 */
public static final int SUCCESS_HEAD = 0;
/** 系统处理未知异常 */
public static final int EXCEPTION_HEAD = 1;
/** JSON解析错误 */
public static final int JSON_RESOLVE = 2;
/** 类型不匹配 */
public static final int TRANSTYPE_NO = 3;
/** Head - messageID未赋值 */
public static final int HEAD_messageID = 4;
public static final Map<Integer, String> RESP_INFO = new HashMap<Integer, String>();
static {
// Head 相关
RESP_INFO.put(SUCCESS_HEAD, "系统处理正常");
RESP_INFO.put(EXCEPTION_HEAD, "系统处理未知异常");
RESP_INFO.put(JSON_RESOLVE, "JSON解析错误");
RESP_INFO.put(TRANSTYPE_NO, "类型不匹配");
RESP_INFO.put(HEAD_messageID, "messageID未赋值");
}
}
该类常量用一个Map<Integer, String>来封装常量对应的信息,在static代码块里,类初始化的时候执行一次put。用的时候ResponseCode.RESP_INFO.get(DATABASE_EXCEPTION)取出相应信息。
枚举
首先看下代码示例,如下:
public enum MessageType {
SYSTEM_MESSAGE(1,"系统消息"),
COMMENT_MESSAGE(2,"评论消息"),
COLLECT_MESSAGE(3,"收藏消息");
private Integer code;
private String name;
MessageType(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode(){
return code;
}
public String getName(){
return name;
}
本质上Enum也是一个类,但是与类不同的是,Enum不能被集成,其主要用来定义指定业务概念的常量。
对比
常量
- 无法限制开发员继承/实现接口
- 常量作为参数时,是String,int等弱类型,开发员传入没有在常量接口里定义的值,这个问题无法通过编译器发现。
- 由于开发员可以直接写常量值, 所以不能用==对比,只能用equals对比,不能优化性能
- 编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译所有引用常量的类,因为里面存的是旧值
枚举
- 私有构造函数,避免被继承和扩展
- 定义方法的参数时,必须用枚举常量类类型,如上面的EnumClassA类型,这样就转变成了强类型,不会出现弱类型引起的问题
- 常量值地址唯一,可以用==直接对比,性能会有提高
- 编译时,没有把常量值编译到代码里,即使常量的值发生变化也不会影响引用常量的类
参考
Java 中的枚举 (enum)
JAVA常量类的实现方式_枚举类_项目实践
java架构篇之常量管理(枚举定义法)
java枚举的使用, 常量与枚举的区别
网友评论