認識Java的整形數據結構

来源:https://www.cnblogs.com/huaweiyun/archive/2022/09/21/16716258.html
-Advertisement-
Play Games

摘要:java中一切都是對象,為什麼int不用創建對象實例化,而可以直接使用? 本文分享自華為雲社區《【Java】對基本類型-整型數據結構的認識》,作者: huahua.Dr 。 整型數據類型有兩個:基本類型和引用類型(包裝類) 整數型基本類型:byte,int,short,long 其引用類型:B ...


摘要:java中一切都是對象,為什麼int不用創建對象實例化,而可以直接使用?

本文分享自華為雲社區《【Java】對基本類型-整型數據結構的認識》,作者: huahua.Dr 。

整型數據類型有兩個:基本類型和引用類型(包裝類)

整數型基本類型:byte,int,short,long

其引用類型:Byte,Integer,Short,Long

他們之前主要的區別在於:

  1. 存儲占用的空間不同,分別是1,2,4,8個位元組(每個位元組占用8bit),
  2. java裡面整數型預設使用的int數據類型,即如果直接寫整數字面量時,它表示的就是int類型,
  3. 整數型數據類型之間可以相互轉換,以int為預設中間類型,定義了一個整數值4,可以直接賦值給int,
  4. 也可以直接賦值給short和byte(只要數值範圍不超過byte和short的存儲範圍,可以自動向下轉型為byte或者short;如果超過則需要強轉但超過的高位數會丟失),也可以直接賦值給long,不需要強轉,會自動向上轉型。
  5. long數據類型可以直接使用L或l聲明
  6. 他們之間可以直接轉,只要數值範圍大於等於它的數值範圍,都可以直接轉;如果小於它的數值範圍就需要強轉,但強轉會導致數值丟失,編譯並不會報錯。

其他的基本相同;因此我們以int類型來展開詳細說明。

java中一切都是對象,為什麼int不用創建對象實例化,而可以直接使用?

單純是為了編程方便,引入基本類型。

既然引入了基本對象,那也不能破壞java是一個操作對象的語言吧?

所以後面引入了包裝類(wrapper class),為每種基本類型都引入了其對應的包裝類型,int基本類型的包裝類型就是Integer對象。

基本類型引入了包裝類型就能將,int基本類型就能像操作對象一樣去操作了嗎?

是的,還Java1.55引入了一個機制:自動拆箱和自動裝箱,使得基本類型和其對應的包裝類型可以相互轉換,原始基本類型可以自動轉換成對應的包裝對象。

基本類型和包裝類型是何時進行相互轉化,如何相互轉換?

自動拆箱與裝箱機制,可以在java變數賦值或者方法調用傳值與返回值或者容器存儲數據時直接使用基本類型或者對應的包裝類型;在java 1.5版本之前,使用容器集合(Collection)存儲數據時,只能存儲引用類型,需要存儲基本類型,則需要先將其轉成其對應的包裝類型才可以。

自動裝箱就是java自動的將基本類型數值轉換成其對應的包裝類型,自動裝箱時編譯器會自動調用其包裝類的valueOf()方法將基本類型數值轉成對象。

自動拆箱就是java自動將包裝類型轉換成其對應的基本類型,自動拆箱時編譯器會自動調用其包裝類的xxxValue()方法:如intValue()\doubleValue()\longValue()等將對象轉成基本類型數值。

當基本數據數值與包裝類型進行運算時,會觸發自動拆箱。

例子:

//before autoboxing
Integer iObject = Integer.valueOf(3);
Int iPrimitive = iObject.intValue()
//after java5
Integer iObject = 3; //autobxing - primitive to wrapper conversion
int iPrimitive = iObject; //unboxing - object to primitive conversion
public static Integer show(Integer iParam){
 System.out.println("autoboxing example - method invocation i: " + iParam);
   return iParam;
}
//autoboxing and unboxing in method invocation
show(3); //autoboxing
int result = show(3); //unboxing because return type of method is Integer

那自動拆箱和裝箱那麼方便,它有什麼缺點嗎?

由於編譯器的介入,增加了操作步驟和工作量,如果頻繁自動拆箱和裝箱,會影響程式性能:

Integer sum = 0;
 for(int i=1000; i<5000; i++){
   sum+=i;
}

上面的代碼sum+=i可以看成sum = sum + i,但是+這個操作符不適用於Integer對象,首先sum進行自動拆箱操作,進行數值相加操作,最後發生自動裝箱操作轉換成Integer對象。其內部變化如下:

int result = sum.intValue() + i;
Integer sum = new Integer(result);

由於我們這裡聲明的sum為Integer類型,在上面的迴圈中會創建將近4000個無用的中間 Integer對象,在這樣龐大的迴圈中,會降低程式的性能並且加重了GC垃圾回收的工作量。因此在我們編程時,需要註意到這一點,正確地聲明變數類型,避免因為自動裝箱引起的性能問題。

