JAVA構(gòu)造器是否為靜態(tài)方法你知道嗎
在thinking in java中,第96頁提到,“即使沒有顯示地使用static關(guān)鍵字,構(gòu)造器實際上也是靜態(tài)方法“,對此我產(chǎn)生了疑惑,于是找相關(guān)資料進行確認,在一篇大神的博客中得到了答案,那就是構(gòu)造器不是靜態(tài)方法。
主要是以下幾點原因:
Java虛擬機規(guī)范第二版中定義了四種不同的字節(jié)碼指令來處理Java程序中不同種類的方法的調(diào)用:
- invokestatic - 用于調(diào)用類(靜態(tài))方法
- invokespecial - 用于調(diào)用實例方法,特化于super方法調(diào)用、private方法調(diào)用與構(gòu)造器調(diào)用
- invokevirtual - 用于調(diào)用一般實例方法(包括聲明為final但不為private的實例方法)
- invokeinterface - 用于調(diào)用接口方法
其中,invokestatic與invokespecial調(diào)用的目標(biāo)必然是可以靜態(tài)綁定的(比如不被繼承),因為它們都無法參與子類型多態(tài);invokevirtual與invokeinterface的則一般需要做運行時綁定,JVM實現(xiàn)可以有選擇的根據(jù)final或?qū)嶋H運行時類層次或類型反饋等信息試圖進行靜態(tài)綁定。
那么Java中的實例構(gòu)造器是不是“靜態(tài)方法”呢?從Java語言規(guī)范中給出的“靜態(tài)方法”的定義來看,答案是“否”——首先從Java語言規(guī)范對“方法”的定義來說,構(gòu)造器根本不是“方法”;其次,實例構(gòu)造器有一個隱式參數(shù),“this”,在實例構(gòu)造器中可以訪問“this”,可以通過“this”訪問到正在初始化的對象實例的所有實例成員。
實例構(gòu)造器無法被隱藏或覆寫,不參與多態(tài),因而可以做靜態(tài)綁定。從這個意義上可以認為實例構(gòu)造器是“靜態(tài)”的,但這種用法與Java語言定義的“靜態(tài)方法”是兩碼事。
另外需要注意的是,Java語言中,實例構(gòu)造器只能在new表達式(或別的構(gòu)造器)中被調(diào)用,不能通過方法調(diào)用表達式來調(diào)用。new表達式作為一個整體保證了對象的創(chuàng)建與初始化是打包在一起進行的,不能分開進行;但實例構(gòu)造器只負責(zé)對象初始化的部分,“創(chuàng)建對象”的部分是由new表達式本身保證的。
這個例子的注意點在于:
1、Java的實例構(gòu)造器只負責(zé)初始化,不負責(zé)創(chuàng)建對象;Java虛擬機的字節(jié)碼指令的設(shè)計也反映了這一點,有一個new指令專門用于創(chuàng)建對象實例,而調(diào)用實例構(gòu)造器則使用invokespecial指令。
2、“this”是作為實例構(gòu)造器的第一個實際參數(shù)傳入的。
靜態(tài)方法中不能使用this,而構(gòu)造器中可以使用this關(guān)鍵字。this是指調(diào)用當(dāng)前方法的對象,而靜態(tài)方法不屬于任何對象。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java中Set與List的關(guān)系與區(qū)別介紹
這篇文章主要介紹了Java中Set與List的關(guān)系與區(qū)別介紹,本文總結(jié)它們兩個接口都是繼承自Collection、它們之間的存儲方式不一樣,需要的朋友可以參考下2015-03-03Springboot實現(xiàn)自定義錯誤頁面的方法(錯誤處理機制)
這篇文章主要介紹了Springboot實現(xiàn)自定義錯誤頁面的方法(錯誤處理機制),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01Java線程的start方法回調(diào)run方法的操作技巧
面試過程中經(jīng)常會被面試官問到為什么我們調(diào)用start()方法時會執(zhí)行run()方法,為什么不能直接調(diào)用run()方法,問的一頭霧水,今天小編給大家介紹下Java線程的start方法回調(diào)run方法的操作技巧,需要的朋友參考下吧2017-11-11