Java基礎6——深入理解五種型別的程式碼塊與程式碼載入順序
阿新 • • 發佈:2019-01-09
程式碼塊與程式碼載入順序
程式碼塊
public class Test {
{
////
}
}
這種形式的程式段我們將其稱之為程式碼塊,所謂程式碼塊就是用大括號({ })將多行程式碼封裝在一起,形成一個獨立的資料體,用於實現特定的演算法。一般來說程式碼塊是不能單獨執行的,它必須要有執行主體。在Java中程式碼塊主要分為一下幾種:
1.普通程式碼塊
普通程式碼塊是我們用得最多的也是最普遍的,它就是在方法名後面用{ }括起來的程式碼段。普通程式碼塊是不能夠單獨存在的,它必須要緊跟在方法名後面。同時也必須要使用方法名呼叫它。
public class Test {
public void test(){
System.out.println("普通程式碼塊");
}
}
2.靜態程式碼塊
想到靜態我們就會想到static,靜態程式碼塊就是用static修飾的用{ }括起來的程式碼段,它的主要目的就是對靜態屬性進行初始化。
public class Test {
static{
System.out.println("靜態程式碼塊");
}
}
3.同步程式碼塊
使用 synchronized 關鍵字修飾,並使用“{ }”括起來的程式碼片段,它表示同一時間只能有一個執行緒進入到該方法塊中
4.構造程式碼塊
在類中直接定義沒有任何修飾符、字首、字尾的程式碼塊即為構造程式碼塊。我們明白一個類必須至少有一個建構函式,建構函式在生成物件時被呼叫。構造程式碼塊和建構函式一樣同樣是在生成一個物件時被呼叫,那麼構造程式碼在什麼時候被呼叫?如何呼叫的呢?看如下程式碼:
public class Test {
/**
* 構造程式碼
*/
{
System.out.println("執行構造程式碼塊...");
}
/**
* 無參建構函式
*/
public Test(){
System.out.println("執行無參建構函式...");
}
/**
* 有參建構函式
* @param id id
*/
public Test(String id){
System.out.println("執行有參建構函式...");
}
}
new一個物件的時候總是先執行構造程式碼,再執行建構函式,但是有一點需要注意構造程式碼不是在建構函式之前執行的,它是依託建構函式執行的。正是由於構造程式碼塊有這幾個特性。
如果一個類中存在若干個建構函式,這些建構函式都需要對例項變數進行初始化,如果我們直接在建構函式中例項化,必定會產生很多重複程式碼,繁瑣和可讀性差。這裡我們可以充分利用構造程式碼塊來實現。這是利用編譯器會將構造程式碼塊新增到每個建構函式中的特性。
public class A {
int i = 1;
int initValue;//成員變數的初始化交給程式碼塊來完成
{
//程式碼塊的作用體現於此:在呼叫構造方法之前,用某段程式碼對成員變數進行初始化。
//而不是在構造方法呼叫時再進行。一般用於將構造方法的相同部分提取出來。
//
for (int i = 0;i < 100;i ++) {
initValue += i;
}
}
{
System.out.println(initValue);//4950
System.out.println(i);//此時會列印i=1
int i = 2;//程式碼塊裡的變數和成員變數不衝突,但會優先使用程式碼塊的變數
System.out.println(i);//此時列印i=2
//System.out.println(j);//提示非法向後引用,因為此時j的的初始化還沒開始。
//
}
{
System.out.println("程式碼塊執行");//程式碼塊執行
}
int j = 2;
{
System.out.println(j);//j=2
System.out.println(i);//i=1 程式碼塊中的變數執行後自動釋放,不會影響程式碼塊之外的程式碼
}
A(){
System.out.println("構造方法執行");//構造方法執行
}
}
5.區域性程式碼塊(補充)
位置:區域性位置(方法內部)
作用:限定變數的生命週期,儘早釋放,節約記憶體
呼叫:呼叫其所在的方法時執行
public class 區域性程式碼塊 {
@Test
public void test (){
B b = new B();
b.go();
}
}
class B {
B(){}
public void go() {
//方法中的區域性程式碼塊,一般進行一次性地呼叫,呼叫完立刻釋放空間,避免在接下來的呼叫過程中佔用棧空間
//因為棧空間記憶體是有限的,方法呼叫可能會會生成很多區域性變數導致棧記憶體不足。
//使用區域性程式碼塊可以避免這樣的情況發生。
{
int i = 1;
ArrayList<Integer> list = new ArrayList<>();
while (i < 1000) {
list.add(i ++);
}
for (Integer j : list) {
System.out.println(j);
}
System.out.println("gogogo");
}
System.out.println("hello");
}
}
---------------------
作者:How 2 Play Life
來源:CSDN
原文:https://blog.csdn.net/a724888/article/details/80069472
版權宣告:本文為博主原創文章,轉載請附上博文連結!
程式碼塊載入順序
- 靜態程式碼塊,它是隨著類的載入而被執行,只要類被載入了就會執行,而且只會載入一次,主要用於給類進行初始化。
- 構造程式碼塊,每建立一個物件時就會執行一次,且優先於建構函式,主要用於初始化不同物件共性的初始化內容和初始化例項環境。
- 建構函式,每建立一個物件時就會執行一次。同時建構函式是給特定物件進行初始化,而構造程式碼是給所有物件進行初始化,作用區域不同。
通過上面的分析,他們三者的執行順序應該為:靜態程式碼塊 > 構造程式碼塊 > 建構函式。
public class 靜態程式碼塊 {
@Test
public void test() {
C c1 = new C();
C c2 = new C();
//結果,靜態程式碼塊只會呼叫一次,類的所有物件共享該程式碼塊
//一般用於類的全域性資訊初始化
//靜態程式碼塊呼叫
//程式碼塊呼叫
//構造方法呼叫
//程式碼塊呼叫
//構造方法呼叫
}
}
class C{
C(){
System.out.println("構造方法呼叫");
}
{
System.out.println("程式碼塊呼叫");
}
static {
System.out.println("靜態程式碼塊呼叫");
}
}
---------------------
作者:How 2 Play Life
來源:CSDN
原文:https://blog.csdn.net/a724888/article/details/80069472
版權宣告:本文為博主原創文章,轉載請附上博文連結!