[轉載] Java是不是面向對象的程序

參考鏈接: 為什么Java不是純粹的面向對象語言

轉載自:https://blog.csdn.net/a21700790yan/article/details/80129053?

?

??

? Java——是否確實的 “純面向對象”?讓我們深入到Java的世界,試圖來證實它。

? 在我剛開始學習 Java 的前面幾年,我從書本里知道了 Java 是遵循 “面向對象編程范式(Object Oriented Programming paradigm)”的。在Java世界內一切都是對象,甚至包括字符串(String)這些都是對象(在 C 語言中,字符串是字符數組),那時候,我認為 Java是一種面向對象的語言。

? 但是在后來,我在互聯網站上陸續看到不少開發者說 “Java實際上不是純粹的面向對象,因為并不是所有的東西在 Java 世界都是一個對象”。他們很多的論點都可以概括為以下兩點:

? 所有的靜態內容( static 關鍵修飾的變量和方法)不屬于任何對象,所以這些是非對象的東西。所有基本類型(char,boolean,byte,short,int,long,float,double)都不是對象,因為我們不能做類似正常對象的所具有的操作(例如:使用“.”來訪問對象的屬性和方法)。

? 在那時,由于個人知識經驗儲備有限,我又很容地相信上面的論點,并且也開始認為 “Java 不是純粹的面向對象編程語言”。

? 到了更后來,在我的一次JVM學習過程中,我有了新的發現:

? JVM 在創建對象的時候,實際上會創建兩個對象:

? 一個是實例對象。另一個是Class 對象。該 Class 對象在JVM內僅僅會裝載一次,該類的靜態方法和靜態屬性也一同裝載,JVM使用該 Class 對象來創建具體的實例對象(如上面的對象)。

? 例如,在下面的 Java 語句中,將有兩個對象被創建:

? Employee emp = new Employee();

? ?1

? 一個是實例對象 emp ;另一個則是 Class對象,我們可以通過 Employee.class 引用到它;這個 Class 對象擁有所有的這個類定義的靜態變量和靜態方法,同時,如果我們訪問 通過 emp 對象來訪問靜態內容,會發現它其實指向的對象就是 Employee.class 。

? 這也揭開了另一個迷:為什么靜態內容在一個對象中(不管是emp還是emp2)改變了,在另一個對象中也同時改變,因為這兩個對象改變的都是在 Employee.class 同一個對象里面的內容。

? 現在,上面說到的第一個論點我們要取消了。因為,靜態內容確實被證實屬于一個對象。

? 但是我們還要確認第二個論點:正如早前提到的,原始類型在Java中不是對象,它們無法做類似對象的操作。為了解決這個問題,Java 官方為每一個原始類型推出了對應的包裝類(比如:Integer 對應 int,Long 對應 long,Character 對應 char),所以,其實現在我們可以為原始類型創建一個包裝對象,同時對它們做對象相關的操作。并且,由于自動拆裝箱,我們可以把一個原始類型值賦值給它對應的包裝類的引用。但是我們仍然不能對這些原始類型做對象的操作——我們需要創建對應包裝類的對象。

? 例如:

? Integer obj = new Integer(5); // here we can do i.toString();

int i = 5; // but we can't do i.toString() here

? ?12

? 到目前為止,從一個最終用戶的角度上來看的,我們可以確認 “原始類別不是對象”。( Java開發人員是Java的最終用戶,因為我們正在使用它,而不是創造它 )。

? 如果站在JVM的視角,會有新的發現:

? 其實,在JVM看來它把所有的 “原始類型” 都是當作對象處理” ,要證明這一點可以通過 Class類的源代碼 或者 Javadoc中Class類的說明。

? 根據 java.lang.Class 類的源代碼,該類的注釋是:

? Java官方描述:

? Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

? ?1

? 參考譯文:

