1.內存分配
1.寄存器-最快的存儲區,位于處理器內部,無法直接控制
2.堆棧:位于RAM,隨機訪問存儲器中,可通過堆棧指針從處理器那里獲得直接支持;堆棧指針,向上移動,則分配內存;向下移動, 則釋放內存;不過創建程序時,Java系統必須知道存儲在堆棧內所有項的生命周期,以便上下移動堆棧指針;這一約束,限制了程序的靈活性;
Java對象引用存儲于堆棧中;而Java對象不存儲于其中
3.堆:一種通用的內存區,也位于RAM區,用于存放所有的Java對象;堆不同于堆棧的好處是:編譯器不需要知道存儲的數據在堆里存活多長時間;因此在堆里存儲有很大的靈活性;當需要一個對象時,只需要new寫一行簡單的代碼,當執行這行代碼時,會自動在堆里進行存儲分配;
用堆進行存儲分配和清理可能比堆棧進行存儲分配需要更多的時間;
4.常量存儲:常量值通常存儲在程序代碼內部,這樣做是安全的,因為他們永遠不會被改變;
5.非RAM存儲:
如流對象和持久化對象;在流對象中,對象轉換成字節流,通常被發送給另一臺機器;在“持久化”對象中,對象被存放于磁盤上;這種存儲方式的技巧在于把對象可以轉化為其他媒介上的事物,他們仍可以保持自己的狀態,在需要時,可以恢復成常規的,基于RAM的對象;Java提供了對輕量級持久化的支持,而諸如JDBC和HIBERNATE這樣的機制提供了更加復雜的對在數據庫存儲和讀取對象信息的支持.
2.基本類型是特例:
小,簡單;不用new來創建變量,而是創建一個并非引用的“自動”變量,這個變量直接存儲值,并置于堆棧中,因此更加高效;
因為new將對象存儲在“堆”中,故用new創建一個對象,特別是小的簡單的變量,往往不是很有效;
3.所有數值類型都有正負號-每種基本類型所占存儲空間的大小都是不變的
char:16bits
byte:8bits
short:16bits
int:32bits
long:64bits
float:32bits
double:64bits
4.數組:當創建一個數組對象時,其實是創建了一個引用數組;并且每個引用會被自動初始化為一個特定值,null
對于用來存放基本類型的數組,編譯器也能確保這種數組的初始化,因為它會將會這種數組所占的內存全部置0
5.二進制碼補充學習
2 二進制 為10
其實全部顯示為00000000000000000000000000000010,高位為0,表示為正
-2 二進制為11111111111111111111111111111110
其計算方法為:
1.首先是找到正數2的二進制形式00000000000000000000000000000010
2.按位取反->111111111111111111111111111111101
3.加1->11111111111111111111111111111110
將11111111111111111111111111111110變為整數
1.首先判斷其為負數,按位取反->0000000000000000000000000000001
2.加1->00000000000000000000000000000010
3.2步驟后,得結果為2,然后因為是負數,所以加一個符號,得-2
所以補碼的設計目的是:
⑴ 使符號位能與有效值部分一起參加運算,從而簡化運算規則。補碼機器數中的符號位,并不是強加上去的,是數據本身的自然組成部分,可以正常地參與運算。
⑵ 使減法運算轉換為加法運算,進一步簡化計算機中運算器的線路設計。
(3)為了統一正0和負0
有符號數:
最高位是符號位,0表示正,1表示負
反碼表示法規定:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
補碼表示法規定:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。
原碼表示雖然很簡單,用原碼來進行加減運算會出問題,
問題出在帶符號位的負數上
反碼表示,將加減數都表示成反碼后,減法可以直接表示成加法
問題出在(+0)和(-0)上,在人們的計算概念中零是沒有正負之分的,于是就出現了補碼,正數的補碼不變,負數的補碼是將其反碼加1
原碼和反碼中,+0與-0的表示并不相同,所以計算機中一般使用補碼。還有利用高位溢出,將減法運算變成加法運算
模的概念:把一個計量單位稱之為?;蚰怠@纾瑫r鐘是以12進制進行計數循環的,即以12為模。在時鐘上,時針加上(正撥)12的整數位或減去(反撥)12的整數位,時針的位置不變。14點鐘在舍去模12后,成為(下午)2點鐘(14=14-12=2)。從0點出發逆時針撥10格即減去10小時,也可看成從0點出發順時針撥2格(加上2小時),即2點(0-10=-10=-10+12=2)。因此,在模12的前提下,-10可映射為+2。由此可見,對于一個模數為12的循環系統來說,加2和減10的效果是一樣的;因此,在以12為模的系統中,凡是減10的運算都可以用加2來代替,這就把減法問題轉化成加法問題了(注:計算機的硬件結構中只有加法器,所以大部分的運算都必須最終轉換為加法)。10和2對模12而言互為補數。
同理,計算機的運算部件與寄存器都有一定字長的限制(假設字長為8),因此它的運算也是一種模運算。當計數器計滿8位也就是256個數后會產生溢出,又從頭開始計數。產生溢出的量就是計數器的模,顯然,8位二進制數,它的模數為8=256。在計算中,兩個互補的數稱為“補碼”。
a. 采用補碼后,可以方便地將減法運算轉化成加法運算,運算過程得到簡化。正數的補碼即是它所表示的數的真值,而負數的補碼的數值部份卻不是它所表示的數的真值。采用補碼進行運算,所得結果仍為補碼。
b. 與原碼、反碼不同,數值0的補碼只有一個,即 [0]補=00000000B。
c. 若字長為8位,則補碼所表示的范圍為-128~+127;進行補碼運算時,應注意所得結果不應超過補碼所能表示數的范圍。
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 小寫
//轉為2進制
System.out.println("i1:" + Integer.toBinaryString(i1));
//轉為16進制
System.out.println("i1:" + Integer.toHexString(i1));
//轉為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個字節,因為是字符->0-2的16次方-1
char c = 0xffff;
System.out.println("c:" + Integer.toBinaryString(c));
//byte的16進制表示的最大值,因為byte1個字節,-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,應該改為0.2f
// float f4 = 0.2;
float f5 = 0.2f;
//TODO 試圖向一個變量賦值超過自身范圍的數值,編譯器會報錯
//byte b2 = 128;Type mismatch: cannot convert from int to byte
byte b2 = 127;
//TODO 輸出各數據類型的最大值/最小值
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轉為整型的時候,總會截尾
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 靜態導入,這樣就不必每次都敲System.out了
import static java.lang.System.out;

/** *//**
*
*循環標簽-標簽是后面跟有冒號的標識符
*<p>
* 1.java中,標簽起作用的唯一地方是剛好在迭代語句之前:即在標簽和迭代語句之間置入任何語句都不好
* 2.在迭代之前設置標簽的唯一理由是:我們希望在其中嵌套另一個迭代或者一個開關switch;break和continue只能中斷當前循環,與標簽一起使用,則會中斷循環,直到標簽所在地方
* 3.注意:在java中使用標簽的理由就是因為有嵌套迭代的存在,而且想從多層嵌套中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 帶標簽的continue回達到標簽的位置,然后并重新進入緊接在那個標簽后面的循環
if(i == 3)

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

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

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

package com.book.chap2.operator;



/** *//**
*
*移位
*<pre>
* 1.左移<<,按照操作符右側指定的位數將操作符左側的操作數向左移動,低位補0
* 2.“有符號”右移>>,按照操作符右側指定的位數將操作符左側的操作數向右移動;“有符號”操作符>>使用符號擴展:若符號為正,則在高位插入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-->這樣一個負數就變成了正數
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));
}
}

posted on 2013-01-08 16:54
landon 閱讀(1254)
評論(0) 編輯 收藏 所屬分類:
Program 、
Book