程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java的初始化與清理

java的初始化與清理

編輯:關於JAVA

隨著計算機革命的發展,“不安全”的編程方式已逐漸成為編程代價高昂的主因之一。

初始化和清理正是涉及安全的兩個問題。

1.用構造器確保初始化

默認構造器(無參構造器):不接受任何參數的構造器

2.方法重載

1.區分重載方法

每個重載的方法都必須有一個獨一無二的參數類型列表。

參數順序的不同也足以區分兩個方法。不過,一般情況下,別這麼做,因為這會使代碼難以維護。

2.涉及基本類型的重載

基本類型能從一個“較小”的類型自動提升至一個“較大”的類型,此過程一旦牽涉到重載,可能會造成一些混淆。

如果傳入的數據類型(實際參數類型)小於方法中聲明的形式參數類型,實際數據就會被提升。char型略有不同,

如果無法找到恰好接受char參數的方法,就會把char直接提升至int型。

如果傳入的實際參數較大,就得通過類型轉換來執行窄化轉換。如果不這樣做,編譯器就會報錯。

3.以返回值區分重載方法

有時調用方法而忽略其返回值,所以根據返回值區分重載方法是行不通的。、

3.默認構造器

如果類中沒有構造器,則編譯器會自動幫你創建一個默認構造器。但是,如果已經定義了一個構造器(無論是否有參數),編譯器就不會幫你自動創建默認構造器。

4.this關鍵字

this關鍵字只能在方法內部使用,表示對“調用方法的那個對象”的引用。

1.在構造器中調用構造器

在構造器中,如果為this添加了參數列表,那麼就有了不同的含義。這將產生對符合此參數列表的某個構造器的明確調用。

盡管可以用this調用一個構造器,但卻不能調用兩個。此外,必須將構造器調用置於最起始處,否則編譯器會報錯。

2.static的含義

static方法(靜態方法)就是沒有this的方法。可以在沒有創建任何對象的前提下,通過類本身調用static方法。具有全局函數的語義。

在static方法的內部不能調用非靜態方法,但是在非靜態方法中可以調用static方法。

5.清理:終結處理和垃圾回收

Java有垃圾回收器負責回收無用對象占據的內存資源。但也有特殊的情況:假定你的對象(並非使用new)獲得了一塊“特殊”的內存區域,由於垃圾

回收器只知道釋放那些經由new分配的內存,所以它不知道該如何釋放該對象的這塊“特殊”內存。為了應對這種情況,Java允許在類中定義一個名為finalize()的方法。

它的工作原理“假定”是這樣的:一旦垃圾回收器准備好釋放對象占用的存儲空間,將首先調用其finalize()方法,並且在下一次垃圾回收動作發生

時,才會真正回收對象占用的內存。所以要是你打算用finalize(),就能在垃圾回收時刻做一些重要的清理工作。

注意:finalize()與C++中的析構函數不同:在C++中,對象一定會被銷毀(如果程序中沒有缺陷的話),而Java裡的對象卻並非總是被垃圾回收。

換句話說:1.對象可能不被垃圾回收  2.垃圾回收並不等於“析構”

只要程序沒有瀕臨存儲空間用完的那一刻,對象占用的空間就總也得不到釋放。如果程序執行結束,並且垃圾回收器一直都沒有釋放你創建的任何

對象的存儲空間,則隨著程序的退出,那些資源也會全部交還給操作系統。這個策略是恰當的,因為垃圾回收本身也有開銷,要是不使用它,那就不用

支付這部分開銷了。

1.finalize()的用途何在

垃圾回收只與內存有關。使用垃圾回收器的唯一原因是為了回收程序不再使用的內存。所以對於與垃圾回收有關的任何行為來說(尤其是finalize()方法),

它們也必須同內存及其回收有關。

finalize()作用:釋放那些通過某種創建對象以外的方式為對象分配的存儲空間。

之所以要有finalize(),是由於在分配內存時可能采用了類似C語言中的做法,而非Java中通常做法。這種情況主要發生在使用“本地方法”的情況下,本地

方法是一種在Java中調用非Java代碼的方式。本地方法目前只支持C和C++,但C和C++可以調用其他語言寫的代碼,所以實際上可以調用任何代碼。

2.你必須實施清理

要清理一個對象,用戶必須在需要清理的時刻調用執行清理動作的方法。

垃圾回收器的存在並不能完全代替析構函數(而且絕對不能直接調用finalize()),如果希望進行除釋放存儲空間之外的清理工作,還是得明確調用某個

恰當的方法。

記住:無論是“垃圾回收”還是“finalize()”,都不保證一定會發生。如果Java虛擬機(JVM)並未面臨內存耗盡的情形,它是不會浪費時間去執行垃圾回收

以恢復內存的。

3.終結條件

通常,不能指望finalize(),必須創建其他的“清理”方法,並且明確的調用它們。

但是可以用finalize()驗證終結條件。在垃圾回收之前,只要對象存在沒有被適當的清理的部分,finalize()可以最終發現這種情況。

System.gc()用於強制進行終結動作。

4.垃圾回收器是如何工作的

在以前所用過的程序語言中,在堆上分配對象是非常昂貴的,你可能會覺得Java中所有對象都在堆上分配的方式也非常昂貴。然而垃圾回收器對於

