內部類和Object類

匿名對象

格式:

匿名對象只可以調用一次成員 :

1. 調用一次成員變量 :?new? 類名(實參).成員變量名;

2.調用一次成員方法:??new? 類名(實參).成員方法名(實參);

匿名對象存在的必要:為了提高內存的使用性能,如果有一個變量(對象),在內存中再也不能使用了,那么這個對象很快就會被JMV標記成垃圾,被回收掉。

內部類

將一個類定義在另一個類或者一個方法的內部,稱為內部類
內部類和外部類共用同一個 java 源文件,但是經過編譯之后,內部類會形成單獨的字節碼文件

實例內部類

格式:

//外部類
class External{private int a1=1;private int a2=2;private static int a3=3;//實例內部類public class Inside{private int a1=1111;private  int a4=4;private static final int a5=5;// 在實例內部類中聲明靜態常量//實例內部類對象必須在先有外部類對象前提下才能創建//實例內部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束public void way(){//在實例內部類方法中訪問同名的成員時,優先訪問自己的System.out.println(a1);//如果要訪問外部類同名的成員,必須:外部類名稱.this.同名成員 來訪問System.out.println(External.this.a1);//每個實例內部類都有一個指向其外部類實例的隱式引用。即 外部類名稱.this.外部類成員//換句話說,當在 way 中訪問外部類的成員時,它實際上是通過 外部類名稱.this 來引用外部類的實例//所以外部類中的任何成員都可以在實例內部類方法中直接訪問System.out.println(a2);System.out.println(a3);System.out.println(a4);System.out.println(a5);System.out.println("這是實例內部類");}}public void way(){//外部類中,不能直接訪問實例內部類中的成員,如果要訪問必須先要創建內部類的對象。Inside inside = new Inside();System.out.println(inside.a4);System.out.println("這是外部類");}
}
public class Test {public static void main(String[] args) {//獲取實例內部類對象//方法1External external = new External();//創建外部實例External.Inside inside1 = external.new Inside(); // 通過外部類實例創建內部類實例inside1.way();// 調用內部類的方法external.way();//方法2//通過new External() 來創建一個新的外部類實例,并通過 new Inside() 創建對應的內部類實例。External.Inside inside2 = new External().new Inside();// 在一行中創建外部類和內部類實例inside2.way();}
}

靜態內部類

靜態內部類的特點:

  1. 靜態修飾: 靜態內部類使用 static 關鍵字修飾,意味著它是外部類的一部分,但它的生命周期不依賴于外部類的實例。
  2. 可以訪問外部類的靜態成員: 靜態內部類可以訪問外部類的靜態變量和靜態方法,但無法直接訪問外部類的實例成員變量和方法。
  3. 實例化方式: 靜態內部類不依賴于外部類的實例,可以通過外部類名直接實例化,可以直接通過外部類來訪問。
  4. 可以獨立存在: 靜態內部類是一個獨立的類,可以像普通類一樣被實例化和使用。它不會像實例內部類一樣必須依賴外部類實例來創建。

靜態內部類的使用場景:

  • 封裝: 當一些功能和外部類緊密相關,但又不需要依賴外部類的實例時,使用靜態內部類來封裝這些功能。
//外部類
class External{public int a1=1;public static int a2=2;public static void way1(){System.out.println(a2);}//靜態內部類:被static修飾的內部類成員static class Static{//可以訪問外部類的靜態變量public static int a3=3;public int a4=4;public void way(){//System.out.println(a1);//編譯失敗,因為a1不是靜態成員變量System.out.println(a2);//靜態內部類可以訪問外部類的靜態變量和靜態方法System.out.println(a3);System.out.println(a4);}}
}
public class Test {public static void main(String[] args) {//創建靜態內部類對象時,不需要先創建外部類對象External.Static st=new External.Static();st.way();}
}

局部內部類

局部內部類的特點:

