Java基礎語法


筆記源於 視頻教程Bilibili:狂神說Java 關注公眾號:狂神說

Java基礎語法1

image-20200505152941991

注釋、標識符、關鍵字

注釋Comments

注釋並不會被執行,是給我們寫代碼的人看的。

書寫注釋是個非常好的習慣,平時就要注意規范

  1. 單行注釋 //

  2. 多行注釋 /* */

  3. 文檔注釋 /** */

單行注釋

只能注釋一行文字

多行注釋

可以注釋一段文字 /* */

文檔注釋

使用文檔注釋時,需要在開始的 /** 之后,第一行或幾行是關於類、變量和方法的主要描述。

之后,可以包含一個或多個何種各樣的@ 標簽。每一個@標簽必須在一個新行的開始或者在一行的開始緊跟星號(*)。

多個相同類型的標簽應該放成一組。

代碼

public class HelloJava {
    /**
     * @param args 
     * @author Ljh
     * 文檔注釋給某個類或方法解釋說明
     */
    public static void main(String[] args) {
        //這是一個單行注釋
        System.out.println("Hello Java!");
        /* 多行注釋
                                   _(\_/)
                                 ,((((^`\
                                ((((  (6 \
                              ,((((( ,    \
          ,,,_              ,(((((  /"._  ,`,
         ((((\\ ,...       ,((((   /    `-.-'
         )))  ;'    `"'"'""((((   (
        (((  /            (((      \
         )) |                      |
        ((  |        .       '     |
        ))  \     _ '      `t   ,.')
        (   |   y;- -,-""'"-.\   \/
        )   / ./  ) /         `\  \
           |./   ( (           / /'
           ||     \\          //'|
           ||      \\       _//'||
           ||       ))     |_/  ||
           \_\     |_/          ||
           `'"                  \_\
         */
    }
}

可以搜索有趣的代碼注釋

標識符

Java 所有的組成部分都需要名字。類名、變量名以及方法名都被稱為標識符。

關於 Java 標識符,有以下幾點需要注意:

  • 所有的標識符都應該以字母(A-Z 或者 a-z),美元符($)、或者下划線(_)開始
  • 首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划線(_)或數字的任何字符組合
  • 關鍵字不能用作標識符
  • 標識符是大小寫敏感的
  • 合法標識符舉例:age、$salary、_value、__1_value
  • 非法標識符舉例:123abc、-salary 、#abc
  • 可以使用中文命名,但不建議用,也不要用拼音,Low
public class TAG {
    public static void main(String[] args) {
        String A_ = "首大寫字母開頭";
        String a_ = "首小寫字母開頭";
        String _A= "下划線開頭";
        String $_ = "美元符號開頭";
        // 不允許數字或非法符號開頭
        // 非法符號:除了 _ $ 以外的任何符號
        // String 1_ = "數字開頭"; X
        // String #_ = "非法符號開頭"; X

        String _1Aa$ = "首字母之后可任意組合";
        // 不允許出現非法符號
        // String _# = "出現非法符號"; X
    }
}

關鍵字

下面列出了 Java 關鍵字。這些保留字不能用於常量、變量、和任何標識符的名稱。

image-20200505160147264

類別 關鍵字 說明
訪問控制 private 私有的
訪問控制 protected 受保護的
訪問控制 public 公共的
訪問控制 default 默認
類、方法和變量修飾符 abstract 聲明抽象
類、方法和變量修飾符 class
類、方法和變量修飾符 extends 擴充,繼承
類、方法和變量修飾符 final 最終值,不可改變的
類、方法和變量修飾符 implements 實現(接口)
類、方法和變量修飾符 interface 接口
類、方法和變量修飾符 native 本地,原生方法(非 Java 實現)
類、方法和變量修飾符 new 新,創建
類、方法和變量修飾符 static 靜態
類、方法和變量修飾符 strictfp 嚴格,精准
類、方法和變量修飾符 synchronized 線程,同步
類、方法和變量修飾符 transient 短暫
類、方法和變量修飾符 volatile 易失
程序控制語句 break 跳出循環
程序控制語句 case 定義一個值以供 switch 選擇
程序控制語句 continue 繼續
程序控制語句 default 默認
程序控制語句 do 運行
程序控制語句 else 否則
程序控制語句 for 循環
程序控制語句 if 如果
程序控制語句 instanceof 實例
程序控制語句 return 返回
程序控制語句 switch 根據值選擇執行
程序控制語句 while 循環
錯誤處理 assert 斷言表達式是否為真
錯誤處理 catch 捕捉異常
錯誤處理 finally 有沒有異常都執行
錯誤處理 throw 拋出一個異常對象
錯誤處理 throws 聲明一個異常可能被拋出
錯誤處理 try 捕獲異常
包相關 import 引入
包相關 package
基本類型 boolean 布爾型
基本類型 byte 字節型
基本類型 char 字符型
基本類型 double 雙精度浮點
基本類型 float 單精度浮點
基本類型 int 整型
基本類型 long 長整型
基本類型 short 短整型
變量引用 super 父類,超類
變量引用 this 本類
變量引用 void 無返回值
保留關鍵字 goto 是關鍵字,但不能使用
保留關鍵字 const 是關鍵字,但不能使用
保留關鍵字 null

