前言
Java中共有八種基本數據類型:byte,int,short,long,float,double,char,boolean。
計算機中的基礎數據單位是bit, 1byte=8bit。
數據類型 | 存儲大小 | 舉例 | 注釋 | 包裝類 |
---|---|---|---|---|
byte | 1byte | 3 | 字節 | Byte |
int | 4byte | 4 | 整數 | Integer |
short | 2bytes | 5 | 短整數 | Short |
long | 8bytes | 6 | 長整數 | Long |
float | 4bytes | 1.3 | 單精度浮點型 | Float |
double | 8bytes | 1.2 | 雙精度浮點型 | Double |
char | 2bytes | ‘a' | 字符 | Char |
boolean | 1bit | true | 布爾值 | Boolean |
這8種基本數據類型很簡單,在示例中應用來看一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Test { public static void main(String[] args){ System.out.println( "8種基本數據類型" ); int a= 5 ; System.out.println(a); char b= 'z' ; System.out.println(b); boolean d= false ; System.out.println(d); byte e= 3 ; System.out.println(e); short f= 4 ; System.out.println(f); long g= 32000000 ; System.out.println(g); float h= 5 ; System.out.println(h); double i= 6 ; System.out.println(i); } } |
一段簡單的輸出代碼,看看打印結果:
1
2
3
4
5
6
7
8
9
|
8種基本數據類型 5 z false 3 4 32000000 5.0 6.0 |
可以看到輸出結果是沒有問題的。
基本數據類型和對象引用
基本數據類型會一直在棧中創建,當聲明基本類型時,不需要new。
1
|
int a= 1 ; |
棧的讀取速度比堆快。基本類型一旦被聲明,java將在棧上直接存儲它,所以基本類型的變量表示的是數據本身。
假如調用基本類型的包裝類來創建對象,那么將會在堆中創建。
1
|
Employee a= new Emploee( 1.4 ); |
等號右側的new Double()
。這個new是在內存的堆中為對象開辟控件,保存對象的數據和方法。
等號左側 Double a。a指代的是Double的一個對象,稱為對象引用,這個對象引用是在棧中創建的。實際上a不是對象本身,它用來指向一個地址。
賦值=。這個就是把對象的地址賦給a。
此時輸出a就是一個內存地址。有興趣的同學自己試一試。
這個地方說明一個問題,假如你自定義的對象重寫了.toString
方法,此處就會顯示你的自定義的重寫方法的輸出值。
在java的基本類型包裝類中就重寫了這個方法,所以調用print方法時會自動調用它的toString()
方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Wrapper { static class Employee{ static int age; Employee( int a){ age=a; } } static class Employer{ static int year; Employer ( int y){ year=y; } @Override public String toString() { return "Employer's year=" +year; } } public static void main(String[] args){ Employee e= new Employee( 4 ); System.out.println( "e=" +e); Employer f= new Employer( 5 ); System.out.println( "f=" +f); } } |
在上邊的例子中Employee的toString()
方法沒有被重寫,Employer的toString()
方法被重寫了。
來看輸出結果:
1
2
|
e=Wrapper$Employee @1b6d3586 f=Employer's year= 5 |
前者仍然是內存地址,后者是我們重寫的方法。
print方法在調用事,假如類中的toString()
方法沒有被重寫,則會電泳String.valueof()
方法(后邊有講),假如重寫了就會調用toString方法。
所有的包裝類(Integer,Boolean等)都已經重寫了toString方法,所以不會輸出內存地址,而是輸出正確的值。
下面的是Double類中的方法:
1
2
3
4
|
private final double value; public String toString() { return toString(value); } |
整形數據類型取值范圍
byte占據8位,則其取值范圍應該是2的8次方,也就是-128~127,超過這個區間就會報錯,例如:
1
|
byte a= 128 ; |
在編譯器中會報錯,提示不能將int轉換為byte,因為128已經超出byte的范圍了。
同樣可以推得其他值的取值范圍。
基本類型的數組輸出值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class TestOne { public static void main(String[] args) { int a= 127 ; System.out.println(a); int [] b= new int []{ 1 , 2 , 3 }; System.out.println(b); int [] c= new int [ 100 ]; System.out.println(c); int [] d={ 1 , 2 , 3 }; System.out.println(d); boolean e= false ; System.out.println(e); boolean [] f={ false , false , true }; System.out.println(f); char g= 'a' ; System.out.println(g); char [] h={ 'a' , 'b' , 'c' }; System.out.println(h); char [] i= new char []{ 'a' , 'b' , 'c' }; System.out.println(i); float j= 1 .2f; System.out.println(j); float [] k={ 1 .2f, 1 .3f, 1 .4f}; System.out.println(k); } } |
看一下打印的結果:
1
2
3
4
5
6
7
8
9
10
11
|
127 [I@15db9742 [I@6d06d69c [I@7852e922 false [Z@4e25154f a abc abc 1.2 [F@70dea4e |
可以看到,在結果中,所有的基本類型都可以打印出來,數組類型只能打印出char數組,其他的都是內存地址。
來看一下源碼,在print函數中
1
2
3
|
public void print( char c) { write(String.valueOf(c)); } |
這個char被轉換為了String類型,然后進行wirte方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private void write(String s) { try { synchronized ( this ) { ensureOpen(); textOut.write(s); textOut.flushBuffer(); charOut.flushBuffer(); if (autoFlush && (s.indexOf( '\n' ) >= 0 )) out.flush(); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true ; } } |
這里會立即發送緩沖流輸出。
對于所有的基礎類型都會打印出具體的值,這個沒有問題,但是對于數組為什么只有char的數組類型打印出了正確的結果而沒有輸出內存地址?
帶著這個問題我們來了解一下:
對于int型數組,java調用的是下面的方法:
1
2
3
4
5
6
7
|
public void println(Object x) { String s = String.valueOf(x); synchronized ( this ) { print(s); newLine(); } } |
此處數組被認為是Object類型,調用的是
1
2
3
|
public static String valueOf(Object obj) { return (obj == null ) ? "null" : obj.toString(); } |
此處的三目表達式用來判空,然后看一下obj.toString()
方法:
1
2
3
|
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } |
相信看到此處應該可以看出來為什么輸出會是[I@1b6d3586了,I代表的類的名稱。
那么對于char數組類型的調用呢,次數室友玄機的:
1
2
3
4
5
6
|
public void println( char x[]) { synchronized ( this ) { print(x); newLine(); } } |
此處調用的是println(char x[])
這個函數,那么這個char x[]
是個什么鬼呢?
其實就是java中的數組初始化,相當于char[] x
。
然后看看print(x)
函數:
1
2
3
|
public void print( char s[]) { write(s); } |
最后是write()
函數:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private void write( char buf[]) { try { synchronized ( this ) { ensureOpen(); textOut.write(buf); textOut.flushBuffer(); charOut.flushBuffer(); if (autoFlush) { for ( int i = 0 ; i < buf.length; i++) if (buf[i] == '\n' ) out.flush(); } } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true ; } } |
到了這大家知道為什么會有區別了么,因為其他類型的數組都被認為是Object類型了,所以會輸出內存地址。而char[]調用的方法是輸出char這個數組中的每一個值,所以不是內存地址了。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。