  1. 定義位置: 局部內部類只能定義在外部類的 方法構造函數 內部。
  2. 作用域: 僅在外部方法內部有效,方法結束后局部內部類實例將被銷毀,不能在外部方法之外被訪問或創建
  3. 訪問限制: 局部內部類只能訪問方法內的 final有效的 final 局部變量(即那些在方法中沒有被修改過的變量),可以訪問外部類中的實例變量。
  4. 不可以使用訪問修飾符: 局部內部類不能使用 publicprivate 等訪問修飾符,因為它的作用范圍僅限于方法內。
  5. 不能使用靜態修飾符: 因為局部內部類是方法的一部分,不能定義為靜態的。

局部內部類的使用場景:

  • 當某些功能只在方法內部需要時,可以使用局部內部類來實現。
  • 適用于需要封裝邏輯但只在某個方法內使用的類,避免在外部暴露不必要的復雜性。
//外部類
class External{public String a1="外部類中的實例成員變量";public final String a2="外部類中不能被修改的實例成員變量";public void display(){System.out.println("外部類的方法");}//外部類的方法public void meth(){String a3="方法中的局部變量";final String a4 = "方法中的局部常量";//局部內部類//局部內部類不能使用 public、private 等訪問修飾符,因為它的作用范圍僅限于方法內。class Inner{String a5="局部內部類中的局部變量";public void way(){String a6="局部內部類方法中的局部變量";//局部內部類可以訪問外部類中的實例變量System.out.println(External.this.a1);System.out.println(a1);System.out.println(a2);//局部內部類可以訪問外部類的方法display();//局部內部類可以訪問外部方法中的未被修改過的局部變量System.out.println(a3);System.out.println(a4);System.out.println(a5);System.out.println(a6);}}//局部內部類只在外部方法的作用域內有效,方法結束后將會被銷毀,不能在外部方法之外被訪問或創建//在meth()方法內部創建局部內部類實例Inner inner = new Inner();inner.way();//調用局部內部類的方法}
}
public class Test {public static void main(String[] args) {External external = new External();external.meth();//調用外部類中的方法,觸發局部內部類的創建}
}

匿名內部類

格式:

匿名類的調用:

方法1:可以直接調用匿名類中特有的方法

方法2:使用場景

匿名類通常作為一個參數傳遞給方法

匿名類的特點:

匿名類本質就是一個子類,匿名類可以作為接口實現或者類繼承的匿名子類。匿名類在定義時就會立即實例化,并且可以用于初始化變量。

代碼實例:

1. 不使用匿名方法

//創建接口
interface Animal{void run();
}
//創建實現接口的方法
class Dog implements Animal{//方法重寫public void run(){System.out.println("跑得快");}
}
public class Test {public static void main(String[] args){running(new Dog());}public static void running(Animal animal){//Animal animal = new Dog;向上轉型animal.run();}
}

2. 使用匿名方法

//創建接口
interface Animal{void run();
}
public class Test {public static void main(String[] args){String name ="小狗";//通過匿名類訪問局部變量,在JDK8版本之前,必須加final關鍵字,表示常量,即不能被修改new Animal(){//方法重寫public void run(){System.out.println(name+"跑得快");}}.run();}
}
//創建接口
interface Animal{void run();
}
public class Test {public static void main(String[] args){String name ="小狗";//通過匿名類訪問局部變量,在JDK8版本之前,必須加final關鍵字,表示常量,即不能被修改running(new Animal(){//方法重寫public void run(){System.out.println(name+"跑得快");}});}public static void running(Animal animal){animal.run();}
}

Object 類

Object 類是所有類的根類,位于 java.lang 包中。這意味著 Java 中的每個類都是 Object 類的子類,直接或間接地繼承了 Object 類的屬性和方法。

Object Java 默認提供的一個類。 Java 里面除了 Object 類,所有的類都是存在繼承關系的。默認會繼承 Object 父類。即所有類的對象都可以使用Object 的引用進行接收
方法簽名描述
public String toString()

返回該對象的字符串表示。如果子類沒有重寫該方法,則默認返回對象的類名、@?符號和對象哈希碼的無符號十六進制表示。

public boolean equals(Object obj)指示某個其他對象是否與此對象相等。默認行為是僅在兩個對象相同(即引用相等)時返回?true
public int hashCode()返回該對象的十進制哈希碼值。默認哈希碼是對象的內存地址轉換成的整數。如果?equals()?方法被重寫,則通常也需要重寫?hashCode()?方法,以確保相等的對象有相同的哈希碼。
protected Object clone()創建并返回此對象的一個副本。默認實現拋出?CloneNotSupportedException,因此子類需要重寫此方法以支持克隆操作,并實現?Cloneable?接口

1. toString 方法

this.getClass():獲取一個類的字節碼
this.getClass().getName():獲取一個類的全限定名(包名+類名)
this.hashCode():獲取一個對象的哈希碼值,是一個十進制數據
Integer.toHexString(十進制數據):把十進制數據轉換成十六進制數據

重寫toString方法

