java不允许未经定义的常量直接出现在代码中

不是报错,只是soanrqube检测觉得这样子不规范,这个也是阿里巴巴java编程手册中的一个规定,里面说法是不允许使用魔法值
java中,在使用sonarqube的时候,string类型的代码不允许直接使用未经定义的常量,什么是未经定义的产量呢?下面举个例子:

    //这个会报未经定义的常量
    String value = "常量";

一开始想到的解决方案是改成下面这个:

    //这样子就是定义了这个变量了,sonarqube也没有报错了
    String value = new String("常量");

但是里面有一个问题,那就是浪费内存。
浪费内存是,里面有两个对象,String value只是一个字符串变量,没有产生对象,new String(“常量”)不是原子操作,把它拆分为"常量"和new String(),首先会在字符串的常量池中查找有没有这个字符串"常量",没有找到就会创建一个字符串对象"常量"在元空间(JDK1.8 , 谢谢评论区指正~),然后new String 会把这个字符串对象拷贝一份到堆中,返回这个对象的引用。

除此之外,我知道String是不可变的,但是那是创建了之后不可变,也就是线程安全,那么我的疑问是在创建的时候是线程安全的么?以下是关于这个方面的个人理解:
之所以说线程不安全,这里引入两个概念:原子操作指令重排

1.原子操作

  • 原子操作,可以理解为不可分割的操作,就是它已经小到不可以再切分为多个操作进行,那么在计算机中要么它完全执行了,要么它完全没有执行,它不会存在执行到中间状态,可以理解为没有中间状态。比如:赋值语句就是一个原子操作:
 n = 1; //这是一个原子操作 

假设n的值以前是0,那么这个操作的背后就是要么执行成功n等于1,要么没有执行成功n等于0,不会存在中间状态,就算是并发的过程中也是一样的。
下面看一句不是原子操作的代码:

int n =1;//不是原子操作

**原因:**这个语句中可以拆分为两个操作,1.声明变量n,2.给变量赋值为1,从中我们可以看出有一种状态是n被声明后但是没有来得及赋值的状态,这样的情况,在并发中,如果多个线程同时使用n,那么就会可能导致不稳定的结果。

2.指令重排

所谓指令重排,就是计算机会对我们代码进行优化,优化的过程中会在不影响最后结果的前提下,调整原子操作的顺序。比如下面的代码:

int a ;   // 语句1 
a = 1 ;   // 语句2
int b = 2 ;     // 语句3
int c = a + b ; // 语句4

正常的情况,执行顺序应该是1234,但是实际有可能是3124,或者1324,这是因为语句3和4都没有原子性问题,那么就有可能被拆分成原子操作,然后重排.

那么回到我们上面那个代码

    String value = new String("常量");
    //这不是原子操作,就是可以拆分,事实上先定义了一个String变量,然后创建了对象"常量",然后拷贝对象到堆中,将对象引用指向value。

上面代码如果在多线程中,有可能触发指令重排,如果有线程创建了对象,还没有将引用指过去,其他线程也就有可能创建多个这样的常量,有可能会导致其他问题出现。【如有错误,还请指教】

正确的改动方法:

1.使用常量,将项目的常量都抽取到一个class文件中:
2.使用format方法:

public class ConstantFile{
    public static final String name = "常量";//方法1
    public void myMethod(){
        String.format("常量,%s,%s",args1,args2);//方法2
    }
}

3.使用枚举类型:

public enum  ConstantFile {
  USA("美国",1),CHINA("中国",2);
  private String name;
  private int index;
  private ConstantFile(String name,int index){
    this.name=name;
    this.index=index;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getIndex() {
    return index;
  }

  public void setIndex(int index) {
    this.index = index;
  }
}

如有错误,还请指教,感激!!!
此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

技术之路不在一时,山高水长,纵使缓慢,驰而不息。

公众号:秦怀杂货店

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值