? Class類的實例表示正在運行的Java應用程序的類和接口。像枚舉是一種類和注解則是一種接口。每個數組也屬于被反射作為由具有相同的元素類型和尺寸的數目的所有陣列共享一類對象的類。原始的Java類型(boolean, byte, char, short, int, long, float, and double)和關鍵字void也表示為Class對象。

? ?1

? 同時也根據Javadoc中對Class.isPrimitive()方法的定義,來判斷

? Java官方描述:

? public boolean isPrimitive()

Determines if the specified Class object represents a primitive type.

There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as t he primitive types that they represent, namely boolean,byte, char, short, int, long, float, and double.

These objects may only be accessed via the following public static final variables, and are the only Class objects for which this method returns true.

Returns:

true if and only if this class represents a primitive type

Since:

JDK1.1

? ?12345678

? 參考翻譯:

? public boolean isPrimitive()

判斷指定的Class對象是否代表一個基本類型。

一共有9種設定好的Class對象來表示對應的基本類型和void關鍵字。這些對象都是由JVM創建的。…

return

當且僅當該類表示一個真正的基本類型

? ?12345

? 以上都說明,在JVM內部,其實原始類型就是對象。

? 當你打開 Javadoc 對 Class 類的定義中,通過 “CTRL+F ” 查找關鍵字 “primitive”, 將會發現證據在表面 “在JVM里,它把基本類型當作對象來處理的”。

? 我們可以再來看一個例子: Integer.TYPE,在這部分文檔清晰記錄著:

? Java官方描述:

? public static final Class<Integer> TYPE

The Class instance representing the primitive type int.

? ?12

? 以上都說明,在JVM內部,其實原始類型就是對象。

? 那么,既然說 “JVM”會為所有的基本類型創建一個對象,那我們為什么還那么常用 “原始類型”, 而不是直接使用對應的包裝類對象呢?

? 這是因為,為 “原始類型” 創建的對象,在JVM內部是很輕量級的,相對與我們直接創建的對應包裝類對象做了許多優化; 也正因為輕量的緣故,這些原始類的功能就比較少(例如我們不能調用其內部的方法,因為他們內部已經優化成沒有方法了)

? 使用實際的例子來說明,為什么我們更應該使用 “原始類型”:

? “原始類型”有更快的速度(例如,下面的代碼執行,在我們的機器上需要9秒,但當我把 Long 改成 long 之后,0秒內就完成了)

? public static void main(String[] args) {

? ? long millis = System.currentTimeMillis();

? ? Long sum = 0L; // uses Long, not long

? ? for (long i = 0; i <= Integer.MAX_VALUE; i++) {

? ? ? ? sum += i;

? ? }

? ? System.out.println(sum);

? ? System.out.println((System.currentTimeMillis() - millis) / 1000);

}

? ?123456789

? “原始類型”允許我們直接使用 “==”來進行比較

? new Integer(3) == new Integer(3); // false

new Integer(100) == new Integer(100); // false

Integer.valueOf(5) == Integer.valueOf(5); //true

Integer.valueOf(200) == Integer.valueOf(200); //false

?

? ?12345

? 我們注意看第四句,輸出結果確實為 “false” 。這個是因在 [-128; 127] 這個區間的265個整數會被 JVM 緩存存放, 所以在這個區間, JVM返回相同的對象;然而,超出這個區間, JVM就不再有緩存了,將會創建新的對象,所以結果是不等的。

? 所以總結一下是: 在JVM內部,原始類型就是被當作對象來處理的。但是我們開發者直接把 “原始類型” 當作對象使用,開發者應該使用對應的包裝來。

? 以上就是為什么我說 “ Java確實是一個純粹的面向對象語言 ”的證實過程。如果你們對這個有什么其他的觀點,請在評論留言,一起討論。

? ?

? ?學習Java的同學注意了!!!? 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:533586908? ?我們一起學Java!?

? ?

??

? ? ? ? ?<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">

? ? ? ? ? ? </div>

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

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

相關文章

極速理解設計模式系列:6.適配器模式(Adapter Pattern)

