java塊
『壹』 在java中什麼是代碼塊
java中有四種代碼塊
1.普通代碼塊:直接在{}中出現的。
2.構造代碼塊:在構造函數的{}中出現的。
3.靜態代碼塊:static{}中出現的。
4.同步代碼塊:多線程中出現。
『貳』 Java中內存分為幾塊
你說的是jvm的內存空間吧。
在方法(代碼塊)中定義一個變數時,java就在棧中為這個變數分配JVM內存空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的JVM內存空間;而在堆中分配的JVM內存由java虛擬機的自動垃圾回收器來管理。
JVM內存區域組成
JVM內存分四種:
1、棧區(stacksegment)—由編譯器自動分配釋放,存放函數的參數值,局部變數的值等,具體方法執行結束之後,系統自動釋放JVM內存資源
2、堆區(heapsegment)—一般由程序員分配釋放,存放由new創建的對象和數組,jvm不定時查看這個對象,如果沒有引用指向這個對象就回收
3、靜態區(datasegment)—存放全局變數,靜態變數和字元串常量,不釋放
4、代碼區(codesegment)—存放程序中方法的二進制代碼,而且是多個對象共享一個代碼空間區域
在方法(代碼塊)中定義一個變數時,java就在棧中為這個變數分配JVM內存空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的JVM內存空間;在堆中分配的JVM內存由java虛擬機的自動垃圾回收器來管理,堆的優勢是可以動態分配JVM內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配JVM內存的。缺點就是要在運行時動態分配JVM內存,存取速度較慢;棧的優勢是存取速度比堆要快,缺點是存在棧中的數據大小與生存期必須是確定的無靈活性。
◆java堆由Perm區和Heap區組成,Heap區則由Old區和New區組成,而New區又分為Eden區,From區,To區,Heap={Old+NEW={Eden,From,To}},見圖1所示。
Heap區分兩大塊,一塊是NEWGeneration,另一塊是OldGeneration.在NewGeneration中,有一個叫Eden的空間,主要是用來存放新生的對象,還有兩個SurvivorSpaces(from,to),它們用來存放每次垃圾回收後存活下來的對象。在OldGeneration中,主要存放應用程序中生命周期長的JVM內存對象,還有個PermanentGeneration,主要用來放JVM自己的反射對象,比如類對象和方法對象等。
在NewGeneration塊中,垃圾回收一般用Copying的演算法,速度快。每次GC的時候,存活下來的對象首先由Eden拷貝到某個SurvivorSpace,當SurvivorSpace空間滿了後,剩下的live對象就被直接拷貝到OldGeneration中去。因此,每次GC後,EdenJVM內存塊會被清空。在OldGeneration塊中,垃圾回收一般用mark-compact的演算法,速度慢些,但減少JVM內存要求.
垃圾回收分多級,0級為全部(Full)的垃圾回收,會回收OLD段中的垃圾;1級或以上為部分垃圾回收,只會回收NEW中的垃圾,JVM內存溢出通常發生於OLD段或Perm段垃圾回收後,仍然無JVM內存空間容納新的Java對象的情況。
JVM調用GC的頻度還是很高的,主要兩種情況下進行垃圾回收:當應用程序線程空閑;另一個是JVM內存堆不足時,會不斷調用GC,若連續回收都解決不了JVM內存堆不足的問題時,就會報outofmemory錯誤。因為這個異常根據系統運行環境決定,所以無法預期它何時出現。
根據GC的機制,程序的運行會引起系統運行環境的變化,增加GC的觸發機會。為了避免這些問題,程序的設計和編寫就應避免垃圾對象的JVM內存佔用和GC的開銷。顯示調用System.GC()只能建議JVM需要在JVM內存中對垃圾對象進行回收,但不是必須馬上回收,一個是並不能解決JVM內存資源耗空的局面,另外也會增加GC的消耗。
◆當一個URL被訪問時,JVM內存區域申請過程如下:
A.JVM會試圖為相關Java對象在Eden中初始化一塊JVM內存區域
B.當Eden空間足夠時,JVM內存申請結束。否則到下一步
C.JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收),釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區
D.Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區
E.當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)
F.完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建JVM內存區域,則出現"outofmemory錯誤"
『叄』 java中什麼是自由塊,什麼是靜態自由塊
自由塊:
{
int i = 0;
}
靜態塊:
static{
int j = 0
}
其中自由塊和靜態塊的區別: 在第一次載入這個類的時候,靜態塊和自由塊都執行,而且先執行靜態塊的內容,第二次載入這個類的時候,只執行自由塊的內容,也就是說靜態塊的內容只執行一次,以後載入都不執行了,你可以看看下面的例子就明白了:
public class StaticTest {
public static void main(String[] args) {
StaticInfo staticInfo1 = new StaticInfo();
staticInfo1.test1();
System.out.println("=======================");
StaticInfo staticInfo2 = new StaticInfo();
staticInfo2.test2();
}
}
class StaticInfo{
{
System.out.println("自由塊");
}
static {
System.out.println("靜態塊");
}
public void test1(){
System.out.println("測試1");
}
public void test2(){
System.out.println("測試2");
}
}
輸出:
靜態塊
自由塊
測試1
=======================
自由塊
測試2
『肆』 java中靜態代碼塊的作用跟用法
Java靜態代碼塊的作用:Java靜態代碼塊中的代碼會在類載入JVM時運行,且只被執行一次,也就是說這些代碼不需要實例化類就能夠被調用。一般情況下,如果有些代碼必須在項目啟動的時候就執行的時候,就需要使用靜態代碼塊。
Java靜態代碼塊的用法:一個類可以使用不包含在任何方法體中的靜態代碼塊,當類被載入時,靜態代碼塊被執行,且只被執行一次,靜態塊常用來執行類屬性的初始化。例如:
static
{
int a=0;
}
『伍』 java中代碼塊被鎖起來後多線程語句一直是一個線程在執行如下方代碼,只有窗口1輸出,求指點
多線程臨界資源肯定不能寫線程內,要另外寫一個類,另外while(Tickets>=0)這里明顯寫成了死循環,所以以上代碼思路完全錯誤
『陸』 Java常見代碼塊的作用與區別
1. 局部代碼塊
作用在方法當中,作用是控制變數的生命周期:
public void show(){
{
System.out.println("局部代碼塊運行!");
}
}123456
在程序中當我們定義完成一個局部變數x之後,並且在接下來的代碼中,不想再用到它時,那麼就沒必要讓x在內存中繼續佔用空間。因此就有了局部代碼塊。
2. 構造代碼塊
作用在類的定義Body中,作用是給類的部分欄位統一初始化:
public class Apple {
private String size;
//構造代碼塊
{
System.out.println("構造代碼塊運行!");
size = "E";
}
}
12345678910
構造代碼塊與構造函數的區別是:構造代碼塊是給所有對象進行統一初始化,而構造函數是給對應的對象初始化,因為構造函數是可以多個的,運行哪個構造函數就會建立什麼樣的對象,但無論建立哪個對象,都會先執行相同的構造代碼塊。也就是說,構造代碼塊中定義的是不同對象共性的初始化內容。所以理所當然的,構造代碼塊在構造函數之前執行。
3. 靜態代碼塊
作用有兩個:
(1)給類的靜態變數賦值;
(2)聲明靜態變數;
作用在類的Body中,對類中的靜態變數初始化:
public class APP {
static int x, y; // 靜態變數
static {
x = 5; // 給靜態變數x賦值
}
public static void myMethod() {
y = x++ + ++x; // x++ 先使用x的值再加1;++x先加1再使用x的值
}
public static void main(String[] args) {
x--;
myMethod();
System.out.println(x + y + ++x);
}
}
輸出:23
『柒』 Java的靜態塊和初始化塊分別何時執行有什麼區別
靜態初始化塊:當類第一次載入時執行。
非靜態初始化塊:非靜態初始化塊會在構造函數執行時,且在構造函數主體代碼執行之前被執行。
區別如下:
1、執行次數不同
靜態塊只執行一次,初始化塊可以執行多次。
2、作用不同
靜態初始化塊僅能初始化類變數,即static修飾的數據成員。
非靜態初始化塊可以初始化類的實例變數。
(7)java塊擴展閱讀:
使用Java靜態代碼塊注意事項:
1、它是隨著類的載入而執行,只執行一次,並優先於主函數。具體說,靜態代碼塊是由類調用的。類調用時,先執行靜態代碼塊,然後才執行主函數的。
2、靜態代碼塊其實就是給類初始化的,而構造代碼塊是給對象初始化的。
3、靜態代碼塊中的變數是局部變數,與普通函數中的局部變數性質沒有區別。
4、一個類中可以有多個靜態代碼塊。
5、對於靜態變數、靜態初始化塊、變數、初始化塊、構造器,它們的初始化順序依次是(靜態變數、靜態初始化塊)>(變數、初始化塊)>構造器。
『捌』 JAVA中 靜態塊的作用
我先說一下靜態塊吧,下面就是一個靜態塊,
static
{
}
靜態塊的特點是在類載入的時候就執行,先說一下類載入,一個程序要想運行,首先要把代碼載入到內存中對吧?然後才能去和CPU交流,這是馮諾依曼計算機規定的。Java也是一樣,Java的.class位元組碼文件要想執行,首先也要載入到內存,由類載入器把位元組碼文件的代碼載入到內存中,這一步就叫類載入,這是首先要進行的。
public
class
Test
{
static
{
System.out.println("我是靜態塊");
}
}
當創建Test類的一個對象的時候,比如new
Test()
,是這樣,首先是類載入,然後才能new對象,靜態塊在類載入的時候就執行了,這就說明靜態塊在new對象之前就會執行,而且一個類在第一次被使用的時候會被載入,然後在整個應用程序的生命周期當中不會再次被載入了,就載入這一次,所以這就說明,靜態塊就執行一次,不會執行第二遍!
public
class
Test
{
public
Test()
{//
構造方法
System.out.println("我是構造方法,創建對象的時候我會執行,我執行完,對象就造出來了");
}
static
{
System.out.println("我是靜態塊,類載入的時候我就執行了,而且只執行這一次");
}
}
然後這樣:
new
Test();
new
Test();
你會發現首先列印出靜態塊的信息,然後才列印出構造方法信息,然後再次new
Test();的時候,只列印出了構造方法的信息,這個例子證明了我上面說的是對的!
這就是靜態塊,我說完了,至於你說的
靜態塊中初始化Map。
初始化這幾個字很難講他的意思,意思包括
把一些內容設為默認狀態、把沒准備的准備好、在什麼什麼之前就怎麼怎麼樣、將變數賦為默認值,等等,這個不能精確的說,只能就事說事,下面就可以說是在靜態塊中初始化Map,
public
class
Test
{
private
static
Map
m;
static
{
m
=
new
HashMap();
}
}
就說道這兒,樓主
看了一個帖子
寫的是初始化Map的,
如果還有疑問
不如把地址貼出來,大家也好幫你,就光說初始化Map,這個問的太叫人沒法回答了。