數據類型

強類型語言

要求變量的使用要嚴格符合規定,所有變量都必須先定義后才能使用。

一旦一個變量被指定了某個數據類型,如果不經過強制轉換,那么它就永遠是這個數據類型了。

舉個例子:如果你定義了一個整型變量 a,那么程序根本不可能將 a 當作字符串類型處理。強類型定義語言是類型安全的語言。

弱類型語言

它與強類型定義語言相反, 一個變量可以賦不同數據類型的值。

類型分類

所以Java是強類型語言,所有變量都必須先定義后才能使用。

Java的數據類型分為兩大類

基本類型(primitive type)

Java語言提供了八種基本類型。六種數字類型(四個整數型,兩個浮點型),一種字符類型,還有一種布爾型。

byte:

  • byte 數據類型是8位、有符號的,以二進制補碼表示的整數;
  • 最小值是 -128(-2^7);
  • 最大值是 127(2^7-1);
  • 默認值是 0;
  • byte 類型用在大型數組中節約空間,主要代替整數,因為 byte 變量占用的空間只有 int 類型的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short 數據類型是 16 位、有符號的以二進制補碼表示的整數
  • 最小值是 -32768(-2^15);
  • 最大值是 32767(2^15 - 1);
  • Short 數據類型也可以像 byte 那樣節省空間。一個short變量是int型變量所占空間的二分之一;
  • 默認值是 0;
  • 例子:short s = 1000,short r = -20000。

int:

  • int 數據類型是32位、有符號的以二進制補碼表示的整數;
  • 最小值是 -2,147,483,648(-2^31);
  • 最大值是 2,147,483,647(2^31 - 1);
  • 一般地整型變量默認為 int 類型;
  • 默認值是 0 ;
  • 例子:int a = 100000, int b = -200000。

long:

  • long 數據類型是 64 位、有符號的以二進制補碼表示的整數;
  • 最小值是 -9,223,372,036,854,775,808(-2^63);
  • 最大值是 9,223,372,036,854,775,807(2^63 -1);
  • 這種類型主要使用在需要比較大整數的系統上;
  • 默認值是 0L
  • 例子: long a = 100000L,Long b = -200000L。
    "L"理論上不分大小寫,但是若寫成"l"容易與數字"1"混淆,不容易分辯。所以最好大寫。

float:

  • float 數據類型是單精度、32位、符合IEEE 754標准的浮點數
  • float 在儲存大型浮點數組的時候可節省內存空間;
  • 默認值是 0.0f
  • 浮點數不能用來表示精確的值,如貨幣
  • 例子:float f1 = 234.5f。

double:

  • double 數據類型是雙精度、64 位、符合IEEE 754標准的浮點數
  • 浮點數的默認類型為double類型;
  • double類型同樣不能表示精確的值,如貨幣;
  • 默認值是 0.0d;可省略
  • 例子:double d1 = 123.4。

boolean:

  • boolean數據類型表示一位的信息;
  • 只有兩個取值:true 和 false;
  • 這種類型只作為一種標志來記錄 true/false 情況;
  • 默認值是 false;
  • 例子:boolean one = true。

char:

  • char類型是一個單一的 16 位 Unicode 字符;
  • 最小值是 \u0000(即為0);
  • 最大值是 \uffff(即為65,535);
  • char 數據類型可以儲存任何字符;
  • 例子:char letter = 'A';
/**
 * 介紹8大基本數據類型
 */
public class PrimaryType {
    public static void main(String[] args) {
        // 八大基本數據類型

        // 整數
        byte byte_num = 127; // 8位1字節 2^8=256 范圍:-2^7 ~ 2^7 -1 (-128 ~ 127)
        short short_num = 32767; // 2字節 范圍:+-三萬多
        int int_num = 123456; // 最常用。 4字節,范圍:正負21億多
        long long_num = 99999999999999L; //8字節! 當超過int范圍時需要在數字后面加L

        // 浮點數
        float float_num = 0.1F; // 4字節,后面必須加F
        double double_num = 0.1; // 8字節,結尾的d 可加可不加

        //字符
        char ch = '1'; // 單一的 16 位 Unicode 字符
        String str = "123456"; // 字符串不是基本數據類型,而是一個類

        //布爾類型
        boolean flag = true;
        boolean flag2 = false;
    }
}

基本數據類型擴展
/**
 * 數據類型面試題
 */
