Java基础进阶系列-01之常量

一、怎样才算是常量

即需要具备怎样的特点,就可以称之为常量

  • final关键字修饰

常量的特性

  • 只能被赋值一次,赋值后值不再改变

  • 对基本类型使用final关键字不能改变的是其数值

    对于对象引用,不能改变的是其引用,而对象本身是可以修改的

关于静态常量

通过final关键字来声明常量,配合static关键字进行修饰,该常量则为静态常量,语法格式如下:

权限修饰符 static final 数据类型 常量名 = 常量值;

// 升序排序
public static final String ORDER_ASC = "ascending";

数据类型可以是基本数据类型,也可以是对象类型

二、定义常量的几种方式

接口常量

  • 在interface中定义的常量默认是public static final类型
  • 当接口用于实现或者继承的,如果我们在实现类或者子类接口中定义了同名的常量,那么引用实现类或者子类接口同名的常量,容易造成混乱

  • 与接口的设计理念不相符,接口是一种规范,主要用来定义必须要实现的API接口,而不是暴露过多信息

  • 源码参考:

com.baomidou.mybatisplus.core.toolkit.Constants
com.alibaba.nacos.common.constant.HttpHeaderConsts
/**
 * 描述 : 性别接口常量.
 *
 * @author : MoCha
 * @version : v1
 * @date : 2020-09-23 22:06
 */
public interface GenderConstants {
    /**
     * 男性
     */
    int MALE = 1;

    /**
     * 女性
     */
    int FEMALE = 2;
}

类常量

final修饰的类,不能被继承,但可以继承其他类,也可以实例化

public final class StringBuffer extends AbstractStringBuilder
 implements java.io.Serializable, CharSequence {}
  • 如果常量类不想被继承或其他用途,可定义为public final class 类名 {},来保证不会被继承

  • 私有化常量类构造方法,保证该类不会被外部实例化

  • 源码参考:

java.nio.charset.StandardCharsets
com.alibaba.csp.sentinel.slots.block.RuleConstant
org.springframework.cloud.netflix.zuul.filters.support.FilterConstants
/**
 * 描述 : 权限类常量.
 * <p>
 * 说明:
 * 1. final关键字修饰类,保证该类不会被继承
 * 2. 私有化构造方法,保证该类不会被外部实例化
 *
 * @author : MoCha
 * @version : v1
 * @date : 2020-09-23 22:08
 */
public final class PermissionConstants {
    /**
     * 菜单权限
     */
    public static final int MENU = 1;

    /**
     * 按钮权限
     */
    public static final int BUTTON = 2;

    /**
     * 阻止实例化
     * <p>
     * Prevents instantiation
     */
    private PermissionConstants() {
    }
}

枚举常量

JLS(Java Language Specification,Java语言规范)提倡枚举项全部大写,字母之间用下划线分隔,这也是从常量的角度考虑的

  • 枚举类型(enum type)是指由一组固定的常量组成合法的类型

  • 枚举类不会被继承。因为JVM在生成枚举类时,将它声明为final

  • 枚举类不允许去继承类。JVM在生成枚举类时已经继承了Enum类,由于Java是单继承,不支持再继承额外的类(唯一的继承位置被Enum类占用了)

  • 枚举类的特性,既不能继承其他类,也不能被实例化,相当于是类常量的final修饰+私有实例化操作

  • Java 中提供了两个方便操作enum的工具类-EnumSet 和 EnumMap

  • 源码参考:

com.baomidou.mybatisplus.core.enums.WrapperKeyword
/**
 * 描述 : 结果状态枚举常量.
 *
 * @author : MoCha
 * @version : v1
 * @date : 2020-09-24 08:26
 */
@Getter
@AllArgsConstructor
public enum ResultStatusEnum {
    /**
     * 请求成功
     */
    SUCCESS(200, "请求成功!"),

    /**
     * 服务器异常
     */
    INTERNAL_SERVER_ERROR(500, "服务器睡着了!");

    private final Integer code;

    private final String message;
}

三、关于常量的几个深度思考

  • 常量作为参数时,是String,int等弱类型,开发人员可以传入没有在常量中里定义的值,这个问题无法通过编译器发现
  • 静态常量不支持字段扩展,每一个key对应一个值,而enum的每一个key可以拥有自己的字段
  • 局部常量与静态常量的区别是?
  • String为什么是不可变的,是因为final关键字的原因吗?

四、定义常量的最佳实践

  • 一、不允许任何魔法值(即未经预先定义的常量)直接出现在代码中

  • 二、在 long 或者 Long 赋值时,数值后使用大写字母 L,不能是小写字母 l,小写容易跟数字混淆,造成误解

    例如:Long a = 2l; 写的是数字的 21,还是 Long 型的 2?

  • 三、不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护

  • 四、子工程内部共享常量:即在当前子工程的 constant 目录下

  • 五、包内共享常量:即在当前包下单独的 constant 目录下

  • 六、类内共享常量:直接在类内部 private static final 定义

  • 七、强关联的常量推荐用枚举定义,其他类似于SUCCESS,或者YES等常量可用类常量来定义,不推荐用接口常量

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值