四個角色&#xff1a;目標抽象類角色(Target)、目標對象角色(Adapter)、源對象角色(Adaptee)、客戶端角色(Client) 目標抽象類角色&#xff08;Target)&#xff1a;定義需要實現的目標接口 目標對象角色&#xff08;Adapter)&#xff1a;調用另外一個源對象&#xff0c;并且轉換…

[轉載] Java之繼承

參考鏈接&#xff1a; Java多重繼承 Java之繼承 繼承是面向對象程序的一個基本特征&#xff0c;通過繼承可以實現父子關系&#xff0c;以及代碼的復用。通過繼承實現的類稱為子類&#xff0c;被繼承的類稱為父類&#xff0c;所有直接或間接被繼承的類都稱為父類。 Java類體…

Spark(二): 內存管理

2019獨角獸企業重金招聘Python工程師標準>>> Spark 作為一個以擅長內存計算為優勢的計算引擎&#xff0c;內存管理方案是其非常重要的模塊&#xff1b; Spark的內存可以大體歸為兩類&#xff1a;execution和storage&#xff0c;前者包括shuffles、joins、sorts和agg…

[轉載] 手把手教你整合最優雅SSM框架:SpringMVC + Spring + MyBatis

參考鏈接&#xff1a; Java繼承類的對象創建 本文發表于2016年6月&#xff0c;寫于作者學生時期。文中使用到的技術和框架可能不是當下最佳實踐&#xff0c;甚至很不“優雅”。但對于剛接觸JavaEE和Spring的同學來說&#xff0c;還是能有很多收獲的&#xff0c;大牛輕拍 我們…

多播、組播、廣播優缺點分析

2019獨角獸企業重金招聘Python工程師標準>>> 單播、多播和廣播單播”&#xff08;Unicast&#xff09;、“多播”&#xff08;Multicast&#xff09;和“廣播”&#xff08;Broadcast&#xff09;這三個術語都是用來描述網絡節點之間通訊方式的術語。那么這些術語究…

[轉載] Java重載、覆蓋與構造函數

參考鏈接&#xff1a; Java中的繼承和構造函數 /** * 拷貝構造函數---Copyf t2 new Copyf(t1);就不會在調用默認構造函數了。 * 復制clone和引用 * 重載是在同一個類&#xff08;范圍&#xff09;中&#xff0c;覆蓋是子類對父類而言。 重載不關心返回值類型。 靜態方法不能被…

LOFTERD18B542F16FF685FD684F427B4…

2019獨角獸企業重金招聘Python工程師標準>>> 驗證 轉載于:https://my.oschina.net/jinhengyu/blog/1572124

[轉載] Java獲取一個類繼承的父類或者實現的接口的泛型參數

參考鏈接&#xff1a; Java中的接口和繼承 泛型的作用就不多介紹了&#xff0c;如果你想具備架構設計能力&#xff0c;那么熟練使用泛型是必不可少的。 不多說了&#xff0c;先定義泛型父類和泛型接口&#xff1a; package cn.zhh; public class Parent<T1, T2> { …

PHP系列(一)PHP流程控制結構

while(){} do{ }while(); for( 表達式1; 表達式2;表達式3 ){ 語句或語句序列; } if(){} if(){ }elseif{} <?php $i0; while(true) { if($i>100) break; echo ".$i.<br>"; $i; } ?> <?php echo "<table border1800>"; echo &quo…

[轉載] Scala繼承與Java的區別

參考鏈接&#xff1a; Java中將final與繼承一起使用 在之前的筆記Java靜態屬性和方法的繼承問題中&#xff0c;通過具體的實驗證明&#xff0c;在子類中重寫父類的字段時并沒有覆蓋父類的字段&#xff0c;只是隱藏了父類的字段。而在scala中則不同&#xff0c;scala子類的同名…

Source Map調試壓縮后代碼

在前端開發過程中&#xff0c;無論是樣式還是腳本&#xff0c;運行時的文件可能是壓縮后的&#xff0c;那這個時候調試起來就很麻煩。 這個時候&#xff0c;可以使用Source Map文件來優化調試&#xff0c;Source Map是一個信息文件&#xff0c;里面儲存著原代碼位置信息&#x…