    @Overridepublic String toString() {//Animal{name='',age= };return "Animal{" +"name='" + name + '\'' +", age=" + age +'}';}

結論:

如果一個類沒有重寫toString方法,那么打印此類的對象是地址值

如果一個類重寫了toString方法,那么打印此類的對象打印的是內容

2. equals 方法

"=="

1. 比較基本數據類型:比較數據值是否相等

2. 比較引用數據類型:比較地址是否相等

//Object 中的equals方法public boolean equals(Object obj) {//this : 調用此方法中的對象 a1//object : a2return (this == obj);
}
public class Test {public static void main(String[] args) {Animal a1=new Animal("小狗",6);Animal a2=new Animal("小狗",6);System.out.println(a1.equals(a2));//false}
}

重寫equals

    @Overridepublic boolean equals(Object o) {//判斷地址是否相同,如果地址相同說明內容一定相同//提高代碼執行效率if (this == o) return true;//getClass():獲取一個類的字節碼對象,同一個類的字節碼對象是相等的//getClass() != o.getClass():保證比較對象的類型是一致的//o == null :如果a2為null,直接返回false,提高代碼的健壯性,不容易報錯//為什么不寫a1是否為null,因為a1為null,代碼在打印時直接報錯,不進入equals方法if (o == null || getClass() != o.getClass()) return false;//向下轉型,目的是為了調用子類特有的成員Animal animal = (Animal) o;//此equals為String類當中的equals,目的是比較字符串的內容return age == animal.age && Objects.equals(name, animal.name);}

結論:

如果一個類沒有重寫equals方法,那么比較對象比較的是地址值是否相等

如果一個類重寫了equals方法,那么比較對象比較的是內容是否相等

3. hashCode 方法

返回該對象的十進制哈希碼值。默認哈希碼是對象的內存地址或字符串或數字轉換成的整數

自定義類的對象哈希碼值默認返回對象的地址

在Object類中

public class Test {public static void main(String[] args) {Animal a1=new Animal("小狗",6);Animal a2=new Animal("小狗",6);System.out.println(a1.hashCode());System.out.println(a2.hashCode());}
}

重寫hashCode方法

    @Overridepublic int hashCode() {return Objects.hash(name, age);}

結論:

如果一個類沒有重寫hashCode方法,那么內容相同的對象將返回不同的哈希碼值,即存儲在不同的位置

如果一個類重寫hashCode了方法,那么內容相同的對象將返回相同的哈希碼值,即存儲在相同的位置

但內容相同的對象在通過equals方法比較時,應該具有相同的哈希碼值,所以重寫 hashCode() 方法是為了確保內容相同的對象具有相同的哈希碼值,這樣它們在哈希表中可以被存儲在相同的位置,從而提高哈希表的性能和正確性。

4. clone 方法

1. 淺克隆

拷貝出的新對象,與原對象中的數據一模一樣(引用類型拷貝的只是地址

import java.util.Arrays;
import java.util.Objects;//Cloneable是一個標記性接口:證明當前類是可以被克隆的class Animal extends Object implements Cloneable{public String name;public int age;public double[] quantity;public Animal(String name, int age, double[] quantity) {this.name = name;this.age = age;this.quantity = quantity;}@Overridepublic String toString() {return "Animal{" +"name='" + name + '\'' +", age=" + age +", quantity=" + Arrays.toString(quantity) +'}';}//淺拷貝@Overrideprotected Object clone() throws CloneNotSupportedException {//調用Object中的clone方法并返回return super.clone();}
}public class Test {public static void main(String[] args) throws CloneNotSupportedException {Animal a3=new Animal("小狗",5,new double[]{20,30,40});System.out.println(a3);System.out.println(a3.quantity);Animal a4=(Animal)a3.clone();System.out.println(a4);System.out.println(a4.quantity);}
}

2. 深克隆

對象中基本類型的數據直接拷貝

對象中的字符串拷貝的是地址

對象中包含的其他對象,不會拷貝地址,會創建新的對象

    public Object clone() throws CloneNotSupportedException {Animal animal = (Animal) super.clone();//把對象中的數組單獨克隆一次animal.quantity=animal.quantity.clone();return animal;}

Comparable 接口

使用Arrays.sort 方法對 Animal 對象進行排序,需要元素實現 Comparable 接口或者傳遞一個 Comparator 實例。

1.?實現 Comparable 接口:在 Animal 類中定義排序規則,讓 Animal 類實現 Comparable<Animal>,并在 compareTo 方法中定義排序規則,如按照 age 升序排序。

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;class Animal implements Comparable<Animal> {public String name;public int age;public Animal(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Animal{" +"name='" + name + '\'' +", age=" + age +'}';}//重寫compareTo方法@Overridepublic int compareTo(Animal o){return this.age-o.age;}
}
public class Test {public static void main(String[] args) {Animal a1=new Animal("大黃" ,5);Animal a2=new Animal("小黑",3);System.out.println(a1.compareTo(a2));//通過compareTo對a1和a2對象的age進行比較Animal[] animals=new Animal[]{new Animal("大黃",7),new Animal("小黑",5),new Animal("小胖",4),new Animal("小白",9)};Arrays.sort(animals);System.out.println(Arrays.toString(animals));}
}

我們發現comparable接口拓展性不強,只能通過age進行比較,對類的侵入性比較強

2. 使用 Comparator 接口:在調用 Arrays.sort 時傳入自定義的比較器

        //使用匿名方法Arrays.sort(animals,new Comparator<Animal>(){//重寫Comparator接口中的compare方法public int compare(Animal o1,Animal o2){return o1.age-o2.age;//按年齡升序排列}});System.out.println(Arrays.toString(animals));//使用匿名方法Arrays.sort(animals,new Comparator<Animal>(){//重寫Comparator接口中的compare方法public int compare(Animal o1,Animal o2){//因為String類實現了Comparable<string>接口//使用可以調用compareTo方法比較兩個字符串大小return o1.name.compareTo(o2.name);//按姓名升序排列}});System.out.println(Arrays.toString(animals));

兩種方法的區別

  1. 實現 Comparable

    • 優點:直接在類中定義了排序規則,適合需要多次排序的場景,代碼復用性高。
    • 缺點:只能實現一種排序規則,無法靈活切換。
  2. 使用 Comparator

    • 優點:可以為不同場景定義不同的排序規則,靈活性更高。
    • 缺點:每次排序都需要定義規則,代碼復用性較低

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

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

相關文章

Python的3D可視化庫vedo 1-3 (visual模塊)網格對象的線和面、圖片的屬性

文章目錄 4 MeshVisual4.1 線條4.1.1 線寬和顏色4.1.2 線條渲染為管 4.2 曲面4.2.1 物體展示為實心或框架4.2.2 曲面插值4.2.3 面的剔除 4.3 紋理4.4 相機跟隨 5 ImageVisual5.1 圖片屬性5.1.1 占用內存大小5.1.2 顏色標量范圍 5.2 渲染屬性5.2.1 透明度5.2.2 亮度5.2.3 對比度…

19 設計模式之享元模式(電影院座位預定案例)

一、享元模式的定義 享元模式是一種結構型設計模式&#xff0c;它通過共享對象來支持大量細粒度的對象&#xff0c;減少內存消耗。享元模式的核心思想是&#xff1a;將對象分為共享部分和非共享部分&#xff0c;只有共享部分是被多個對象共享的&#xff0c;而非共享部分則是每個…

使用redis 的stream 做消息中間件 多線程消費消息

1.redis stream 特點 1.支持消息持久化 2.消費者組模式 3.消息確認機制 4. 消息重試機制 5. 死信隊列2. 消息生產者服務 2.1 如下代碼Service Slf4j public class StreamMessageProducer {Autowiredprivate StringRedisTemplate redisTemplate;private static final String S…

Python100道練習題

Python100道練習題 BIlibili 1、兩數之和 num1 20 num2 22result num1 num2print(result)2、一百以內的偶數 list1 []for i in range(1,100):if i % 2 0:list1.append(i) print(list1)3、一百以內的奇數 # 方法一 list1 [] for i in range(1,100):if i % 2 ! 0:lis…

Java轉C之并發和多線程

提綱&#xff1a; 概念介紹與對比概述 簡述Java與C在并發和多線程方面的核心區別解釋C11標準、POSIX、C11 <threads.h>、Pthread等名詞 Java多線程與并發回顧 線程、Runnable、ExecutorService概念說明同步關鍵字與工具類含義 C并發基礎 沒有Java式的內置線程類&#xf…

Ubuntu系統本地化搭建Maxakb+Ollama

安裝docker 最詳細的ubuntu 安裝 docker教程-騰訊云開發者社區-騰訊云 安裝Ollama Ollama官網 執行命令&#xff1a; curl -fsSL https://ollama.com/install.sh | sh安裝完成后下載模型 執行命令&#xff1a; ollama run llama3.3:70b安裝MaxKb 執行命令&#xff1a; d…

基于JAVA的旅游網站系統設計

摘要 隨著信息技術和網絡技術的迅速發展&#xff0c;人們的生活質量和觀念也在發生著改變&#xff0c;各地爭相發展旅游業&#xff0c;傳統的 旅游社已經無法滿足人們的需求&#xff0c;旅游網站將突破傳統在時間和地域的限制&#xff0c;成為方便、快捷、安全、可靠的旅游 方…

【Flux.jl】 卷積神經網絡

Flux.jl 是包含卷積神經網絡的, 但是官方API文件中沒有給出一個完整的程序框架, 只是對所需神經元給了局部解釋, 此外對 model-zoo 模型動物園中的案例沒有及時跟著 Flux.jl 的版本更新, 也無法運行出來結果。 因此本文搭建了一個完整可訓練的卷積神經網絡。 Conv 卷積算子…

H5游戲出海如何獲得更多增長機會?

海外H5小游戲的崛起給了國內眾多中小廠商出海發展的機會&#xff0c;開發者如何在海外市場獲得更多的增長機會&#xff1f;#APP出海# H5游戲如何在海外獲得核心用戶&#xff1f; HTML5游戲的開發與運營者們首先可以利用量多質高的HTML5游戲&#xff0c;維持海外用戶粘性&…

Next.js系統性教學:深入理解和應用組件組合模式

更多有關Next.js教程&#xff0c;請查閱&#xff1a; 【目錄】Next.js 獨立開發系列教程-CSDN博客 目錄 更多有關Next.js教程&#xff0c;請查閱&#xff1a; 1. 什么是組件組合模式&#xff1f; 1.1 組件組合模式概述 1.2 組件組合模式的優勢 2. Next.js 中的組件組合模式…

國際薦酒師Peter助力第六屆地博會,推動地理標志產品國際化發展

國際薦酒師Peter Lisicky助力第六屆知交會暨地博會&#xff0c;推動地理標志產品國際化發展 第六屆粵港澳大灣區知識產權交易博覽會暨國際地理標志產品交易博覽會于2024年12月9日至11日在中新廣州知識城盛大舉行&#xff0c;吸引了全球眾多行業專家、企業代表及相關機構齊聚一…

Mybatis 延遲加載的實現原理詳細解析

Mybatis 延遲加載的實現原理詳細解析 &#xff08;1&#xff09;代理對象機制的深入探討 代理對象的生成&#xff1a;Mybatis 使用代理對象來實現延遲加載是基于 Java 的代理機制。當開啟延遲加載并且配置正確后&#xff0c;對于需要延遲加載的關聯對象&#xff0c;Mybatis 會…

2024 亞馬遜云科技re:Invent:Werner Vogels架構哲學,大道至簡 六大經驗助力架構優化

在2024亞馬遜云科技re:Invent全球大會第四天的主題演講中&#xff0c;亞馬遜副總裁兼CTO Dr.Werner Vogels分享了 The Way of Simplexity&#xff0c;繁簡之道&#xff0c;濃縮了Werner在亞馬遜20年構建架構的經驗。 Werner表示&#xff0c;復雜性總是會“悄無聲息”地滲透進來…

Java Web 開發學習中:過濾器與 Ajax 異步請求

一、過濾器 Filter&#xff1a; 過濾器的概念與用途 在一個龐大的 Web 應用中&#xff0c;有許多資源需要受到保護或進行特定的預處理。過濾器就像是一位智能的守衛&#xff0c;站在資源的入口處&#xff0c;根據預先設定的規則&#xff0c;決定哪些請求可以順利訪問資源&…

ThinkPHP框架審計--基礎

基礎入門 搭建好thinkphp 查看版本方法&#xff0c;全局搜version 根據開發手冊可以大致了解該框架的路由 例如訪問url http://127.0.0.1:8094/index.php/index/index/index 對應代碼位置 例如在代碼下面添加新方法 那么訪問這個方法的url就是 http://127.0.0.1:8094/index.…

淺談Python庫之?Requests

一、?Requests的介紹 Requests 是一個簡單易用的 HTTP 庫&#xff0c;用于發送各種 HTTP 請求。它由 Kenneth Reitz 創建&#xff0c;并廣泛用于 Python 社區中。 二、?Requests的特點 1、人性化的 API&#xff1a;簡潔的接口使得編寫請求代碼變得簡單直觀。 2、跨平臺&…

如何在vue中使用ECharts

一. 打開ECharts官網,點擊快速入門 下面是ECharts官網的鏈接 https://echarts.apache.org/ 二.在vue中使用 1.首先先引入Echarts js文件 如下圖&#xff0c;下面的第一張圖片是官網的實現&#xff0c;第二章圖片是我根據官網的實現 2.給ECharts 創建一個DOM容器 3. 使用ec…

網絡原理之 IP 協議

目錄 1. IP 協議報文格式 2. 網段劃分 3. 地址管理 1) 動態分配 2) NAT 機制 (網絡地址轉換) 3) IPv6 4. 路由選擇 1. IP 協議報文格式 IP 協議是網絡層的重點協議。 網絡層要做的事情&#xff0c;主要就是兩方面&#xff1a; 1) 地址管理 制定一系列的規則&#xff…

HyperMesh CFD功能詳解:后處理功能Part 2

Clips Clips 按鈕包含兩個工具。Box Clip用于空間上的裁剪&#xff0c;Scalar Clip可以根據物理量的范圍裁剪。 示例&#xff1a;Box Clips 裁剪 示例&#xff1a;Scalar Clips 裁剪 通過裁剪&#xff0c;僅顯示density范圍是10~20的等值面 示例&#xff1a;顯示效果控制 部分透…

Java項目實戰II基于微信小程序的跑腿系統(開發文檔+數據庫+源碼)

目錄 一、前言 二、技術介紹 三、系統實現 四、核心代碼 五、源碼獲取 全棧碼農以及畢業設計實戰開發&#xff0c;CSDN平臺Java領域新星創作者&#xff0c;專注于大學生項目實戰開發、講解和畢業答疑輔導。獲取源碼聯系方式請查看文末 一、前言 在快節奏的現代生活中&…