「MoreThanJava」Day 2:變量、數據類型和運算符

  • 「MoreThanJava」 宣揚的是 「學習,不止 CODE」,本系列 Java 基礎教程是本身在結合各方面的知識以後,對 Java 基礎的一個總回顧,旨在 「幫助新朋友快速高質量的學習」
  • 固然 不論新老朋友 我相信您均可以 從中獲益。若是以爲 「不錯」 的朋友,歡迎 「關注 + 留言 + 分享」,文末有完整的獲取連接,您的支持是我前進的最大的動力!

Part 1. 數據類型

假設您遇到了如下撕碎的紙片,您以爲會是什麼意思?html

在不瞭解上下文的狀況下,很難說出 MIX 的含義,它多是羅馬數字 1009,也能夠是英語單詞 mix 或者別的什麼東西。java

在不知道上下文的狀況下,一串字母沒有任何意義。git

與一串字母同樣,一串 01 的含義取決於如何使用。而決定這一串數據如何使用的方案被稱爲其 數據類型 (跟文件類型有些相似)程序員

8 種基本數據類型

Java 是一種強類型語言。這意味着必須爲每一條數據聲明一種類型。在 Java 中共有 8 種基本類型 (primitive type),其中 4 種整型、2 種浮點類型、1 種字符類型、1 種表示真值的 boolean (布爾) 類型。github

整型

整型被用來表示沒有小數部分的數值,容許是負數。Java 提供了 4 種整型,具體內容以下:express

類型 存儲需求 取值範圍
int 4 字節 -2147483648 ~ 2147483647 (剛超過 20 億,這個數值也就是 232 對半分紅正負值,32=4字節*每一個字節8位)
short 2 字節 -32768 ~ 32767
long 8 字節 -9223372036854775808 ~ 9223372036854775807
byte 1 字節 -128 ~ 127

在一般狀況下,int 類型最經常使用。但若是想要表示整個地球的居住人口,那麼就須要使用 long 類型了。byteshort 類型主要用於特定的應用場合,例如,底層的文件處理或者存儲空間很寶貴時的大數組 (由於節約內存)編程

浮點類型

浮點類型用於表示有小數部分的數值。在 Java 中有兩種浮點類型,具體內容以下:數組

類型 存儲需求 取值範圍
float 4 字節 大約 ±3.40282347E + 38F (大約有效數爲 6 ~ 7)
double 8 字節 大約 ±1.7976931486231580E + 308 (大約有效數爲 15 位)

double 表示這種類型的數值精度是 float 類型的兩倍 (也有人稱 double 爲雙精度數值)less

浮點數精度問題

問一個問題:0.1 + 0.2 = ?編程語言

先別奇怪,在 IDEA 中嘗試着輸出一下這句話就知道了:

System.out.println(0.1 + 0.2);

// 輸出:0.30000000000000004

0.1 + 0.2 爲何會等於 0.30000000000000004?而不是咱們想象中的 0.3

這不是由於它們在計算時出現了錯誤,而是由於浮點數計算標準的要求。

首先咱們要明確一點:編程中的浮點數並不能和數學中的小數看作同一個東西

  • 編程中的浮點數的精度每每都是有限的,單精度的浮點數使用 32 位表示,而雙精度的浮點數使用 64 位表示;
  • 數學中的小數系統能夠經過引入無限序列....能夠表示任意的實數;

請考慮使用 十進制 表示 1/3

0.3333333333333333....

若是想要完整地表達 1/3 的精度,那麼小數點以後的 3 須要無限地寫下去。若是須要讓你在一張紙上表達清晰,顯然因爲紙張大小的限制你沒法無限地寫下去...

0.10.2二進制 中同 1/3十進制 中同樣,不屬於整數的範疇,因此只能用近似值來代替,因爲精度的限制 0.10.2 使用單精度浮點數表示的實際值爲:0.1000000014901161193847656250.20000000298023223876953125,把它們相加起來獲得的結果與咱們在一開始看到的很是類似:

在交易系統或者科學計算的場景中,若是須要更高的精度小數,可使用具備 28 個有效位數的 decimal 或者直接使用分數,不過這些表示方法的開銷也隨着有效位數的增長而提升,咱們應該按照須要選擇最合適的方法。