[轉載] Python3十大經典錯誤及解決辦法

參考鏈接&#xff1a; Python中的關鍵字2 ◆ ◆ ◆ ◆ ◆ 接觸了很多Python愛好者&#xff0c;有初學者&#xff0c;亦有轉行人。不論大家學習Python的目的是什么&#xff0c;總之&#xff0c;學習Python前期寫出來的代碼不報錯就是極好的。下面&#xff0c;嚴小樣兒為大家羅…

兩臺電腦間大量數據拷貝的快捷方法

可能大家會遇到需要將一臺電腦里的數據拷貝到另外一臺電腦&#xff0c;最常用的方法是用u盤或移動硬盤等存儲設備來拷貝&#xff0c;這樣速度慢&#xff0c;而且可能拷貝多次才能將數據拷貝完。現提供一種方法&#xff0c;就是通過windows 的文件共享來實現。通過千兆網線直接連…

[轉載] 使用 Web 標準生成 ASP.NET 2.0 Web 站點

參考鏈接&#xff1a; 使用super訪問Java祖父母的成員 Stephen WaltherSuperExpert.com 適用于&#xff1a; Microsoft ASP.NET 2.0 (Beta 2) Microsoft Visual Studio .NET 2005 Microsoft Visual Web Developer 摘要&#xff1a; Microsoft ASP.NET 2.0 具有很多有用的功能…

Office快捷鍵大全之三(Access快捷鍵下篇)

向下鍵 向某幫助主題的末尾滾動 Page Up 以較大增量向某幫助主題的開頭滾動 Page Down 以較大增量向某幫助主題的末尾滾動 Home 移到某幫助主題的開頭 End 移到某幫助主題的末尾 CtrlP 打印當前幫助主題 CtrlA 選定整個幫助主題 CtrlC 將選定項復制到"剪貼…

[轉載] 如何在Android設備之間共享Google Play應用,音樂等

參考鏈接&#xff1a; 使用super訪問Java祖父母的成員 We recently showed you how to configure your iOS devices for app and media sharing; more than a few people wrote in asking how to do the same thing with Google Play purchases. Read on as we dig into how t…

linux 高性能讀書筆記之通用socket地址

####socket網絡編程接口 socket的地址是結構體sockaddr 代碼如下 struct sockaddr{ sa_family_t sa_family; char sa_data[14]; } sa_family 成員是地址族類型&#xff08;sa_family_t)變量。地址族類型通常與協議族類型對應 1.二者對應表 協議族地址表描述PF_UNIXAF_UNIXUNIX本…

[轉載] JAVA面向對象之代碼塊 繼承 方法的重寫 super關鍵字與重寫toString()方法介紹

參考鏈接&#xff1a; 可以重寫Java中的私有方法嗎 JAVA面向對象之代碼塊與繼承 代碼塊分類 局部代碼塊 作用:限制變量生命周期 書寫位置:在方法中 構造代碼塊 開發中很少使用 書寫位置:類中 方法外 調用時機:如果你有構造代碼塊 系統會幫你調用 幫你在創建對象…

struts2中s:select標簽的使用

轉自&#xff1a;https://www.cnblogs.com/Sara-shi/archive/2013/03/13/struts2_select.html 1 靜態生成 <s:select name"user.sex" list"#{0:男,1:女}" label"性別" headerKey"" headerValue"請選擇性別"></s:se…

[轉載] JAVA面試題大全(part_1)

參考鏈接&#xff1a; 對Java中派生類方法更嚴格的訪問 JAVA面試題大全(part_1) 1、面向對象的特征有哪些方面 (1)抽象&#xff1a; 抽象就是忽略一個主題中與當前目標無關的那些方面&#xff0c;以便更充分地注意與當前目標有關的方面。抽象并不打算了解全部問題&#xf…