1. 程式人生 > >java不允許未經定義的常量直接出現在程式碼中

java不允許未經定義的常量直接出現在程式碼中

不是報錯,只是soanrqube檢測覺得這樣子不規範,這個也是阿里巴巴java程式設計手冊中的一個規定,裡面說法是不允許使用魔法值
java中,在使用sonarqube的時候,string型別的程式碼不允許直接使用未經定義的常量,什麼是未經定義的產量呢?下面舉個例子:

    //這個會報未經定義的常量
    String value = "常量";

一開始想到的解決方案是改成下面這個:

    //這樣子就是定義了這個變量了,sonarqube也沒有報錯了
    String value = new String("常量");

但是裡面有一個問題,那就是浪費記憶體。
浪費記憶體是,裡面有兩個物件,String value只是一個字串變數,沒有產生物件,new String(“常量”)不是原子操作,把它拆分為”常量”和new String(),首先會在字串的常量池中查詢有沒有這個字串”常量”,沒有找到就會建立一個字串物件”常量”在棧中,然後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;
  }
}

如有錯誤,還請指教,感激!!!

相關推薦

java允許未經定義常量直接出現在程式碼

不是報錯,只是soanrqube檢測覺得這樣子不規範,這個也是阿里巴巴java程式設計手冊中的一個規定,裡面說法是不允許使用魔法值 java中,在使用sonarqube的時候,string型別的程式碼不允許直接使用未經定義的常量,什麼是未經定義的產量

圖片存放資料夾,直接存在資料庫

<?php session_start(); include("Conn/conn.php"); $tpmc = $_POST['tpmc']; $file = $_FILES['file'];//added $file = $file['tmp_name'];/

java類的構造方法可以直接呼叫該類已有的方法。

例項程式碼如下: 其中構造方法中的呼叫替換掉原註釋的部分。 package test; /**  * @author : suyuyuan * @date :2016年6月22日 下午2:46:43  * @version 1.0  */     class People{

JAVA】使用自定義註解簡易模擬Spring的自動裝配@Autowired

            使用自定義註解簡易模擬Spring中的自動裝配@Autowired 我們在學Spring的時候,常常需要配置大量的bean,由Spring進行管理,這就導致配置檔案的膨脹,後來使用到@Autowired註解,才發現到註解的強大,那麼底層是怎麼實現

Java-Annotation的一種用法(消除程式碼冗餘的if/else或switch語句)

# Java-Annotation的一種用法(消除程式碼中冗餘的if/else或switch語句) ### 1.冗餘的if/else或switch ​ 有沒有朋友寫過以下的程式碼結構,大量的if/esle判斷,來選擇不同的執行方式 ```java if(type==1001){ return dec

Java的static方法為什麼允許直接使用非static的變數

在學習java時我們都知道: 1. 非靜態方法可以訪問類中非static和static的變數         2.靜態方法只能直接訪問靜態變數 例如: <span style="font-family:Courier New;font-size:14px;">

cvc-complex-type.3.2.2: 元素 'constructor-arg' 允許出現屬性 'name'

image 版本號 gpo alt type body 版本 log 3.0 將版本號改成 3.0 以上的即可。 cvc-complex-type.3.2.2: 元素 'constructor-arg' 中不允許出現屬性 'name

Java基礎------生成一個六位數的驗證碼(包含大寫字母、小寫字母、數字,並且允許重復)?

參考 數組 rand 定義 ole ava length log post 問題描述:生成一個六位數的驗證碼(包含大寫字母、小寫字母、數字,並且不允許重復)? 參考代碼如下: import java.util.Arrays;import java.util.Random

ACTOR允許出現阻塞

actor scala 因為actor接收請求的速度很快,如果出現阻塞(如IO操作)會耗時,接收請求的速度超過程 序處理的速度就可能會導致內存溢出。如果中間需要連接數據庫 的話,數據庫操作需要在Future 中進行,然後為Future分配線程池, 來保證數據庫的操作無阻塞進行。

錯誤: 此上下文中允許函數定義

atl 利用 其他 沒有 了解 相同 除了 運行機制 參考 1 為了搞清這個問題,我們先來了解一下matlab編譯運行代碼的幾種方式。 在腳本編輯器中編寫,全選後右鍵執行所選內容。使用這種方式編譯運行,無非就是將選中的代碼一行一行放到命令行中運行,這種方式,便於程序的調試

Java Set( 允許重複的集合)

HashSet:  防止重複 使用HashSet的class必須implements Comparable(); ArrayList<class> classList=new ArrayList<class>

定義常量 java

首先看示例: /**   * Method One   */   interface ConstantInterface {       

錯誤頁面的制定,允許直接丟擲錯誤。

Web.xml配置: <error-page>     <error-code>403</error-code>     <location>/403.html</location>

java無法直接引用pom定義的變數

maven佔位符類似於EL表示式,通過${}來獲取pom中定義的變數,這樣可以根據不同的部署環境,將對應的xml檔案中的變數進行替換(一般情況下,測試和開發環境引用的變數都是不一樣的,如果手動替換,這樣工作量會很大)。根據pom.xml中不同部署環境配置的變數,可以動態的將xml檔案中引用變數替換,

Word VBA 把一個Word檔案的內容通過字串操作複製到另一個Word檔案內(要求允許出現空行)

Sub 巨集1() ' ' 巨集1 巨集 ' Documents.Open FileName:="D:\VBA\被插入文字的檔案.docx", ConfirmConversions:=False, ReadOnly _ :=False, AddToRe

Java定義常量(Constant) 的幾種方法

常量使用目的 為什麼要將常亮提取出來?         常亮提取出來有利於程式碼閱讀,而且下次再做這種判斷不用手寫或複製,直接通過常量類就能得到,能夠避免有的地方是username,有的地方是name來判斷同一個邏輯含義相同變數問題。不過我覺得提取出來並不會有

【修真院JAVA小課堂】什麼叫明文,什麼叫密文,為什麼允許在資料庫裡明文儲存密碼

大家好,我是IT修真院深圳分院第十二期學員,一枚正直純潔善良的JAVA程式設計師。 今天給大家分享一下,修真院官網JAVA任務五的一個知識點:什麼叫明文,什麼叫密文,為什麼不允許在資料庫裡明文儲存密碼? 1.背景介紹 2.知識剖析 3.常見問題 4.解決方案

ejs裡面如何判斷某個引數是是已經定義了?直接用會拋異常,直接判斷也會。

Express, EJS, challenge with testing for undefined up vote 1 down vote favorite 1 I’m creating a simple website with nodejs u

Java語法】java成員內部類內為什麼允許有任何靜態宣告搜尋

看下內部類Eclipse給的錯誤我們可以看出一部分,靜態的屬性或者方法不允許宣告在非靜態的物件中.   下面我們看下think in java 中談內部類   內部類自動獲得對其外圍類所有成員的訪問權,這是如何做到的? 當某個外圍類建立了一個內部類物件時,此內部

java 能引用另一方法定義的內部類中非終態變數

package com.study; public class Test { public void test01(){ String m = "外部定義的方法"; class Test02{ public Test02() {