提高對象的創建的速度,卻有非常明顯的效果。Java從堆上分配空間的速度,可以和其他語言從堆棧上分配空間的速度相媲美。

在某些Java虛擬機中,堆就像一個傳送帶,每分配一個新對象,它就往前移動一格,對象存儲空間的分配速度非常快。但Java中堆未必完全像傳送帶

那樣工作,要是那樣的話,勢必導致頻繁的內存頁面調度。然而垃圾回收器的介入,當它工作時,將一面回收空間,一面使堆中的對象緊湊排列。

其他系統中的垃圾回收機制:引用計數是一種簡單但速度很慢的垃圾回收技術。(當對象被引用時,引用計數加1,當離開或被置空時,引用計數減1,

當某個對象的引用計數為0時,就釋放其占用的空間)

在一些更快的模式中,垃圾回收器並不基於引用計數技術。它們依靠的思想是:對任何“活”的對象,一定能最終追溯到其存活在堆棧或靜態存儲區中的

引用。因此,如果從堆棧和靜態存儲區開始,遍歷所有的引用,就能找到所有“活”的對象。,沒有找到的對象就被自動回收。

Java虛擬機采用一種只適應的垃圾回收技術。

“停止-復制”:先暫停程序的運行,然後將所有活的對象從當前堆復制到另一個堆,沒有被復制的全部都是垃圾。當對象被復制到新堆時,它們是一個挨一個的,

所以新堆保持緊湊排列。“復制式回收器”效率會降低。原因:1.需要兩個分離的堆,維護比實際多一倍的空間。2。復制問題,程序進入穩定狀態後,可能只會產生

少量的垃圾,甚至沒有垃圾。復制式回收器仍然會將所有內存自一處復制到另一處,這很浪費。為了避免這種情況,一些Java虛擬機會進行檢查:要是沒有新垃圾

產生就轉換到另一種工作模式--“標記-清掃”。

“標記-清掃”:思路是從堆棧和靜態存儲區出發,遍歷所有的引用,進而找出所有存活的對象,然後設一個標記,全部標記工作完成,開始清理沒有標記的對象。

不會發生任何復制動作,所以剩下的堆空間是不連續的,垃圾回收器要是希望得到連續的空間,就得重新整理剩下的對象。

垃圾回收器根據不同的情況,調用不同的垃圾回收模式,這將是“自適應”技術。“自適應的、分代的、停止-復制、標記-清掃”式垃圾回收器。

6.成員初始化

Java盡力保證:所有變量在使用前都能得到恰當的初始化。對於方法的局部變量,Java以編譯時錯誤的形式來貫徹這種保證。

如果類的數據成員是基本類型,都會有一個默認的初始值。

1.指定初始化

如果想給某個變量賦初值,就直接的方法是,在定義時直接賦值。

也可以調用某個方法來提供初始值。

7.構造器初始化

可以用構造器來進行初始化,但是:無法阻止自動初始化的進行,它將在構造器被調用之前發生。

1.初始化順序

在類的內部,變量定義的先後順序決定了初始化的順序。即使變量定義散布於方法定義之間,它們仍舊會在任何方法(包括構造器)被調用之前得到初始化。

2.靜態數據的初始化

無論創建多少個對象,靜態數據都只占用一份存儲區域。

靜態初始化只有在必要的時刻才會進行。

3.顯式的靜態初始化

Java允許將多個靜態初始化動作組織成一個特殊的“靜態子句”(靜態塊)

static int i;  
static
{  
     
    i=45;  
     
}  
4.非靜態實例初始化  
int a;  
int b;  
{  
     
    a = 1;  
     
    b = 2;  
     
}

查看本欄目

與靜態初始化子句一模一樣,只不過少了static關鍵字。8.數組的初始化

數組只是相同類型的,用一個標識符名稱封裝到一起的一個對象序列或基本類型數據序列。

數組是通過方括號下標操作符[]來定義和使用的。

int[] arrInt = {1,2,3,4,5}; 或 int arrInt[];

arrInt.length:獲得數組內包含了多少個元素

Arrays.toString():屬於java.util標准庫,它將產生一維數組的可打印版本。

1.可變參數列表

public void printArray(Object[] args);

public void method(int... arrInt);9.枚舉類型

enum關鍵字,它使得我們在需要群組並使用枚舉類型集時,可以方便地處理。

public enum Spiciness  
{  
NOT,MILD,MEDIUM,HOT,FLAMING  
}  
Spiciness howHot = Spiciness.Hot;

在創建enum時,編譯器會自動添加一些有用的特性:

1.toString()方法2.ordinal()方法:用來顯示某個特定enum常量的聲明順序3.static values()方法:用來按照enum常量的聲明順序,產生由這些常量值構成的數組。enum有一個特別實用的特性,即它可以在switch語句內實用

Spiciness degree;  
switch(degree)  
{  
     
    case NOT:  
     
         break;  
     
    case MILD:  
     
        break;  
     
    case MEDIUM:  
     
        break;  
     
    case HOT:  
     
        break;  
     
    case FLAMING:  
     
        break;  
     
    default:   
     
        break;  
     
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved