JAVA關鍵字自測

1,final,finally,finalize。html

final用於修飾類、成員變量和成員方法。java

final修飾的類,不能被繼承(String、StringBuilder、StringBuffer、Math,不可變類),其中全部的方法都不能被重寫,因此不能同時用abstract和final修飾類(abstract修飾的類是抽象類,抽象類是用於被子類繼承的,和final起相反的做用);程序員

Final修飾的方法不能被重寫,可是子類能夠用父類中final修飾的方法;編程

Final修飾的成員變量是不可變的,若是成員變量是基本數據類型,初始化以後成員變量的值不能被改變,若是成員變量是引用類型,那麼它只能指向初始化時指向的那個對象,不能再指向別的對象,可是對象當中的內容是容許改變的。使用final關鍵字修飾一個變量時,是引用不能變,不是引用的對象不能變數組

finally和try catch 搭配使用,用於處理異常。throws, throw, try, catch, finally分別表明什麼意義?緩存

try塊表示程序正常的業務執行代碼。若是程序在執行try塊的代碼時出現了「非預期」狀況,JVM將會生成一個異常對象,這個異常對象將會被後面相應的catch塊捕獲。安全

catch塊表示一個異常捕獲塊。當程序執行try塊引起異常時,這個異常對象將會被後面相應的catch塊捕獲。網絡

throw用於手動地拋出異常對象。throw後面須要一個異常對象。併發

throws用於在方法簽名中聲明拋出一個或多個異常類,throws關鍵字後能夠緊跟一個或多個異常類。框架

finally塊表明異常處理流程中總會執行的代碼塊。

對於一個完整的異常處理流程而言,try塊是必須的,try塊後能夠緊跟一個或多個catch塊,最後還能夠帶一個finally塊。try塊中能夠拋出異常。

finalize是object類中的一個方法,子類能夠重寫finalize()方法實現對資源的回收。

finalize在什麼狀況下被調用?有三種狀況1.全部對象被Garbage Collection時自動調用,好比運行System.gc()的時候.2.程序退出時爲每一個對象調用一次finalize方法。3.顯式的調用finalize方法
除此之外,正常狀況下,當某個對象被系統收集爲無用信息的時候,finalize()將被自動調用,可是jvm不保證finalize()必定被調用,也就是說,finalize()的調用是不肯定的,這也就是爲何sun不提倡使用finalize()的緣由。

構造函數的一個重要做用是爲對象申請資源,相應地,析構函數要負責釋放這些資源。GC原本就是內存回收了,應用還須要在finalization作什麼呢? 答案是大部分時候,什麼都不用作(也就是不須要重載)。只有在某些很特殊的狀況下,好比你調用了一些native的方法(通常是C寫的),能夠要在finaliztion裏去調用C的釋放函數。

2,static,靜態修飾符,

static方法的做用:「static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是能夠的。並且能夠在沒有建立任何對象的前提下,僅僅經過類自己來調用static方法。這實際上正是static方法的主要用途。簡而言之,在沒有建立對象的狀況下能夠調用方法和變量。

static方法通常稱做靜態方法,因爲靜態方法不依賴於任何對象就能夠進行訪問,所以對於靜態方法來講,是沒有this的,由於它不依附於任何對象,既然都沒有對象,就談不上this了。而且因爲這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,由於非靜態成員方法/變量都是必須依賴具體的對象纔可以被調用。可是要注意的是,雖然在靜態方法中不能訪問非靜態成員方法和非靜態成員變量,可是在非靜態成員方法中是能夠訪問靜態成員方法/變量的。

咱們最多見的static方法就是main方法,至於爲何main方法必須是static的,如今就很清楚了。由於程序在執行main方法的時候沒有建立任何對象,所以只有經過類名來訪問。另外記住,即便沒有顯示地聲明爲static,類的構造器實際上也是靜態方法。

static變量也稱做靜態變量,靜態變量和非靜態變量的區別是:靜態變量被全部的對象所共享,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化。而非靜態變量是對象所擁有的,在建立對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。static成員變量的初始化順序按照定義的順序進行初始化。

static關鍵字還有一個比較關鍵的做用就是 用來造成靜態代碼塊以優化程序性能。static塊能夠置於類中的任何地方,類中能夠有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每一個static塊,而且只會執行一次。爲何說static塊能夠用來優化程序性能,是由於它的特性:只會在類加載的時候執行一次。

與C/C++中的static不一樣,Java中的static關鍵字不會影響到變量或者方法的做用域。在Java中可以影響到訪問權限的只有private、public、protected(包括包訪問權限)這幾個關鍵字

靜態成員變量雖然獨立於對象,可是不表明不能夠經過對象去訪問,全部的靜態方法和靜態變量均可以經過對象訪問(只要訪問權限足夠)

在C/C++中static是能夠做用域局部變量的,可是在Java中切記:static是不容許用來修飾局部變量。不要問爲何,這是Java語法的規定。

帶有static代碼塊的繼承關係類的代碼的執行順序,main方法入口,先執行父類的靜態代碼塊,後執行子類靜態代碼塊,最後執行子類的普通方法

具體參考http://www.cnblogs.com/dolphin0520/p/3799052.html

靜態類和非靜態類的區別,static修飾,可否直接使用類名進行調用

Java中是否能夠覆蓋(override)一個private或者是static的方法?

若是在父類中修飾了一個private的方法,子類繼承以後,對子類也是不可見的。那麼若是子類聲明瞭一個跟父類中定義爲private同樣的方法,那麼編譯器只看成是你子類本身新增的方法,並不能算是繼承過來的。

Static表示靜態的意思,可用於修飾成員變量和成員函數,被靜態修飾的成員函數只能訪問靜態成員,不能夠訪問非靜態成員。靜態是隨着類的加載而加載的,所以能夠直接用類進行訪問。
重寫是子類中的方法和子類繼承的父類中的方法同樣(函數名,參數,參數類型,反回值類型),可是子類中的訪問權限要不低於父類中的訪問權限。重寫的前提是必需要繼承,private修飾不支持繼承,所以被私有的方法不能夠被重寫。
靜態方法形式上能夠被重寫,即子類中能夠重寫父類中靜態的方法。可是實際上從內存的角度上靜態方法不能夠被重寫。

main() 方法爲何必須是靜態的?能不能聲明 main() 方法爲非靜態?

由於程序在執行main方法的時候沒有建立任何對象,所以只有經過類名來訪問,不能

是否能夠從一個靜態(static)方法內部發出對非靜態(non-static)方法的調用?

不能,

靜態變量和靜態代碼塊何時加載?

當類加載器將類加載到JVM中的時候就會建立靜態變量,這跟對象是否建立無關。靜態變量加載的時候就會分配內存空間

靜態代碼塊的代碼只會在類第一次初始化的時候執行一次。

三、java修飾符:public、protected、default、private

修飾範圍從對象類,包,子包,其餘包逐漸減小

四、volatile是Java提供的一種輕量級的同步機制,在併發編程中,它也扮演着比較重要的角色。同synchronized相比(synchronized一般稱爲重量級鎖),volatile更輕量級,相比使用synchronized所帶來的龐大開銷。

所謂可見性,是指當一條線程修改了共享變量的值,新值對於其餘線程來講是能夠當即得知的。

volatile並不能徹底替代synchronized,它依然是個輕量級鎖,在不少場景下,volatile並不能勝任

num++不是個原子性的操做,而是個複合操做

禁止指令重排序優化

volatile有什麼實踐應用?一種實踐是用 volatile 修飾 long 和 double 變量,使其能按原子類型來讀寫。double 和 long 都是64位寬,所以對這兩種類型的讀是分爲兩部分的,第一次讀取第一個 32 位,而後再讀剩下的 32 位,這個過程不是原子的,但 Java 中 volatile 型的 long 或 double 變量的讀寫是原子的。

volatile 修復符的另外一個做用是提供內存屏障(memory barrier),例如在分佈式框架中的應用。簡單的說,就是當你寫一個 volatile 變量以前,Java 內存模型會插入一個寫屏障(write barrier),讀一個 volatile 變量以前,會插入一個讀屏障(read barrier)。意思就是說,在你寫一個 volatile 域時,能保證任何線程都能看到你寫的值,同時,在寫以前,也能保證任何數值的更新對全部線程是可見的,由於內存屏障會將其餘全部寫的值更新到緩存

volatile 變量是什麼?volatile 變量和 atomic 變量有什麼不一樣

volatile 變量和 atomic 變量看起來很像,但功能卻不同。Volatile變量能夠確保先行關係,即寫操做會發生在後續的讀操做以前, 但它並不能保證原子性。例如用volatile修飾count變量那麼 count++ 操做就不是原子性的。而AtomicInteger類提供的atomic方法可讓這種操做具備原子性如getAndIncrement()方法會原子性的進行增量操做把當前值加一,其它數據類型和引用變量也能夠進行類似操做。

volatile 類型變量能使得一個非原子操做變成原子操做嗎

一個典型的例子是在類中有一個 long 類型的成員變量。若是你知道該成員變量會被多個線程訪問,如計數器、價格等,你最好是將其設置爲 volatile。爲何?由於 Java 中讀取 long 類型變量不是原子的,須要分紅兩步,若是一個線程正在修改該 long 變量的值,另外一個線程可能只能看到該值的一半(前 32 位)。可是對一個 volatile 型的 long 或 double 變量的讀寫是原子。

能建立 volatile 數組嗎?

能,Java 中能夠建立 volatile 類型數組,不過只是一個指向數組的引用,而不是整個數組。個人意思是,若是改變引用指向的數組,將會受到 volatile 的保護,可是若是多個線程同時改變數組的元素,volatile 標示符就不能起到以前的保護做用了。

volatile修飾的變量若是是對象或數組之類的,其含義是對象獲數組的地址具備可見性,可是數組或對象內部的成員改變不具有可見性:

五、transient變量有什麼特色

https://www.cnblogs.com/lanxuezaipiao/p/3369962.html

什麼是序列化?

序列化 (Serialization)將對象的狀態信息轉換爲能夠存儲或傳輸的形式的過程。在序列化期間,對象將其當前狀態寫入到臨時或持久性存儲區。之後,能夠經過從存儲區中讀取或反序列化對象的狀態,從新建立該對象

爲何要實現序列化?

序列化是爲了解決在對對象流進行讀寫操做時所引起的問題。序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化

如何實現序列化?

將須要被序列化的類實現Serializable接口,該接口沒有須要實現的方法,implements Serializable只是爲了標註該對象是可被序列化的。而後使用一個輸出流(如:FileOutputStream)來構造一個 ObjectOutputStream(對象流)對象。接着,使用ObjectOutputStream對象的writeObject(Object obj)方法,就能夠將參數爲obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。

何時實現類的序列化

能夠在程序再次運行時讀取這些對象的值,或者在其餘程序中利用這些保存下來的對象。這種狀況下就要用到對象的序列化。 對象序列化的最主要的用處就是在傳遞,和保存對象(object)的時候,保證對象的完整性和可傳遞性。 譬如經過網絡傳輸,或者把一個對象保存成一個文件的時候,要實現序列化接口 。

      咱們都知道一個對象只要實現了Serilizable接口,這個對象就能夠被序列化,java的這種序列化模式爲開發者提供了不少便利,咱們能夠沒必要關係具體序列化的過程,只要這個類實現了Serilizable接口,這個類的全部屬性和方法都會自動序列化。

      然而在實際開發過程當中,咱們經常會遇到這樣的問題,這個類的有些屬性須要序列化,而其餘屬性不須要被序列化,打個比方,若是一個用戶有一些敏感信息(如密碼,銀行卡號等),爲了安全起見,不但願在網絡操做(主要涉及到序列化操做,本地序列化緩存也適用)中被傳輸,這些信息對應的變量就能夠加上transient關鍵字。換句話說,這個字段的生命週期僅存於調用者的內存中而不會寫到磁盤裏持久化。

      總之,java 的transient關鍵字爲咱們提供了便利,你只須要實現Serilizable接口,將不須要序列化的屬性前添加關鍵字transient,序列化對象的時候,這個屬性就不會序列化到指定的目的地中。

六、this和super關鍵字

super主要存在於子類方法中,用於指向子類對象中父類對象,用於訪問父類的構造函數,方法,變量。

this和super很像,this指向的是當前對象的調用,super指向的是當前調用對象的父類。類加載完畢,建立對象,父類的構造方法會被調用(默認自動無參),而後執行子類相應構造建立了一個子類對象,該子類對象還包含了一個父類對象。該父類對象在子類對象內部。this super只能在有對象的前提下使用,不能在靜態上下文使用

super的使用:super();第一行隱式語句

super(y);調用父類構造函數;

Java關鍵字this只能用於方法方法體內。當一個對象建立後,Java虛擬機(JVM)就會給這個對象分配一個引用自身的指針,這個指針的名字就是this。所以,this只能在類中的非靜態方法中使用,靜態方法和靜態的代碼塊中絕對不能出現this

 第1、經過this調用另外一個構造方法,用發是this(參數列表),這個僅僅在類的構造方法中,別的地方不能這麼用。
 第2、函數參數或者函數中的局部變量和成員變量同名的狀況下,成員變量被屏蔽,此時要訪問成員變量則須要用「this.成員變量名」的方式來引用成員變量。固然,在沒有同名的狀況下,能夠直接用成員變量的名字,而不用this,用了也不爲錯,呵呵。
 第3、在函數中,須要引用該函所屬類的當前對象時候,直接用this。

七、public static void 寫成 static public void會怎樣?

main函數寫成這樣能出結果和原來同樣

八、說明一下public static void main(String args[])這段聲明裏每一個關鍵字的做用

 public關鍵字聲明主函數爲public就是告訴其餘的類能夠訪問這個函數。

static關鍵字,告知編譯器main函數是一個靜態函數。也就是說main函數中的代碼是存儲在靜態存儲區的,即當定義了類之後這段代碼就已經存在了。若是main()方法沒有使用static修飾符,那麼編譯不會出錯,可是若是你試圖執行該程序將會報錯,提示main()方法不存在。由於包含main()的類並無實例化(即沒有這個類的對象),因此其main()方法也不會存。而使用static修飾符則表示該方法是靜態的,不須要實例化便可使用。

void關鍵字代表main()的返回值是無類型。

String是命令行傳進參數的類型,args是指命令行傳進的字符串數組。

九、sizeof 是Java 的關鍵字嗎?

不是,Java是一種純面向對象的編程語言,它將內存管理的細節都交給Java Virtual Machine(JVM)進行。同時Java是一種跨平臺的語言,可移植性好,它在數據類型在機器中的大小都相同。而在C/C++中須要sizeof是由於移植,不一樣的數據類型在不一樣的機器上大小可能不一樣,程序員必須知道對應的數據類型大小。

十、switch

switch後面的表達式類型,支持枚舉類型,java 1.6(包括)之前,只是支持等價成int 基本類型的數據:byte ,short,char,int(其餘的都不能夠)。1.7加入的新特性能夠支持String類型的數據。long是不能夠的。就算是經過強制的轉化也必須是轉成int。

相關文章
相關標籤/搜索