1.內(nèi)存分配
1.寄存器-最快的存儲區(qū),位于處理器內(nèi)部,無法直接控制
2.堆棧:位于RAM,隨機訪問存儲器中,可通過堆棧指針從處理器那里獲得直接支持;堆棧指針,向上移動,則分配內(nèi)存;向下移動, 則釋放內(nèi)存;不過創(chuàng)建程序時,Java系統(tǒng)必須知道存儲在堆棧內(nèi)所有項的生命周期,以便上下移動堆棧指針;這一約束,限制了程序的靈活性;
Java對象引用存儲于堆棧中;而Java對象不存儲于其中
3.堆:一種通用的內(nèi)存區(qū),也位于RAM區(qū),用于存放所有的Java對象;堆不同于堆棧的好處是:編譯器不需要知道存儲的數(shù)據(jù)在堆里存活多長時間;因此在堆里存儲有很大的靈活性;當(dāng)需要一個對象時,只需要new寫一行簡單的代碼,當(dāng)執(zhí)行這行代碼時,會自動在堆里進行存儲分配;
用堆進行存儲分配和清理可能比堆棧進行存儲分配需要更多的時間;
4.常量存儲:常量值通常存儲在程序代碼內(nèi)部,這樣做是安全的,因為他們永遠不會被改變;
5.非RAM存儲:
如流對象和持久化對象;在流對象中,對象轉(zhuǎn)換成字節(jié)流,通常被發(fā)送給另一臺機器;在“持久化”對象中,對象被存放于磁盤上;這種存儲方式的技巧在于把對象可以轉(zhuǎn)化為其他媒介上的事物,他們?nèi)钥梢员3肿约旱臓顟B(tài),在需要時,可以恢復(fù)成常規(guī)的,基于RAM的對象;Java提供了對輕量級持久化的支持,而諸如JDBC和HIBERNATE這樣的機制提供了更加復(fù)雜的對在數(shù)據(jù)庫存儲和讀取對象信息的支持.
2.基本類型是特例:
小,簡單;不用new來創(chuàng)建變量,而是創(chuàng)建一個并非引用的“自動”變量,這個變量直接存儲值,并置于堆棧中,因此更加高效;
因為new將對象存儲在“堆”中,故用new創(chuàng)建一個對象,特別是小的簡單的變量,往往不是很有效;
3.所有數(shù)值類型都有正負號-每種基本類型所占存儲空間的大小都是不變的
char:16bits
byte:8bits
short:16bits
int:32bits
long:64bits
float:32bits
double:64bits
4.數(shù)組:當(dāng)創(chuàng)建一個數(shù)組對象時,其實是創(chuàng)建了一個引用數(shù)組;并且每個引用會被自動初始化為一個特定值,null
對于用來存放基本類型的數(shù)組,編譯器也能確保這種數(shù)組的初始化,因為它會將會這種數(shù)組所占的內(nèi)存全部置0
5.二進制碼補充學(xué)習(xí)
2 二進制 為10
其實全部顯示為00000000000000000000000000000010,高位為0,表示為正
-2 二進制為11111111111111111111111111111110
其計算方法為:
1.首先是找到正數(shù)2的二進制形式00000000000000000000000000000010
2.按位取反->111111111111111111111111111111101
3.加1->11111111111111111111111111111110
將11111111111111111111111111111110變?yōu)檎麛?shù)
1.首先判斷其為負數(shù),按位取反->0000000000000000000000000000001
2.加1->00000000000000000000000000000010
3.2步驟后,得結(jié)果為2,然后因為是負數(shù),所以加一個符號,得-2
所以補碼的設(shè)計目的是:
⑴ 使符號位能與有效值部分一起參加運算,從而簡化運算規(guī)則。補碼機器數(shù)中的符號位,并不是強加上去的,是數(shù)據(jù)本身的自然組成部分,可以正常地參與運算。
⑵ 使減法運算轉(zhuǎn)換為加法運算,進一步簡化計算機中運算器的線路設(shè)計。
(3)為了統(tǒng)一正0和負0
有符號數(shù):
最高位是符號位,0表示正,1表示負
反碼表示法規(guī)定:正數(shù)的反碼與其原碼相同;負數(shù)的反碼是對其原碼逐位取反,但符號位除外。
補碼表示法規(guī)定:正數(shù)的補碼與其原碼相同;負數(shù)的補碼是在其反碼的末位加1。
原碼表示雖然很簡單,用原碼來進行加減運算會出問題,
問題出在帶符號位的負數(shù)上
反碼表示,將加減數(shù)都表示成反碼后,減法可以直接表示成加法
問題出在(+0)和(-0)上,在人們的計算概念中零是沒有正負之分的,于是就出現(xiàn)了補碼,正數(shù)的補碼不變,負數(shù)的補碼是將其反碼加1
原碼和反碼中,+0與-0的表示并不相同,所以計算機中一般使用補碼。還有利用高位溢出,將減法運算變成加法運算
模的概念:把一個計量單位稱之為模或模數(shù)。例如,時鐘是以12進制進行計數(shù)循環(huán)的,即以12為模。在時鐘上,時針加上(正撥)12的整數(shù)位或減去(反撥)12的整數(shù)位,時針的位置不變。14點鐘在舍去模12后,成為(下午)2點鐘(14=14-12=2)。從0點出發(fā)逆時針撥10格即減去10小時,也可看成從0點出發(fā)順時針撥2格(加上2小時),即2點(0-10=-10=-10+12=2)。因此,在模12的前提下,-10可映射為+2。由此可見,對于一個模數(shù)為12的循環(huán)系統(tǒng)來說,加2和減10的效果是一樣的;因此,在以12為模的系統(tǒng)中,凡是減10的運算都可以用加2來代替,這就把減法問題轉(zhuǎn)化成加法問題了(注:計算機的硬件結(jié)構(gòu)中只有加法器,所以大部分的運算都必須最終轉(zhuǎn)換為加法)。10和2對模12而言互為補數(shù)。
同理,計算機的運算部件與寄存器都有一定字長的限制(假設(shè)字長為8),因此它的運算也是一種模運算。當(dāng)計數(shù)器計滿8位也就是256個數(shù)后會產(chǎn)生溢出,又從頭開始計數(shù)。產(chǎn)生溢出的量就是計數(shù)器的模,顯然,8位二進制數(shù),它的模數(shù)為8=256。在計算中,兩個互補的數(shù)稱為“補碼”。
a. 采用補碼后,可以方便地將減法運算轉(zhuǎn)化成加法運算,運算過程得到簡化。正數(shù)的補碼即是它所表示的數(shù)的真值,而負數(shù)的補碼的數(shù)值部份卻不是它所表示的數(shù)的真值。采用補碼進行運算,所得結(jié)果仍為補碼。
b. 與原碼、反碼不同,數(shù)值0的補碼只有一個,即 [0]補=00000000B。
c. 若字長為8位,則補碼所表示的范圍為-128~+127;進行補碼運算時,應(yīng)注意所得結(jié)果不應(yīng)超過補碼所能表示數(shù)的范圍。
6.部分源碼
package com.book.chap2.operator;

