為什么Java中類方法不能訪問實例方法

? ? ? 我們已經知道類體中的方法分為實例方法和類方法兩種,用static修飾的是類方法。二者有什么區別呢?當一個類創建了一個對象后,這個對象就可以調用該類的方法。


? ? ? ?當類的字節碼文件被加載到內存時,類的實例方法不會被分配入口地址,當該類創建對象后,類中的實例方法才分配入口地址,從而實例方法可以被類創建的任何對象調用執行。需要注意的是,當我們創建第一個對象時,類中的實例方法就分配了入口地址,當再創建對象時,不再分配入口地址,也就是說,方法的入口地址被所有的對象共享,當所有的對象都不存在時,方法的入口地址才被取消。


? ? ? ?對于類中的類方法,在該類被加載到內存時,就分配了相應的入口地址。從而類方法不僅可以被類創建的任何對象調用執行,也可以直接通過類名調用。類方法的入口地址直到程序退出才被取消。

? ? ? 類方法在類的字節碼加載到內存時就分配了入口地址,因此,Java語言允許通過類名直接調用類方法,而實例方法不能通過類名調用。在講述類的時候我們強調過,在Java語言中,類中的類方法不可以操作實例變量,也不可以調用實例方法,這是因為在類創建對象之前,實例成員變量還沒有分配內存,而且實例方法也沒有入口地址。


有時候我們對靜態方法和實例化方法會有一些 誤解
1、大家都以為 ?靜態方法常駐內存,實例方法不是,所以靜態方法效率高但占內存。
? ? ?事實上,他們都是一樣的,在加載時機和占用內存上,靜態方法和實例方法是一樣的,在類型第一次被使用時加載。調用的速度基本上沒有差別。

2、大家都以為“?靜態方法在堆上分配內存,實例方法在堆棧上

? ? ?事實上所有的方法都不可能在堆或者堆棧上分配內存,方法作為代碼是被加載到特殊的代碼內存區域,這個內存區域是不可寫的。

方法占不占用更多內存,和它是不是static沒什么關系。 ??
? ? ?? 因為字段是用來存儲每個實例對象的信息的,所以字段會占有內存,并且因為每個實例對象的狀態都不一致(至少不能認為它們是一致的),所以每個實例對象的所以字段都會在內存中有一分拷貝,也因為這樣你才能用它們來區分你現在操作的是哪個對象。 但方法不一樣,不論有多少個實例對象,它的方法的代碼都是一樣的,所以只要有一份代碼就夠了。因此無論是static還是non-static的方法,都只存在一份代碼,也就是只占用一份內存空間。 ??

同樣的代碼,為什么運行起來表現卻不一樣?這就依賴于方法所用的數據了。主要有兩種數據來源,一種就是通過方法的參數傳進來,另一種就是使用class的成員變量的值……

3、大家都以為 實例方法需要先創建實例才可以調用,比較麻煩,靜態方法不用,比較簡單
? ? ?事實上如果一個方法與他所在類的實例對象無關,那么它就應該是靜態的,而不應該把它寫成實例方法。所以所有的實例方法都與實例有關,既然與實例有關,那么創建實例就是必然的步驟,沒有麻煩簡單一說。
當然你完全可以把所有的實例方法都寫成靜態的,將實例作為參數傳入即可,一般情況下可能不會出什么問題。
從面向對象的角度上來說,在抉擇使用實例化方法或靜態方法時,應該根據是否該方法和實例化對象具有邏輯上的相關性,如果是就應該使用實例化對象? 反之使用靜態方法。這只是從面向對象角度上來說的。
如果從線程安全、性能、兼容性上來看? 也是選用實例化方法為宜。

我們為什么要把方法區分為:靜態方法和實例化方法 ?
? ? ? 如果我們繼續深入研究的話,就要脫離技術談理論了。早期的結構化編程,幾乎所有的方法都是“靜態方法”,引入實例化方法概念是面向對象概念出現以后的事情了,區分靜態方法和實例化方法不能單單從性能上去理解,創建c++,java,c#這樣面向對象語言的大師引入實例化方法一定不是要解決什么性能、內存的問題,而是為了讓開發更加模式化、面向對象化。這樣說的話,靜態方法和實例化方式的區分是為了解決模式的問題。

拿別人一個例子說事:

? ? ? 比如說“人”這個類,每個人都有姓名、年齡、性別、身高等,這些屬性就應該是非靜態的,因為每個人都的這些屬性都不相同;但人在生物學上屬于哪個門哪個綱哪個目等,這個屬性是屬于整個人類,所以就應該是靜態的——它不依賴與某個特定的人,不會有某個人是“脊椎動物門哺乳動物綱靈長目”而某個人卻是“偶蹄目”的。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373981.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373981.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373981.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python展開 c函數中的宏預處理_C中的預處理宏

C中的預處理宏宏定義就屬于預處理命令的一種。那么,什么是宏呢?宏:c語言標準允許在程序中用一個標識符來表示一個字符串。標識符就是宏名。宏替換:宏替換就是宏定義。在編譯預處理中,將程序中所有的宏名用相應的字符串…

(轉) 中斷處理程序中斷服務例程

關于中斷處理程序和中斷服務例程ISR的區別及聯系,之前一直搞混,今天抽時間將兩者關系弄弄清楚。ok,下面進入主題。首先中斷處理程序(Interrupt Handler)和中斷服務例程ISR(Inerrupt Service Routine)是兩個不同的概念.簡單來說就是,一條中斷線…

使用SQL:2003 MERGE語句的奧術魔術

時不時地,由于以下任何原因,我們不得不將INSERT與UPDATE區分開來感到尷尬: 我們必須至少發表兩個聲明 我們必須考慮性能 我們必須考慮比賽條件 我們必須在[UPDATE; 如果UPDATE_COUNT 0 THEN INSERT]和[INSERT; 如果例外然后更新] 我們必…

Swing 學習小記

初學Swing一路問題,一路學習 問題一:JPanel中動態組件添加,刷新問題? 錯誤一:使用repaint()方法,以為可以刷新,可行不通。 錯誤繼續發生:還是使用repaint()方法,與之前不…

leetcode Spiral Matrix

題目連接 https://leetcode.com/problems/spiral-matrix/ Spiral Matrix Description Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. For example, Given the following matrix: [   [ 1, 2, 3 ],   [ 4, 5…

python學生類出不來中文_Python 這類看起來學習門檻低的語言,是否真的適合入門編程學習?...

Python(計算機程序設計語言)Python是一種跨平臺的計算機程序設計語言。 是一個高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。最初被設計用于編寫自動化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越多被用于獨立的、大型項目的開…

克隆可序列化和不可序列化的Java對象

開發人員經常依靠3d方庫來避免重新發明輪子,尤其是在Java世界中,Apache和Spring這樣的項目如此盛行。 在處理這些框架時,我們通常很少或根本無法控制其類的行為。 這有時會導致問題。 例如,如果您想深度克隆不提供合適克隆方法的對…

2014編程之美資格賽

2014 編程之美挑戰賽 --- 資格賽真題 題目1 : 同構 時間限制:2000ms單點時限:1000ms內存限制:256MB描述 給定2個樹A和B,保證A的節點個數>B的節點個數。 現在你需要對樹A的邊進行二染色。 一個好的染色方案,指不存在一個樹A中的連通塊,同時…

JavaScript之面向對象學習六原型模式創建對象的問題,組合使用構造函數模式和原型模式創建對象...

一、仔細分析前面的原型模式創建對象的方法,發現原型模式創建對象,也存在一些問題,如下: 1、它省略了為構造函數傳遞初始化參數這個環節,結果所有實例在默認的情況下都將取得相同的屬性值,這還不是最大的問題! 2、最大的問題是原型…

stand up meeting 12/11/2015

part組員今日工作工作耗時/h明日計劃工作耗時/hUI馮曉云完成單詞釋義熱度排序;允許用戶自主添加釋義;完成了button位置的修正(finally)和彈窗的美化; 6try the backup plan 6PDF Reader朱玉影 完成了pdf文件的打…

ssrf漏洞內網滲透_滲透技巧之SSRF

SSRF——服務端請求偽造,上一篇,我談到了CSRF客戶端請求偽造,這個是我們通過攻擊用戶,引誘客戶點擊我們偽造好的表單,從而達到我們攻擊的目的,是從客戶端發起的,那么SSRF服務端請求偽造當然是通…

引入故意緩存

幾周前,我參加了ThoughtWorks 技術雷達研討會。 我在ThoughtWorks工作了多年,想想是否有人知道這些人在軟件開發方面的發展趨勢。 在技??巧上帶有上升箭頭的數字中,第17位被稱為“周到緩存”。 和斯科特肖一起喝酒時,我問他是什…

(小議)面向對象

什么是面向對象?如果讓我理解,只有一句話:它是一個與面向過程相對的概念,是一種進化或者升級。人們所設計的程序幾乎都是線性思維,即一步一步往下執行。對于一個沒有人機交互的簡單程序來說,這是簡單易行的…

int類型究竟占幾個字節

最近在看深入理解計算機系統這本書,上面提到了在32位機器和64機器中int類型都占用4個字節。后來,查了The C Programming language這本書,里面有一句話是這樣的:Each compiler is free to choose appropriate sizes for its own ha…

python fieldnames_csvreader.fieldnames在python中未被識別為csv reader對象的屬性

我試圖使用CSV模塊在Python中提取CSV文件的標題.CSV文件非常扁平,看起來像:This, That, The Other1, 2, 3我正在做以下事情:>讀入CSV文件并制作閱讀器對象>將讀者的迭代器推到下一行,強制它至少訪問第一行一次(來自csv模塊文檔:“如果在…

Spring Insight – Web應用程序分析

您是否正在使用Spring Framework編寫Web應用程序? 您是否曾經想過引擎蓋下發生了什么? 為什么您的應用程序響應如此緩慢? 在您仍然等待應用程序響應的同時,為什么窗外的蝸牛如此之快地消失在遠處? 您應該:)&#xff0c…

創建動態鏈接庫時設置導出函數的方法

有兩種方法1.使用模塊定義文件, 2.在要導出的函數前加上 __declspec(dllexport) 我們用VS2008新建個DLL工程,工程名為“TestDLL” 把默認的源文件后綴 .CPP改為.C(C文件) int _stdcall MyFunction(int iVariant){return 0; } 1. 使用傳統的模…

javascript的瀏覽器Bom詳解,window、location、history對象

BOM(BrowserObjectModel)也叫瀏覽器對象模型,描述與瀏覽器進行交互的方法和接口。BOM由多個對象組成, 其中代表瀏覽器窗口的Window對象是BOM的頂層對象,其他對象都是該對象的子對象。 JavaScript由三部分組成:ECMAScript,BOM&…

python右斜杠_Python中的左斜杠、右斜杠(正斜杠和反斜杠)

首先,"/"左傾斜是正斜杠,"\"右傾斜是反斜杠,可以記為:除號是正斜杠一般來說對于目錄分隔符,Unix和Web用正斜杠/,Windows用反斜杠,但是現在Windows(一)目錄中的斜杠們python讀文件需要輸入的目錄參…

重用生成的JAXB類

在本文中,我將演示如何利用– XJC擴展來重用以前從XML模式生成的類。 當其他XML架構導入XML架構并且您不想每次都生成相同的類時,這很有用。 導入的架構(Product.xsd) 以下XML模式代表有關產品的基本信息。 產品是此示例域中的常…