從新回到最開始的問題 — 0.10.2 相加不等於 0.3 的緣由包括如下兩個:

  • 使用二進制表達十進制的小數時,某些數字沒法被有限位的二進制小數表示;
  • 單精度和雙精度的浮點數只包括 7 位或者 15 位的有效小數位,存儲須要無限位表示的小數時只能存儲近似值;

在使用單精度和雙精度浮點數時也應該牢記它們只有 7 位和 15 位的有效位數

char 類型

char 用來表示單個字符。在 Java 中 char 類型的數據使用 16 位來存儲和表示,而許多編程語言則僅用 8 位。

char 類型的字面量值須要用 單引號 括起來。例如:'A' 是編碼值爲 65字符常量,它與 "A" 不一樣,"A" 是僅包含字符 A字符串 (String 類型)

強烈建議:不要在程序中使用 char 類型,除非您確實須要處理 UTF-16 代碼單元。

(更多相關資料放入了下面的自取資料,感興趣能夠去閱讀一下更多 char 類型的東西,不感興趣跳過便可...)

boolean 類型

boolean (布爾) 類型有兩個值:falsetrue (注意這兩個是布爾類型的字面常量也是保留字),用來判斷邏輯條件是否成立。

對象類型

Java 中的全部數據都屬於「基本數據類型」或「對象」中的一種。

雖然只有八種基本數據類型,但 Java 有許多知足您需求的相關類型的對象供您使用,例如,表示字符串的 String 類型。

咱們會在以後的內容中更多地討論對象 (由於 Java 是一種面向對象的編程語言),如今,您須要瞭解如下信息:

  • 基本數據類型使用少許的固定字節數 (下面會詳細介紹)
  • 只有 8 種基本數據類型,您沒法建立新的原始數據類型;
  • 一個對象是一個較大的數據塊,可能使用不少字節的內存;
  • 對象類型的數據被稱爲
  • Java 中已經封裝了足夠多的類用來知足您各種的需求,您也能夠發明新的類來知足程序的特定需求;

Part 2. 變量

計算機內存中有數以十億計的字節用於存儲機器指令和數據。

程序運行時,某些內存用於存儲機器指令,而另一些則用於存儲數據。後來,當另外一個程序運行時,之前保存的機器指令中的某些字節如今能夠用來保存數據,而以前保存的數據中的某些字節如今能夠保存機器指令。

計算機先驅 約翰·馮·諾依曼 (John von Neumann) 的想法是:使用相同的存儲器來存儲指令和數據

回想一下,數據類型是一種使用位模式來表示值的方案

能夠把 變量 視爲一個由一個或多個字節組成的小盒子,該盒子可使用特定的數據類型保存值。

要將值存儲在內存中,之後再取回它,則程序必須爲每一個變量指定一個名稱,如 className/ payAmount (變量名採用小駝峯命名法)

變量隨運行程序的須要而變化。當正在運行的程序再也不須要變量時,該內存部分可用於其餘目的。

聲明變量

在 Java 中,每一個變量都必須有一個類型 (type)。在聲明變量時,須要先指定變量的類型,而後是變量名:

double salary;
int vacationDays;
long earthPopluation;
boolean finished;

能夠看到,每一個變量都以分號 (;) 結束。因爲聲明是一條完整的 Java 語句,而全部的 Java 語句都以分號結束,因此這裏的分號是必須的。

變量命名

在 Java 中,變量命名須要遵循如下硬性規定和強烈建議遵照的非硬性規定:

硬性規則

  1. 變量名必須是一個以字母開頭並由字母或數字構成的序列 (儘管 $ 是合法的,但不要在你本身的代碼中使用這個字符,它只用在 Java 編譯器或其餘工具生成的名字中)
  2. 每個字符都有意義,且大小寫敏感;
  3. 不要使用 Java 中的保留字;

《阿里巴巴 Java 開發手冊》規則

  1. 【強制】 代碼中的命名 (全部標識符) 均不能如下劃線或美圓符號開始,也不能如下劃線或美圓符號結束;(反例: $name)
  2. 【強制] 代碼中的命名嚴禁使用拼音與英文混合的方式,更不容許直接使用中文的方式;(反例:DaZhePromotion - 打折)
  3. 【強制】 杜絕徹底不規範的縮寫,避免詞不達意;(反例:condition 縮寫成 condi)
  4. 【推薦】 爲了達到代碼自解釋的目的,任何自定義編程元素在命名時,使用盡可能完整的單詞組合來表達其意;(反例:int a; 的隨意命名方式)