/** *//**
*
*直接常量
*<p>byte,short,int,long均有符號和無符號之分,如byte[-128-127]</p>
*<p>Integer.toBinaryString</p>
*
*@author landon
*@since JDK1.6
*@version 1.0 2012-3-21
*
*/
public class Literals


{
public static void main(String
args)

{
//0x-16進制
int i1 = 0x2f;//f 小寫
//轉(zhuǎn)為2進制
System.out.println("i1:" + Integer.toBinaryString(i1));
//轉(zhuǎn)為16進制
System.out.println("i1:" + Integer.toHexString(i1));
//轉(zhuǎn)為8進制
System.out.println("i1:" + Integer.toOctalString(i1));
System.out.println(i1);
//0x-16進制
int i2 = 0x2F;//F 大寫
System.out.println("i2:" + Integer.toBinaryString(i1));
System.out.println(i2);
//0-8進制
int i3 = 0177;
System.out.println("i3:" + Integer.toBinaryString(i3));
//char能表示的16進制的最大值,char,2個字節(jié),因為是字符->0-2的16次方-1
char c = 0xffff;
System.out.println("c:" + Integer.toBinaryString(c));
//byte的16進制表示的最大值,因為byte1個字節(jié),-128-127
byte b = 0x7f;
System.out.println("b:" + Integer.toBinaryString(b));
//short的16進制表示的最大值
short s = 0x7fff;
System.out.println("s:" + Integer.toBinaryString(s));
//long的后綴--小寫l容易和1混淆
long n1 = 200L;
long n2 = 200l;
//float的后綴
float f1 = 1;
float f2 = 1f;
float f3 = 1F;
//double的后綴
double d1 = 1;
double d2 = 1d;
double d3 = 1D;
//TODO 此會編譯錯誤,因為0.2默認為double,應(yīng)該改為0.2f
// float f4 = 0.2;
float f5 = 0.2f;
//TODO 試圖向一個變量賦值超過自身范圍的數(shù)值,編譯器會報錯
//byte b2 = 128;Type mismatch: cannot convert from int to byte
byte b2 = 127;
//TODO 輸出各數(shù)據(jù)類型的最大值/最小值
System.out.println("byte:" + Byte.MIN_VALUE + "-" + Byte.MAX_VALUE +
" " + Integer.toHexString(Byte.MIN_VALUE) + "-" + Integer.toHexString(Byte.MAX_VALUE));
System.out.println("char:" + Character.MIN_VALUE + "-" + Character.MAX_VALUE +
" " + Integer.toHexString(Character.MIN_VALUE) + "-" + Integer.toHexString(Character.MAX_VALUE));
System.out.println("short:" + Short.MIN_VALUE + "-" + Short.MAX_VALUE +
" " + Integer.toHexString(Short.MIN_VALUE) + "-" + Integer.toHexString(Short.MAX_VALUE));
System.out.println("int:" + Integer.MIN_VALUE + "-" + Integer.MAX_VALUE +
" " + Integer.toHexString(Integer.MAX_VALUE) + "-" + Integer.toHexString(Integer.MIN_VALUE));
System.out.println("long:" + Long.MIN_VALUE + "-" + Long.MAX_VALUE +
" " + Long.toHexString(Long.MAX_VALUE) + "-" + Long.toHexString(Long.MIN_VALUE));
//TODO 將float或者double轉(zhuǎn)為整型的時候,總會截尾
System.out.println((int)0.1);
System.out.println((int)0.9f);
//TODO 如果需要舍入,則需Math.round
System.out.println(Math.round(0.9));
System.out.println(Math.round(0.4));
}
}