public class PrimaryTypeExt {
    public static void main(String[] args) {
        /*  二進制是Binary,簡寫為B
            八進制是Octal,簡寫為O
            十進制為Decimal,簡寫為D
            十六進制為Hexadecimal,簡寫為H
         */

        //整數擴展 進制:  2   8   10  16
        int bin_num = 0b10; // 二進制 0b 開頭
        int oct_num = 010; // 八進制0開頭
        int dec_num = 10; // 十進制正常寫
        int hex_num = 0x10; // 十六進制 0x 開頭

        System.out.println(bin_num);//默認打印10進制
        System.out.println(oct_num);
        System.out.println(dec_num);
        System.out.println(hex_num);

        System.out.println("----------------");
        //浮點數 精度有丟失
        // 所以銀行業務不用float,用BigDecimal
        // 最好完全避免使用浮點數進行比較!!!

        float num1 = 4.0f;
        float num2 = 3.6f;
        System.out.println(num1 - num2); //0.4000001
        //如何解釋出現4.0-3.6 =0.40000001
        // 答:二進制的小數無法精確的表示10進制小數,
        // 計算機在計算4.0 -3.6 時,先將兩數轉成2進制形式
        // 用二進制計算后再將結果轉成十進制,這期間出現了誤差。

        System.out.println("--------字符串擴展--------");
        //字符串擴展
        char ch = 'A'; // 底層原理 是 '\u0041'  十進制的65 -> 十六進制41
        char ch2 = '國';

        System.out.println((int) ch);
        System.out.println((int) ch2);
        System.out.println('\u0041');//Unicode編碼
        // 所有的字符本質還是數字

        System.out.println("--------轉義字符\\--------");
        // 轉義字符
        System.out.println("換行\ntab\t鍵");


        System.out.println("--------布爾擴展--------");
        // 布爾使用
        boolean flag = true;
        if (flag == true)
            System.out.println("新手用法");
        if (flag)
            System.out.println("老手用法");
        // 代碼要精簡易讀

    }
}

image-20200505165734525

引用類型(reference type)

除了八大基本數據類型之外其他都是引用類型

如 類,接口,數組等

  • 在Java中,引用類型的變量非常類似於C/C++的指針。引用類型指向一個對象,指向對象的變量是引用變量。

    ​ 這些變量在聲明時被指定為一個特定的類型,比如 Employee、Puppy 等。變量一旦聲明后,類型就不能被改變了。

  • 對象、數組都是引用數據類型。

  • 所有引用類型的默認值都是null。

  • 一個引用變量可以用來引用任何與之兼容的類型。

浮點儲存模型

二進制的科學計數法來保存浮點數,

例如:5.5,其二進制數為101.1,則用二進制的科學計數法可以表示為 1.011 * 2^2,這樣小數點的位置就是固定的。

任何一個浮點數可以表示為下面的形式(國際標准IEEE 754):

(-1)^S * M * 2^E
(-1)^S表示符號位,當S=0時,為正;當S=1時,為負
M表示有效數字,M>=1且M<2
2^E表示指數位

上面的例子中,S=0,M=1.011,E=2。
所以當存儲浮點數時,只需要將上述三個數字保存起來,就可以了。
對於但精度浮點數,其存儲模型為:

image-20200505173223176

類型轉換

整型、實型(常量)、字符型數據可以混合運算。運算中,不同類型的數據先轉化為同一類型,然后進行運算。

轉換從低級到高級。

低 --------------------------------------> 高

byte,short,char—> int —> long—> float —> double

數據類型轉換必須滿足如下規則:

  • 不能對boolean類型進行類型轉換。

  • 不能把對象類型轉換成不相關類的對象。

  • 在把容量大的類型轉換為容量小的類型時必須使用強制類型轉換。

  • 轉換過程中可能導致溢出或損失精度,例如:

    int i =128;   
    byte b = (byte)i;
    

    因為 byte 類型是 8 位,最大值為127,所以當 int 強制轉換為 byte 類型時,值 128 時候就會導致溢出。

  • 浮點數到整數的轉換是通過舍棄小數得到,而不是四舍五入,例如:

    (int)23.7 == 23;        
    (int)-45.89f == -45
    

自動類型轉換(低到高)

必須滿足轉換前的數據類型的位數要低於轉換后的數據類型,

例如: short數據類型的位數為16位,就可以自動轉換位數為32的int類型,

同樣float數據類型的位數為32,可以自動轉換為64位的double類型。

強制類型轉換(高到底)

  • 條件是轉換的數據類型必須是兼容的。
  • 格式:(type)value type是要強制類型轉換后的數據類型

隱含強制類型轉換

  • 整數的默認類型是 int。
  • 浮點型不存在這種情況,因為在定義 float 類型時必須在數字后面跟上 F 或者 f。