還有一個問題:如果int與Integer混用,Integer自動拆箱成int時,會調用Integer.intValue()方法進行拆箱,如果Integer賦值為null,M那麼此時就會出現空指針異常。

如果一個類中有兩個重載方法,一個重載方法的參數是int基本類型,一個是Integer引用類型,那麼調用該方法時,會自動拆箱或裝箱嗎,實際會調用到那個方法?

Java1.5之前肯定是會根據實際參數是基本類型還是引用類型來選擇對應的方法;但是java1.5之後,有了自動拆箱和裝箱機制之後,也是不會觸發該機制的。也是根據實際參數類型來選擇對應的方法調用。下麵我們用實際代碼來說明一下:

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        Test test = new Test();
        int para1 = 12;
        Integer para2 = 12;
 test.test(12);
 test.test(para2);
    }
    public void test(int para1) {
 System.out.println("我的參數是int基本類型,值:"+para1);
    }
    public void test(Integer para2) {
 System.out.println("我的參數是Integer類型,值:"+para2);
    }
}

輸出:

我的參數是int基本類型,值:12

我的參數是Integer類型,值:12

那麼基本類型int與包裝類型Integer,數值進行比較是否相等會出現什麼情況?

情況有三種:==比較的是地址,對象Object的equals方法比較的也是地址,只不過包裝類型重寫了Object方法,比較的數值。

  1. int與int比較是否相等,使用==進行兩個數值相等的int比較,結果是true
  2. Integer與Integer比較是否相等,-128到127的Integer兩個數值相等的對象使用==比較結果是true,應為JVM為了省記憶體會將該範圍的數值緩存起來,共用一個Integer對象;該範圍以外的==比較結果是false;如果都是重新new 的兩個數值相等的Integer對象,==也是false,需要使用Integer對象的equals方法,比較才是true,
  3. int與Integer比較是否相等,Integer會自動拆箱,返回的結果是true.
 // Example 1: == comparison pure primitive – no autoboxing
        int i1 = 1;
        int i2 = 1;
 System.out.println("i1==i2 : " + (i1 == i2)); // true
        // Example 2: equality operator mixing object and primitive
        Integer num1 = 1; // autoboxing
        int num2 = 1;
 System.out.println("num1 == num2 : " + (num1 == num2)); // true
        // Example 3: special case - arises due to autoboxing in Java
        Integer obj1 = 1; // autoboxing will call Integer.valueOf()
        Integer obj2 = 1; // same call to Integer.valueOf() will return same
        // cached Object
 System.out.println("obj1 == obj2 : " + (obj1 == obj2)); // true
        // Example 4: equality operator - pure object comparison
        Integer one = new Integer(1); // no autoboxing
        Integer anotherOne = new Integer(1);
 System.out.println("one == anotherOne : " + (one == anotherOne)); // false
        int num3 = 129;
        Integer obj3 = 129;
 System.out.println("num3==obj3:"+(num3==obj3));// true

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 案例 學習網址:https://seaborn.pydata.org/examples/errorband_lineplots.html import seaborn as sns import pandas as pd sns.set_theme(style="darkgrid") # 導入數據 ...
  • 前言 工欲善其事,必先利其器。本篇文章我們介紹下 Terraform,為後續創建各種雲資源做準備,比如Kubernetes 關鍵詞:IaC, Infrastructure as Code, Terraform, 基礎架構即代碼,Terraform 例子, Terraform 入門,Terraform ...
  • 顧名思義,子流程是一個包含其他活動、網關、事件等的活動,這些活動本身形成了一個流程,該流程是更大流程的一部分。 使用子流程確實有一些限制: 一個子流程只能有一個none類型的啟動事件,不允許有其他類型的啟動事件。一個子流程必須至少有一個結束事件。(請註意,BPMN 2.0 規範允許在子流程中省略開始 ...
  • Docker安裝和卸載 一,已安裝Docker,卸載Docker 1.方法一 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-l ...
  • Django_模型ORM Django中內嵌了ORM框架,不需要直接編寫SQL語句進行資料庫操作,而是通過定義模型類,操作模型類來完成對資料庫中表的增刪改查和創建等操作。 O是object,也就類對象的意思。 R是relation,翻譯成中文是關係,也就是關係資料庫中數據表的意思。 M是mappin ...
  • 17.1遠程資源授權準備 17.1.1認證和訪問流程圖 參考:http://www.zyiz.net/tech/detail-141309.html 17.1.2為用戶指定角色 可以使用ROLE_USER和ROLE_ADMIN 兩種角色 17.1.3添加認證服務和資源服務 17.1.4配置客戶端的認 ...
  • 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 特效 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> O ...
  • “為什麼加索引能提升查詢效率”! 我們都認為“加索引”提升查詢效率是理所應當的 竟然還有理由? 該怎麼回答呢? 大家好,我是Mic,一個工作了14年的Java程式員 下麵分析一下這個問題的考察點 考察目標 這是一道原理性的問題,考察求職者對於Mysql中索引的實現原理的理解程度。 一般情況下,考察3 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...