package com.book.chap2.operator;

//TODO 靜態(tài)導(dǎo)入,這樣就不必每次都敲System.out了
import static java.lang.System.out;

/** *//**
*
*循環(huán)標(biāo)簽-標(biāo)簽是后面跟有冒號的標(biāo)識符
*<p>
* 1.java中,標(biāo)簽起作用的唯一地方是剛好在迭代語句之前:即在標(biāo)簽和迭代語句之間置入任何語句都不好
* 2.在迭代之前設(shè)置標(biāo)簽的唯一理由是:我們希望在其中嵌套另一個迭代或者一個開關(guān)switch;break和continue只能中斷當(dāng)前循環(huán),與標(biāo)簽一起使用,則會中斷循環(huán),直到標(biāo)簽所在地方
* 3.注意:在java中使用標(biāo)簽的理由就是因為有嵌套迭代的存在,而且想從多層嵌套中break或者continue
*</p>
*
*@author landon
*@since JDK1.6
*@version 1.0 2012-3-21
*
*/
public class LoopLabel


{
public static void main(String
args)

{
int i = 0;
//label
OUTER:
while(true)

{
System.out.println("outter while loop");
while(true)

{
i++;
System.out.println("i = " + i);
if(i == 1)

{
out.println("continue");
continue;
}
//TODO 帶標(biāo)簽的continue回達到標(biāo)簽的位置,然后并重新進入緊接在那個標(biāo)簽后面的循環(huán)
if(i == 3)

{
out.println("continue outer");
continue OUTER;
}
if(i == 5)

{
out.println("break");
break;
}
//TODO 帶標(biāo)簽的break會中斷并跳出標(biāo)簽所指的循環(huán)
if(i == 7)

{
out.println("break outer");
break OUTER;
}
}
}
}
}

package com.book.chap2.operator;



/** *//**
*
*移位
*<pre>
* 1.左移<<,按照操作符右側(cè)指定的位數(shù)將操作符左側(cè)的操作數(shù)向左移動,低位補0
* 2.“有符號”右移>>,按照操作符右側(cè)指定的位數(shù)將操作符左側(cè)的操作數(shù)向右移動;“有符號”操作符>>使用符號擴展:若符號為正,則在高位插入0;若符號為負,則在高位插入1
* 3."無符號"右移,Java新增,它使用零擴展,無論正負,都在高位插入0
*</pre>
*
*@author landon
*@since JDK1.6
*@version 1.0 2012-3-21
*
*/
public class ShiftBit


{
public static void main(String
args)

{
int j = 2;
//正-左移
System.out.println("before shift:"+ j + " " + Integer.toBinaryString(j));
int shitfJ1 = j << 5;
System.out.println("after shift:"+ shitfJ1 + " " + Integer.toBinaryString(shitfJ1));
int k = -2;
//負-左移
System.out.println("before shift:"+ k + " " + Integer.toBinaryString(k));
int shitfk1 = k << 5;
System.out.println("after shift:"+ shitfk1 + " " + Integer.toBinaryString(shitfk1));
int i = 128;
//正-右移
System.out.println("before shift:"+ i + " " + Integer.toBinaryString(i));
int shitfI1 = i >> 5;
System.out.println("after shift:"+ shitfI1 + " " + Integer.toBinaryString(shitfI1));
//負-右移,符號為負,右移的時候,高位插入1
int m = -128;
System.out.println("before shift:"+ m + " " + Integer.toBinaryString(m));
int shitfm1 = m >> 5;
System.out.println("after shift:"+ shitfm1 + " " + Integer.toBinaryString(shitfm1));
int n = 128;
//正-無符號右移,無論正負,高位均插入0
System.out.println("before shift:"+ n + " " + Integer.toBinaryString(n));
int shitn1 = n >>> 5;
System.out.println("after shift:"+ shitn1 + " " + Integer.toBinaryString(shitn1));
//負-無符號右移,無論正負,高位均插入0-->這樣一個負數(shù)就變成了正數(shù)
int o = -128;
System.out.println("before shift:"+ o + " " + Integer.toBinaryString(o));
int shitfo1 = o >>> 5;
System.out.println("after shift:"+ shitfo1 + " " + Integer.toBinaryString(shitfo1));
}
}