public class TypeConversion {
    public static void main(String[] args) {
        int i = 128;
        byte b = (byte)i;
        System.out.println(b);//byte類型的范圍是-128 ~ 127 ,強轉128溢出。
        // 強制轉換(類型)變量名

        double d = i;
        System.out.println(d);
        // 由低 -> 高 自動轉換

        System.out.println((int)23.7);//23 去掉小數,不是四舍五入哦
        System.out.println((int)-45.89f);// -45

        System.out.println('a'+1); //a -> 97

        System.out.println("----------");
        // jdk7 特性 _
        int num =  10_0000_0000;
        System.out.println(num);
        System.out.println(num*20);// int 的范圍21億多,現在結果200億溢出
        System.out.println((long)num*20);//先轉換再計算
        System.out.println((long)(num*20));//先計算再轉換
        
        long l = 1l; //小寫l 與數字1太像了,建議都用大寫L

    }
}

變量、常量

變量

在Java語言中,所有的變量在使用前必須聲明。聲明變量的基本格式如下:

type varName[ = value][, varName[= value] ...] ;

格式說明:type為Java數據類型。varName是變量名。可以使用逗號隔開來聲明多個同類型變量(不建議)。

作用域:

  • 類變量:獨立於方法之外的變量,用 static 修飾。
  • 實例變量:獨立於方法之外的變量,不過沒有 static 修飾。
  • 局部變量:類的方法中的變量。

image-20200505184150847

類變量(靜態變量)

  • 類變量也稱為靜態變量,在類中以 static 關鍵字聲明,但必須在方法之外。
  • 無論一個類創建了多少個對象,類只擁有類變量的一份拷貝。
  • 靜態變量除了被聲明為常量外很少使用。常量是指聲明為public/private,final和static類型的變量。常量初始化后不可改變。
  • 靜態變量儲存在靜態存儲區。經常被聲明為常量,很少單獨使用static聲明變量。
  • 靜態變量在第一次被訪問時創建,在程序結束時銷毀。
  • 與實例變量具有相似的可見性。但為了對類的使用者可見,大多數靜態變量聲明為public類型。
  • 默認值和實例變量相似。數值型變量默認值是0,布爾型默認值是false,引用類型默認值是null。變量的值可以在聲明的時候指定,也可以在構造方法中指定。此外,靜態變量還可以在靜態語句塊中初始化。
  • 靜態變量可以通過:ClassName.VariableName的方式訪問。
  • 類變量被聲明為public static final類型時,類變量名稱一般建議使用大寫字母。如果靜態變量不是public和final類型,其命名方式與實例變量以及局部變量的命名方式一致。

實例變量

  • 實例變量聲明在一個類中,但在方法、構造方法和語句塊之外;
  • 當一個對象被實例化之后,每個實例變量的值就跟着確定;
  • 實例變量在對象創建的時候創建,在對象被銷毀的時候銷毀;
  • 實例變量的值應該至少被一個方法、構造方法或者語句塊引用,使得外部能夠通過這些方式獲取實例變量信息;
  • 實例變量可以聲明在使用前或者使用后;
  • 訪問修飾符可以修飾實例變量;
  • 實例變量對於類中的方法、構造方法或者語句塊是可見的。一般情況下應該把實例變量設為私有。通過使用訪問修飾符可以使實例變量對子類可見;
  • 實例變量具有默認值。數值型變量的默認值是0,布爾型變量的默認值是false,引用類型變量的默認值是null。變量的值可以在聲明時指定,也可以在構造方法中指定;
  • 實例變量可以直接通過變量名訪問。但在靜態方法以及其他類中,就應該使用完全限定名:ObejectReference.VariableName。

局部變量

  • 局部變量聲明在方法、構造方法或者語句塊中;
  • 局部變量在方法、構造方法、或者語句塊被執行的時候創建,當它們執行完成后,變量將會被銷毀;
  • 訪問修飾符不能用於局部變量
  • 局部變量只在聲明它的方法、構造方法或者語句塊中可見;
  • 局部變量是在棧上分配的
  • 局部變量沒有默認值,所以局部變量被聲明后,必須經過初始化,才可以使用。

image-20200505183433544

常量

常量在程序運行時是不能被修改的。

在 Java 中使用 final 關鍵字來修飾常量,聲明方式和變量類似:

final double PI = 3.1415927;

雖然常量名也可以用小寫,但為了便於識別,通常使用大寫字母表示常量

字面量可以賦給任何內置類型的變量。例如:

byte a = 68;
char a = 'A'

byte、int、long、和short都可以用十進制、16進制以及8進制的方式來表示。

當使用常量的時候,前綴 0 表示 8 進制,而前綴 0x 代表 16 進制, 例如:

int decimal = 100;
int octal = 0144;
int hexa =  0x64;

和其他語言一樣,Java的字符串常量也是包含在兩個引號之間的字符序列。下面是字符串型字面量的例子:

"Hello World"
"two\nlines"
"\"This is in quotes\""

