java學習中的一些疑惑解答

Tory49R 8年前發布 | 7K 次閱讀 Java Java開發

一、java中的枚舉類型:

在實際編程中,往往存在著這樣的“數據集”,它們的數值在程序中是穩定的,而且“數據集”中的元素是有限的。例如星期一到星期日七個數據元素組成了一周的“數據集”,春夏秋冬四個數據元素組成了四季的“數據集”。在java中如何更好的使用這些“數據集”呢?因此枚舉便派上了用場,下面的一段代碼來說明枚舉類型的特點和用法:

public class EnumTest {

public static void main(String[] args) {
    Size s=Size.SMALL;
    Size t=Size.LARGE;
    //s和t引用同一個對象?
    System.out.println(s==t);  //
    //是原始數據類型嗎?
    System.out.println(s.getClass().isPrimitive());
    //從字符串中轉換
    Size u=Size.valueOf("SMALL");
    System.out.println(s==u);  //true
    //列出它的所有值
    for(Size value:Size.values()){
        System.out.println(value);
    }
}

} enum Size{SMALL,MEDIUM,LARGE}; </code></pre>

從運行結果來看

(1)枚舉類型中的元素不是一個對象,枚舉是一個數據集,它的每個具體值都引用一個特定的對象。相同的值則引用同一個對象。

(2)枚舉類型是一種新的數據類型,并非是原始數據類型

(3)枚舉類型中的元素可以轉換為字符串類型,并且里面的所以元素可以列舉出來

二、反碼,補碼,原碼的理解:

在學習原碼, 反碼和補碼之前, 需要先了解機器數和真值的概念。

1、機器數

一個數在計算機中的二進制表示形式,  叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數為0, 負數為1.

比如,十進制中的數 +3 ,計算機字長為8位,轉換成二進制就是00000011。如果是 -3 ,就是 10000011 。

那么,這里的 00000011 和 10000011 就是機器數。

2、真值

因為第一位是符號位,所以機器數的形式值就不等于真正的數值。例如上面的有符號數 10000011,其最高位1代表負,其真正數值是 -3 而不是形式值131(10000011轉換成十進制等于131)。所以,為區別起見,將帶符號位的機器數對應的真正數值稱為機器數的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

對于一個數, 計算機要使用一定的編碼方式進行存儲. 原碼, 反碼, 補碼是機器存儲一個具體數字的編碼方式.

1. 原碼

原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值. 比如如果是8位二進制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符號位. 因為第一位是符號位, 所以8位二進制數的取值范圍就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原碼是人腦最容易理解和計算的表示方式.

2. 反碼

反碼的表示方法是:正數的反碼是其本身,負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可見如果一個反碼表示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算.

3. 補碼

補碼的表示方法是:正數的補碼就是其本身,負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1. (即在反碼的基礎上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]補

[-1] = [10000001]原 = [11111110]反 = [11111111]補

對于負數, 補碼表示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值.

三、Java中同名變量的屏蔽原則:

每個變量都有一個“有效”的區域(稱為“作用域”),出了這個區域,變量將不再有效,同名的變量在指定的范圍內有自動屏蔽的原則。即局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。下面以一段程序來進行說明:

public class Test {
    private static int value = 1;
    public static void main(String[] args) {
        int value = 2;
        System.out.println(value);

輸出結果是:2。顯然可以看出value=1的是全局變量,而value=2的是全局變量。

四、Java中數據類型的轉換規則:

基本數據類型的轉換是指由系統根據轉換規則自動完成,不需要程序員明確地聲明不同數據類型之間的轉換。轉換在編譯器執行,而不是等到運行期再執行。

具體規則:

(1)布爾型和其它基本數據類型之間不能相互轉換;

(2)byte型可以轉換為short、int、long、float和double;

(3)short可轉換為int、long、float和double;

(4)char可轉換為int、long、float和double;

(5)int可轉換為long、float和double;

(6)long可轉換為float和double;

(7)float可轉換為double;

注:(其中除了float類型轉換為double類型為無精度損失,其他類型轉換為double類型都是有精度損失)

也就是說,只能有取值窄的范圍向寬范圍轉換,反之則不行。

五、問題:為什么double類型的數值進行運算得不到“數學上精確”的結果?

答案:這個涉及到二進制與十進制的轉換問題。N進制可以理解為:數值×基數的冪,例如我們熟悉的十進制數123.4=1×102+2×10+3×(10的0次冪)+4×(10的-1次冪);其它進制的也是同理,例如二進制數11.01=1×2+1×(2的0次冪)+0+1×(2的-2次冪)=十進制的3.25。

double類型的數值占用64bit,即64個二進制數,除去最高位表示正負符號的位,在最低位上一定會與實際數據存在誤差(除非實際數據恰好是2的n次方)。

舉個例子來說,比如要用4bit來表示小數3.26,從高到低位依次對應2的1,0,-1,-2次冪,根據最上面的分析,應當在二進制數11.01(對應十進制的3.25)和11.10(對應十進制的3.5)之間選擇。

簡單來說就是我們給出的數值,在大多數情況下需要比64bit更多的位數才能準確表示出來(甚至是需要無窮多位),而double類型的數值只有64bit,后面舍去的位數一定會帶來誤差,無法得到“數學上精確”的結果。

六、Java中輸出的加號連接符的使用:

首先看看下面的代碼輸出結果:

public static void main(String[] args) {
    int X=100;
    int Y=200;
    System.out.println("X+Y="+X+Y);
    System.out.println(X+Y+"=X+Y");
 }

輸出結果為:

從輸出結果我們可以看出只有與 ” ” 字符串直接相連的后面 “+” 加號才會都被定義成連接符。

System.out.println(“X+Y=”+X+Y); 這條輸出語句打印的內容 ”  ” 字符串后面的兩個 “+” 加號都會被定義成連接符,所以是100200而不是300.

System.out.println(X+Y+”=X+Y”); 而這條輸出語句打印的內容前面的X+Y會先運算的,因為前面的 “+” 加號還是運算符,Y后面的+加號才是連接符。只有與 ” ” 字符串直接相連時后面 “+” 加號才會都被定義成連接符。

 

來自:http://www.58maisui.com/2016/10/08/673/

 

 本文由用戶 Tory49R 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!