變量初始化

聲明一個變量以後,必須用賦值語句對變量進行顯式初始化,千萬不要使用未初始化的變量的值。例如,Java 編譯器認爲下面的語句序列是錯誤的:

int amount;
System.out.println(amount); // ERROR -- variable not initialized

要相對一個已經聲明過的變量進行賦值,就須要將變量名放在等號 (=) 左側,再把一個適當取值放在等號的右側:

int amount;
amount = 12;

也能夠將變量的聲明和初始化放在同一行中。例如:

int amount = 12;

最後,在 Java 中能夠將聲明放在代碼中的任何地方。

但讓變量儘量地靠近變量第一次使用的地方,這是一種良好的程序編寫風格。

變量使用範例

咱們來使用變量完成兩個數的加減乘除:

int num1 = 2;
int num2 = 3;
System.out.println(num1 + num2);
System.out.println(num1 - num2);
System.out.println(num1 * num2);
System.out.println(num1 / num2);

Part 3. 運算符

計算機的最基本用途之一就是執行數學運算,做爲一門計算機語言,Java 也提供了一套豐富的運算符來操縱變量。咱們能夠把運算符分紅如下幾組:

  • 算術運算符;
  • 關係運算符;
  • 位運算符;
  • 邏輯運算符;
  • 賦值運算符;
  • 其餘運算符;

算術運算符

算術運算符用在數學表達式中,它們的做用和在數學中的做用同樣。下表列出了全部的算術運算符。

表格中的實例假設整數變量 A 的值爲 10,變量 B 的值爲 20

實例

下面的簡單示例程序演示了算術運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 25;
        int d = 25;
        System.out.println("a + b = " + (a + b));
        System.out.println("a - b = " + (a - b));
        System.out.println("a * b = " + (a * b));
        System.out.println("b / a = " + (b / a));
        System.out.println("b % a = " + (b % a));
        System.out.println("c % a = " + (c % a));
        System.out.println("a++   = " + (a++));
        System.out.println("a--   = " + (a--));
        // 查看  d++ 與 ++d 的不一樣
        System.out.println("d++   = " + (d++));
        System.out.println("++d   = " + (++d));
    }
}

運行結果:

a + b = 30
a - b = -10
a * b = 200
b / a = 2
b % a = 0
c % a = 5
a++   = 10
a--   = 11
d++   = 25
++d   = 27

i++ 與 ++i 到底有什麼不一樣?

實際上,無論是前置 ++,仍是後置 ++,都是先將變量的值加 1,而後才繼續計算的。

兩者之間真正的區別是前置 ++ 是將變量的值加 1 後,使用增值後的變量進行運算的,而後置 ++ 是首先將變量賦值給一個臨時變量,接下來對變量的值加 1,而後使用那個臨時變量進行運算。

關係運算符

下表爲Java支持的關係運算符。

表格中的實例整數變量 A 的值爲 10,變量 B 的值爲 20

實例

下面的簡單示例程序演示了關係運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("a == b = " + (a == b));
        System.out.println("a != b = " + (a != b));
        System.out.println("a > b = " + (a > b));
        System.out.println("a < b = " + (a < b));
        System.out.println("b >= a = " + (b >= a));
        System.out.println("b <= a = " + (b <= a));
    }
}

運行結果:

a == b = false
a != b = true
a > b = false
a < b = true
b >= a = true
b <= a = false

位運算符

Java定義了位運算符,應用於整數類型 (int),長整型 (long),短整型 (short),字符型 (char),和字節型 (byte) 等類型。

位運算符做用在全部的位上,而且按位運算。假設 a = 60,b = 13; 它們的二進制格式表示將以下:

A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A = 1100 0011

下表列出了位運算符的基本運算,假設整數變量 A 的值爲 60 和變量 B 的值爲 13

實例

下面的簡單示例程序演示了關係運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        int a = 60; /* 60 = 0011 1100 */
        int b = 13; /* 13 = 0000 1101 */
        int c = 0;
        c = a & b;       /* 12 = 0000 1100 */
        System.out.println("a & b = " + c);

        c = a | b;       /* 61 = 0011 1101 */
        System.out.println("a | b = " + c);

        c = a ^ b;       /* 49 = 0011 0001 */
        System.out.println("a ^ b = " + c);

        c = ~a;          /*-61 = 1100 0011 */
        System.out.println("~a = " + c);

        c = a << 2;     /* 240 = 1111 0000 */
        System.out.println("a << 2 = " + c);

        c = a >> 2;     /* 15 = 1111 */
        System.out.println("a >> 2  = " + c);

        c = a >>> 2;     /* 15 = 0000 1111 */
        System.out.println("a >>> 2 = " + c);
    }
}

運行結果:

a & b = 12
a | b = 61
a ^ b = 49
~a = -61
a << 2 = 240
a >> 2  = 15
a >>> 2 = 15

邏輯運算符

下表列出了邏輯運算符的基本運算,假設布爾變量 A 爲真,變量 B 爲假:

實例

下面的簡單示例程序演示了關係運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        boolean a = true;
        boolean b = false;
        System.out.println("a && b = " + (a && b));
        System.out.println("a || b = " + (a || b));
        System.out.println("!(a && b) = " + !(a && b));
    }
}

運行結果:

a && b = false
a || b = true
!(a && b) = true

短路邏輯運算符

當使用與邏輯運算符時,在兩個操做數都爲 true 時,結果才爲 true,可是當獲得第一個操做爲 false 時,其結果就一定是 false,這時候就不會再判斷第二個操做了。

事實上,若是全部的邏輯表達式都有一部分沒必要計算,那將得到潛在的性能提高。

實例:

public class LuoJi {

    public static void main(String[] args) {
        int a = 5;//定義一個變量;
        boolean b = (a < 4) && (a++ < 10);
        System.out.println("使用短路邏輯運算符的結果爲" + b);
        System.out.println("a的結果爲" + a);
    }
}

運行結果:

使用短路邏輯運算符的結果爲false
a的結果爲5

賦值運算符

下面是 Java 語言支持的賦值運算符:

實例

下面的簡單示例程序演示了關係運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 0;
        c = a + b;
        System.out.println("c = a + b = " + c);
        c += a;
        System.out.println("c += a  = " + c);
        c -= a;
        System.out.println("c -= a = " + c);
        c *= a;
        System.out.println("c *= a = " + c);
        a = 10;
        c = 15;
        c /= a;
        System.out.println("c /= a = " + c);
        a = 10;
        c = 15;
        c %= a;
        System.out.println("c %= a  = " + c);
        c <<= 2;
        System.out.println("c <<= 2 = " + c);
        c >>= 2;
        System.out.println("c >>= 2 = " + c);
        c >>= 2;
        System.out.println("c >>= 2 = " + c);
        c &= a;
        System.out.println("c &= a  = " + c);
        c ^= a;
        System.out.println("c ^= a   = " + c);
        c |= a;
        System.out.println("c |= a   = " + c);
    }
}

運行結果:

c = a + b = 30
c += a  = 40
c -= a = 30
c *= a = 300
c /= a = 1
c %= a  = 5
c <<= 2 = 20
c >>= 2 = 5
c >>= 2 = 1
c &= a  = 0
c ^= a   = 10
c |= a   = 10

其餘運算符

條件運算符 (?:)

條件運算符也被稱爲三元運算符。該運算符有 3 個操做數,而且須要判斷布爾表達式的值。該運算符的主要是決定哪一個值應該賦值給變量。

variable x = (expression) ? value if true : value if false

實例

下面的簡單示例程序演示了關係運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:

public class Test {

    public static void main(String[] args) {
        int a, b;
        a = 10;
        // 若是 a 等於 1 成立,則設置 b 爲 20,不然爲 30
        b = (a == 1) ? 20 : 30;
        System.out.println("Value of b is : " + b);

        // 若是 a 等於 10 成立,則設置 b 爲 20,不然爲 30
        b = (a == 10) ? 20 : 30;
        System.out.println("Value of b is : " + b);
    }
}

運行結果:

Value of b is : 30
Value of b is : 20

instanceof 運算符

該運算符用於操做對象實例,檢查該對象是不是一個特定類型(類類型或接口類型)。

instanceof 運算符使用格式以下:

( Object reference variable ) instanceof  (class/interface type)

若是運算符左側變量所指的對象,是操做符右側類或接口 (class/interface) 的一個對象,那麼結果爲真。

下面是一個例子:

String name = "James";
boolean result = name instanceof String; // 因爲 name 是 String 類型,因此返回真

要點回顧

  1. Java 是一種強類型語言,任何一種數據都屬於 1 種基本類型或者對象類型 (類) 中的一種;
  2. 8 種基本數據類型;
  3. 爲何引入變量、如何定義使用變量以及變量名的命名規範;
  4. Java 中的運算符以及使用實例;

練習

獲取用戶輸入 Scanner

java.util.Scanner 是 Java5 的新特徵,咱們能夠經過 Scanner 類來獲取用戶的輸入。

下面是建立 Scanner 對象的基本語法:

Scanner scanner = new Scanner(System.in);

在下面的示例中,咱們將使用該類的 nextLine() 方法,該方法用於讀取字符串:

import java.util.Scanner;  // Import the Scanner class

class MyClass {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);  // Create a Scanner object
        System.out.println("Enter username");

        String userName = scanner.nextLine();  // Read user input
        System.out.println("Username is: " + userName);  // Output user input
    }
}

輸入類型

在上面的示例中,咱們使用了 nextLine() 用於讀取字符串的方法。要閱讀其餘類型,請查看下錶:

練習 1:輸入圓的半徑計算周長和麪積

參考答案:

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        System.out.println("請輸入圓的半徑:");

        Scanner scanner = new Scanner(System.in);
        int radius = scanner.nextInt();

        // 計算周長和麪積
        double area = radius * radius * 3.14;
        double perimeter = 2 * 3.14 * radius;

        System.out.println("該圓的面積爲:" + area);
        System.out.println("該圓的周長爲:" + perimeter);
    }
}

練習 2:輸入年份判斷是否是閏年

提示:

閏年須要知足:

  1. 能被 4 整除,而且不能被 100 整除;
  2. 或者能被 400 整除;

參考答案:

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        System.out.println("請輸入年份:");

        Scanner scanner = new Scanner(System.in);
        int year = scanner.nextInt();

        boolean leapYear;

        boolean divisbleBy4 = year % 4 == 0;
        boolean notDivisbleBy100 = year % 100 != 0;
        boolean divisibleBy400 = year % 400 == 0;
        leapYear = (divisbleBy4 && notDivisbleBy100) || divisibleBy400;

        System.out.println("該年份是不是閏年:" + leapYear);
    }
}

自取資料

擴展閱讀推薦

  1. Java 基本數據類型 | 菜鳥教程 - https://www.runoob.com/java/j...
  2. 浮點類型精度深度討論:

    1. 爲何 0.1 + 0.2 = 0.3? - https://draveness.me/whys-the...
    2. 爲何 0.1 + 0.2 = 0.300000004? - https://draveness.me/whys-the...:2
  3. IEEE754標準: 浮點數在內存中的存儲方式 - https://www.jianshu.com/p/8ee...
  4. 爲何Java中char類型不能完整表示一個字符? - https://fookwood.com/java-str...

推薦書籍

Java 核心技術·卷 I(原書第 11 版)

推薦理由: 這本書在知識體系完整充實的同時,又比《Thinking in Java》暴風式的知識洗禮來得輕鬆,新人入門書籍強烈推薦!

碼出高效:Java開發手冊

推薦理由: 阿里系出品。從最基礎的計算機基礎入手,到 Java 的方方面面,加上精美的配圖和通俗易懂的解釋,是很是適合新手閱讀的一本兒關於 Java 的技術書籍。

參考資料

  1. Introduction to Computer Science using Java - http://programmedlessons.org/...
  2. Java 運算符 | 菜鳥教程 - https://www.runoob.com/java/j...
  3. 《Java 核心技術 卷I》(第11版)
  • 本文已收錄至個人 Github 程序員成長系列 【More Than Java】,學習,不止 Code,歡迎 star:https://github.com/wmyskxz/MoreThanJava
  • 我的公衆號 :wmyskxz,我的獨立域名博客:wmyskxz.com,堅持原創輸出,下方掃碼關注,2020,與您共同成長!

很是感謝各位人才能 看到這裏,若是以爲本篇文章寫得不錯,以爲 「我沒有三顆心臟」有點東西 的話,求點贊,求關注,求分享,求留言!

創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!

相關文章
相關標籤/搜索