字符串常量和字符常量都可以包含任何Unicode字符。例如:

char a = '\u0001';
String a = "\u0001";

轉義符

Java語言支持一些特殊的轉義字符序列。

符號 字符含義
\n 換行 (0x0a)
\r 回車 (0x0d)
\f 換頁符(0x0c)
\b 退格 (0x08)
\0 空字符 (0x20)
\s 字符串
\t 制表符
" 雙引號
' 單引號
\ 反斜杠
\ddd 八進制字符 (ddd)
\uxxxx 16進制Unicode字符 (xxxx)
  • 修飾符不區分先后順序
static final double PI = 3.1415927;
final static double PI = 3.1415927;

兩個結果都可以

運算符

image-20200506005504369

優先級

優先級 運算符 結合性
1 ()、[]、{} 從左向右
2 !、+正、-負、~、++、-- 從右向左
3 *、/、% 從左向右
4 +加、-減 從左向右
5 «、»、>>> 從左向右
6 <、<=、>、>=、instanceof 從左向右
7 ==、!= 從左向右
8 & 從左向右
9 ^ 從左向右
10 | 從左向右
11 && 從左向右
12 || 從左向右
13 ?: 從右向左
14 =、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>= 從右向左

Java語言分隔符

分號(;):語句的分割,表示一個代碼語句結束;

花括號({}):表示一個代碼塊,是一個整體,花括號要成對使用;在面向對象的理念中,代碼塊通常表示一個或者多個業務邏輯;

方括號([]):通常是定義數組和訪問數組元素時使用;

圓括號(()):使用很廣泛,如數據類型轉換、數據運算、方法的定義和使用等;

圓點(.):類和對象訪問它的成員時使用,如:Arrays.sort();

空格( ):把一整個代碼語句語句分割成幾段,空格的使用次數不限,和英語中單詞之間要使用空格是一樣的。

注意:以上分隔符都必須都是半角下的英文符號;.要注意區分空格和空白,空格對應的是鍵盤上的空格鍵的輸入,在Java中,空格是可以作為一個有效字符使用的,而空白相對於空格來說要寬泛得多,也可以說空白是由大量的空字符組成的;

包機制

包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。

包名統一使用單數形式,但是類名如果有復數含義,類名可以使用復數形式。

正例:應用工具類包名為 com.alibaba.ei.kunlun.aap.util、類名為 MessageUtils(此規則參考 spring 的
框架結構)

image-20200506020656818

JavaDoc

image-20200506021302241

命令行模式:

image-20200506022605082

通過IDEA生成JavaDoc

image-20200506022726574

image-20200506023205265

  1. 注意生成 JavaDoc 的源代碼對象的選擇,一般以模塊(Module)為主,必要時可以單獨選擇必要的 Java 源代碼文件,

    不推薦以 PRoject 為 JavaDoc 生成的源范圍。

  2. Locale 可選填項,表示的是需要生成的 JavaDoc 以何種語言版本展示,根據 javadoc.exe 的幫助說明,這其實對應的就是 javadoc.exe 的 -locale 參數,如果不填,默認可能是英文或者是當前操作系統的語言,既然是國人,建議在此填寫 zh_CN,這樣生成的 JavaDoc 就是中文版本的,當然指的是 JavaDoc 的框架中各種通用的固定顯示區域都是中文的。你自己編寫的注釋轉換的內容還是根據你注釋的內容來。

  3. Other command line arguments:”可選填項,非常重要,是填寫直接向 javadoc.exe 傳遞的參數內容。因為有一些重要的設置,只能通過直接參數形式向 javadoc.exe 傳遞。這里必須要填寫如下參數:

    -encoding UTF-8 -charset UTF-8 -windowtitle "窗口名稱" -link http://docs.Oracle.com/javase/8/docs/api

    參數說明:

    • -encoding UTF-8 表示你的源代碼(含有符合 JavaDoc 標准的注釋)是基於 UTF-8 編碼的,以免處理過程中出現中文等非英語字符亂碼;
    • -charset UTF-8 表示在處理並生成 JavaDoc 超文本時使用的字符集也是以 UTF-8 為編碼,目前所有瀏覽器都支持 UTF-8,這樣最具有通用性,支持中文非常好;
    • -windowtitle 表示生成的 JavaDoc 超文本在瀏覽器中打開時,瀏覽器窗口標題欄顯示的文字內容;
    • -link 很重要,它表示你生成的 JavaDoc 中涉及到很多對其他外部 Java 類的引用,是使用全限定名稱還是帶有超鏈接的短名稱,舉個例子,我創建了一個方法 public void func(String arg),這個方法在生成 JavaDoc 時如果不指定 -link 參數,則 JavaDoc 中對該方法的表述就會自動變為 public void func(java.lang.String arg),因為 String 這個類對我自己實現的類來講就是外部引用的類,雖然它是 Java 標准庫的類。如果指定了 -link http://docs.oracle.com/javase/8/docs/api 參數,則 javadoc.exe 在生成 JavaDoc 時,會使用 String 這樣的短名稱而非全限定名稱 java.lang.String,同時自動為 String 短名稱生成一個超鏈接,指向官方 JavaSE 標准文檔 http://docs.oracle.com/javase/8/docs/api 中對 String 類的詳細文檔地址。
    • -link 實質上是告訴 javadoc.exe 根據提供的外部引用類的 JavaDoc 地址去找一個叫 package-list 的文本文件,在這個文本文件中包含了所有外部引用類的全限定名稱,因此生成的新 JavaDoc 不必使用外部引用類的全限定名,只需要使用短名稱,同時可以自動創建指向其外部引用 JavaDoc 中的詳細文檔超鏈接。每個 JavaDoc 都會在根目錄下有一個 package-list 文件,包括我們自己生成的 JavaDoc。
  4. JavaDoc 生成完畢,即可在其根目錄下找到 index.html 文件,打開它就可以看到我們自己的標准 JavaDoc API 文檔啦。

    image-20200506023750351

Java開發手冊(泰山版)

編程規約

(一) 命名風格

  1. 【強制】代碼中的命名均不能以下划線或美元符號開始,也不能以下划線或美元符號結束。
    反例:name / name / $name / name / name$ / name

  2. 【強制】所有編程相關的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式
    說明:正確的英文拼寫和語法可以讓閱讀者易於理解,避免歧義。注意,純拼音命名方式更要避免采用。
    正例:ali / alibaba / taobao / cainiao/ aliyun/ youku / hangzhou 等國際通用的名稱,可視同英文。
    反例:DaZhePromotion [打折] / getPingfenByName() [評分] / int 某變量 = 3

  3. 【強制】類名使用 UpperCamelCase 風格

但以下情形例外:DO / BO / DTO / VO / AO /PO / UID 等。
正例:ForceCode / UserDO / HtmlDTO / XmlService / TcpUdpDeal / TaPromotion
反例:forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion

  1. 【強制】方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格
    正例: localValue / getHttpMessage() / inputUserId

  2. 【強制】常量命名全部大寫,單詞間用下划線隔開,力求語義表達完整清楚,不要嫌名字長。
    正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME
    反例:MAX_COUNT / EXPIRED_TIME

  3. 【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;

    ​ 測試類命名以它要測試的類的名稱開始,以 Test 結尾。

  4. 【強制】類型與中括號緊挨相連來表示數組
    正例:定義整形數組 int[] arrayDemo;
    反例:在 main 參數中,使用 String args[]來定義。

  5. 【強制】POJO 類中的任何布爾類型的變量,都不要加 is 前綴,否則部分框架解析會引起序列
    化錯誤。
    說明:在本文 MySQL 規約中的建表約定第一條,表達是與否的值采用 is_xxx 的命名方式,所以,需要在
    設置從 is_xxx 到 xxx 的映射關系。

反例:定義為基本數據類型 Boolean isDeleted 的屬性,它的方法也是 isDeleted(),框架在反向解析的時
候,“誤以為”對應的屬性名稱是 deleted,導致屬性獲取不到,進而拋出異常。

  1. 【強制】包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用
    單數形式,但是類名如果有復數含義,類名可以使用復數形式。
    正例:應用工具類包名為 com.alibaba.ei.kunlun.aap.util、類名為 MessageUtils(此規則參考 spring 的
    框架結構)

  2. 【強制】避免在子父類的成員變量之間、或者不同代碼塊的局部變量之間采用完全相同的命名,使可讀性降低。
    說明:子類、父類成員變量名相同,即使是 public 類型的變量也是能夠通過編譯,而局部變量在同一方法內的不同代碼塊中同名也是合法的,但是要避免使用。對於非 setter/getter 的參數名稱也要避免與成員變量名稱相同。
    反例:

public class ConfusingName {
    public int stock;
    // 非 setter/getter 的參數名稱,不允許與本類成員變量同名
    public void get(String alibaba) {
        if (condition) {
            final int money = 666;
            // ...
        }
        for (int i = 0; i < 10; i++) {
            // 在同一方法體中,不允許與其它代碼塊中的 money 命名相同
            final int money = 15978;
            // ...
        }
    }
}
class Son extends ConfusingName {
    // 不允許與父類的成員變量名稱相同
    public int stock;
}

  1. 【強制】杜絕完全不規范的縮寫,避免望文不知義。
    反例:AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類隨意縮寫嚴重降低了代碼的可閱讀性。

  2. 【推薦】為了達到代碼自解釋的目標,任何自定義編程元素在命名時,使用盡量完整的單詞組
    合來表達。
    正例:在 JDK 中,對某個對象引用的 volatile 字段進行原子更新的類名為:AtomicReferenceFieldUpdater。
    反例:常見的方法內變量為 int a;的定義方式

  3. 【推薦】在常量與變量的命名時,表示類型的名詞放在詞尾,以提升辨識度。
    正例:startTime / workQueue / nameList / TERMINATED_THREAD_COUNT
    反例:startedAt / QueueOfWork / listName / COUNT_TERMINATED_THREAD

  4. 【推薦】如果模塊、接口、類、方法使用了設計模式,在命名時需體現出具體模式。
    說明:將設計模式體現在名字中,有利於閱讀者快速理解架構設計理念。
    正例: public class OrderFactory;
    public class LoginProxy;
    public class ResourceObserver;

  5. 【推薦】接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔
    性,並加上有效的 Javadoc 注釋。盡量不要在接口里定義變量,如果一定要定義變量,確定
    與接口方法相關,並且是整個應用的基礎常量。
    正例:接口方法簽名 void commit();
    接口基礎常量 String COMPANY = "alibaba";
    反例:接口方法定義 public abstract void f();
    說明:JDK8 中接口允許有默認實現,那么這個 default 方法,是對所有實現類都有價值的默認實現。

  6. 接口和實現類的命名有兩套規則:
    1)【強制】對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務一定是接口,內部的實現類用
    Impl 的后綴與接口區別。
    正例:CacheServiceImpl 實現 CacheService 接口。
    2)【推薦】如果是形容能力的接口名稱,取對應的形容詞為接口名(通常是–able 的形容詞)。
    正例:AbstractTranslator 實現 Translatable 接口。

  7. 【參考】枚舉類名帶上 Enum 后綴,枚舉成員名稱需要全大寫,單詞間用下划線隔開。
    說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。
    正例:枚舉名字為 ProcessStatusEnum 的成員名稱:SUCCESS / UNKNOWN_REASON。

  8. 【參考】各層命名規約:
    A) Service/DAO 層方法命名規約
    1) 獲取單個對象的方法用 get 做前綴。
    2) 獲取多個對象的方法用 list 做前綴,復數結尾,如:listObjects。
    3) 獲取統計值的方法用 count 做前綴。
    4) 插入的方法用 save/insert 做前綴。
    5) 刪除的方法用 remove/delete 做前綴。
    6) 修改的方法用 update 做前綴。
    B) 領域模型命名規約
    1) 數據對象:xxxDO,xxx 即為數據表名。
    2) 數據傳輸對象:xxxDTO,xxx 為業務領域相關的名稱。

    3) 展示對象:xxxVO,xxx 一般為網頁名稱。
    4) POJO 是 DO/DTO/BO/VO 的統稱,禁止命名成 xxxPOJO。

(二) 常量定義

  1. 【強制】不允許任何魔法值 ( 即未經預先定義的常量 ) 直接出現在代碼中。
    反例:
    //本例中同學 A 定義了緩存的 key,然后緩存提取的同學 B 使用了 Id#taobao 來提取,少了下划線,導致故障。
    String key = "Id#taobao_" + tradeId;
    cache.put(key, value);

  2. 【強制】在 long 或者 Long 賦值時,數值后使用大寫的 L,不能是小寫的 l,小寫容易跟數字
    混淆,造成誤解。
    說明:Long a = 2l; 寫的是數字的 21,還是 Long 型的 2。

  3. 【推薦】不要使用一個常量類維護所有常量,要按常量功能進行歸類,分開維護。
    說明:大而全的常量類,雜亂無章,使用查找功能才能定位到修改的常量,不利於理解,也不利於維護。
    正例:緩存相關常量放在類 CacheConsts 下;系統配置相關常量放在類 ConfigConsts 下。

  4. 【推薦】常量的復用層次有五層:跨應用共享常量、應用內共享常量、子工程內共享常量、包
    內共享常量、類內共享常量。
    1) 跨應用共享常量:放置在二方庫中,通常是 client.jar 中的 constant 目錄下。
    2) 應用內共享常量:放置在一方庫中,通常是子模塊中的 constant 目錄下。
    反例:易懂變量也要統一定義成應用內共享常量,兩位工程師在兩個類中分別定義了“YES”的變量:
    類 A 中:public static final String YES = "yes";
    類 B 中:public static final String YES = "y";
    A.YES.equals(B.YES),預期是 true,但實際返回為 false,導致線上問題。
    3) 子工程內部共享常量:即在當前子工程的 constant 目錄下。
    4) 包內共享常量:即在當前包下單獨的 constant 目錄下。
    5) 類內共享常量:直接在類內部 private static final 定義。

  5. 【推薦】如果變量值僅在一個固定范圍內變化用 enum 類型來定義。
    說明:如果存在名稱之外的延伸屬性應使用 enum 類型,下面正例中的數字就是延伸信息,表示一年中的
    第幾個季節。
    正例:

public enum SeasonEnum {
    SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
    private int seq;
    SeasonEnum(int seq) {
        this.seq = seq;
    }
    public int getSeq() {

        return seq;
    }
}

(三) 代碼格式

  1. 【強制】如果是大括號內為空,則簡潔地寫成{}即可,大括號中間無需換行和空格;如果是非
    空代碼塊則:
    1) 左大括號前不換行。
    2) 左大括號后換行。
    3) 右大括號前換行。
    4) 右大括號后還有 else 等代碼則不換行;表示終止的右大括號后必須換行。

  2. 【強制】左小括號和右邊相鄰字符之間不出現空格 ; 右小括號和左邊相鄰字符之間也不出現空
    格;而左大括號前需要加空格。詳見第 5 條下方正例提示。
    反例:if (空格 a == b 空格)

  3. 【強制】if/for/while/switch/do 等保留字與括號之間都必須加空格。

  4. 【強制】任何二目、三目運算符的左右兩邊都需要加一個空格。
    說明:包括賦值運算符=、邏輯運算符&&、加減乘除符號等。

  5. 【強制】采用 4 個空格縮進,禁止使用 tab 字符。
    說明:如果使用 tab 縮進,必須設置 1 個 tab 為 4 個空格。IDEA 設置 tab 為 4 個空格時,請勿勾選 Use tab
    character;而在 eclipse 中,必須勾選 insert spaces for tabs。
    正例: (涉及 1-5 點)

public static void main(String[] args) {
    // 縮進 4 個空格
    String say = "hello";
    // 運算符的左右必須有一個空格
    int flag = 0;
    // 關鍵詞 if 與括號之間必須有一個空格,括號內的 f 與左括號,0 與右括號不需要空格
    if (flag == 0) {
        System.out.println(say);
    }
    // 左大括號前加空格且不換行;左大括號后換行
    if (flag == 1) {
        System.out.println("world");
        // 右大括號前換行,右大括號后有 else,不用換行
    } else {
        System.out.println("ok");
        // 在右大括號后直接結束,則必須換行
    }
}

  1. 【強制】注釋的雙斜線與注釋內容之間有且僅有一個空格。
    正例:
    // 這是示例注釋,請注意在雙斜線之后有一個空格
    String commentString = new String();

  2. 【強制】在進行類型強制轉換時,右括號與強制轉換值之間不需要任何空格隔開。
    正例:
    long first = 1000000000000L;
    int second = (int)first + 2;

  3. 【強制】單行字符數限制不超過 120 個,超出需要換行,換行時遵循如下原則:
    1)第二行相對第一行縮進 4 個空格,從第三行開始,不再繼續縮進,參考示例。
    2)運算符與下文一起換行。
    3)方法調用的點符號與下文一起換行。
    4)方法調用中的多個參數需要換行時,在逗號后進行。
    5)在括號前不要換行,見反例。
    正例:

StringBuilder sb = new StringBuilder();
// 超過 120 個字符的情況下,換行縮進 4 個空格,並且方法前的點號一起換行
sb.append("zi").append("xin")...
    .append("huang")...
    .append("huang")...
    .append("huang");
反例:
    StringBuilder sb = new StringBuilder();
// 超過 120 個字符的情況下,不要在括號前換行
sb.append("you").append("are")...append
    ("lucky");
// 參數很多的方法調用可能超過 120 個字符,逗號后才是換行處
method(args1, args2, args3, ...
       , argsX);

  1. 【強制】方法參數在定義和傳入時,多個參數逗號后邊必須加空格。
    正例:下例中實參的 args1,后邊必須要有一個空格。
    method(args1, args2, args3);

  2. 【強制】IDE 的 text file encoding 設置為 UTF-8; IDE 中文件的換行符使用 Unix 格式,不要
    使用 Windows 格式。

  3. 【推薦】單個方法的總行數不超過 80 行。
    說明:除注釋之外的方法簽名、左右大括號、方法內代碼、空行、回車及任何不可見字符的總行數不超過
    80 行。
    正例:代碼邏輯分清紅花和綠葉,個性和共性,綠葉邏輯單獨出來成為額外方法,使主干代碼更加清晰;共
    性邏輯抽取成為共性方法,便於復用和維護。

  4. 【推薦】沒有必要增加若干空格來使變量的賦值等號與上一行對應位置的等號對齊。
    正例:
    int one = 1;
    long two = 2L;
    float three = 3F;
    StringBuilder sb = new StringBuilder();
    說明:增加 sb 這個變量,如果需要對齊,則給 one、two、three 都要增加幾個空格,在變量比較多的情
    況下,是非常累贅的事情。

  5. 【推薦】不同邏輯、不同語義、不同業務的代碼之間插入一個空行分隔開來以提升可讀性。
    說明:任何情形,沒有必要插入多個空行進行隔開。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM