最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的Kotlin?內(nèi)部類原理

 更新時(shí)間:2022年06月16日 11:18:54   作者:??自動(dòng)化BUG制造器????  
這篇文章主要介紹了Java中的Kotlin?內(nèi)部類原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下

Java 中的內(nèi)部類

這是一個(gè) Java 內(nèi)部類的簡(jiǎn)單實(shí)現(xiàn):

public class OutterJava {
 ? ?private void printOut() {
 ? ? ? ?System.out.println("AAA");
 ?  }
?
 ? ?class InnJava {
 ? ? ? ?public void printInn() {
 ? ? ? ? ? ?printOut();
 ? ? ?  }
 ?  }
}

外部類是一個(gè)私有方法,內(nèi)部類為什么可以訪問到外部類的私有方法呢?思考這個(gè)問題,首先要從它的字節(jié)碼入手,看看 JVM 到底對(duì) java 文件做了什么。

字節(jié)碼分析流程是:

  • javac xxx.java生成 class 文件。
  • javap -c xxx.class對(duì)代碼進(jìn)行反匯編,可以生成可查看的代碼內(nèi)容。

通過 javac 命令生成 class 文件,此時(shí)會(huì)發(fā)現(xiàn)生成了兩個(gè) class 文件,一個(gè)外部類 OtterJava 的,一個(gè)內(nèi)部類 InnJava 的。

OutterJava.class

OutterJava.class 反匯編后的代碼如下所示,這里面除了一個(gè)構(gòu)造方法,多生成了一個(gè)

Compiled from "OutterJava.java"
public class java.OutterJava {
 ?public java.OutterJava();
 ? ?Code:
 ? ? ? 0: aload_0
 ? ? ? 1: invokespecial #2 ? ? ? ? ? ? ? ? ?// Method java/lang/Object."<init>":()V
 ? ? ? 4: return
?
 ?private void printOut();
 ? ?Code:
 ? ? ? 0: getstatic ? ? #3 ? ? ? ? ? ? ? ? ?// Field java/lang/System.out:Ljava/io/PrintStream;
 ? ? ? 3: ldc ? ? ? ? ? #4 ? ? ? ? ? ? ? ? ?// String AAA
 ? ? ? 5: invokevirtual #5 ? ? ? ? ? ? ? ? ?// Method java/io/PrintStream.println:(Ljava/lang/String;)V
 ? ? ? 8: return
?
 ?static void access$000(java.OutterJava);
 ? ?Code:
 ? ? ? 0: aload_0
 ? ? ? 1: invokespecial #1 ? ? ? ? ? ? ? ? ?// Method printOut:()V
 ? ? ? 4: return
}

從反編譯出來的內(nèi)容來看,多了一個(gè)靜態(tài)的access$000(OutterJava)方法,它的內(nèi)部調(diào)用了 printOut()

InnJava.class

Compiled from "OutterJava.java"
class java.OutterJava$InnJava {
 ?final java.OutterJava this$0;
?
 ?java.OutterJava$InnJava(java.OutterJava);
 ? ?Code:
 ? ? ? 0: aload_0
 ? ? ? 1: aload_1
 ? ? ? 2: putfield ? ? ?#1 ? ? ? ? ? ? ? ? ?// Field this$0:Ljava/OutterJava;
 ? ? ? 5: aload_0
 ? ? ? 6: invokespecial #2 ? ? ? ? ? ? ? ? ?// Method java/lang/Object."<init>":()V
 ? ? ? 9: return
?
 ?public void printInn2();
 ? ?Code:
 ? ? ? 0: aload_0
 ? ? ? 1: getfield ? ? ?#1 ? ? ? ? ? ? ? ? ?// Field this$0:Ljava/OutterJava;
 ? ? ? 4: invokestatic ?#3 ? ? ? ? ? ? ? ? ?// Method java/OutterJava.access$000:(Ljava/OutterJava;)V
 ? ? ? 7: return
}

在 InnJava 的字節(jié)碼反編譯出來的內(nèi)容中,主要有兩個(gè)點(diǎn)需要注意:

  • 構(gòu)造方法需要一個(gè)外部類參數(shù),并把這個(gè)外部類實(shí)例保存到了this$0中。
  • 調(diào)用外部類私有方法,實(shí)際上是調(diào)用了OutterJava.access$000方法。

小結(jié):

在 Java 中,內(nèi)部類與外部類的關(guān)系是:

  • 內(nèi)部類持有外部類的引用,作為內(nèi)部構(gòu)造參數(shù)傳入外部類實(shí)例,并保存到了內(nèi)部類的屬性this$0中。
  • 內(nèi)部類調(diào)用外部類的私有方法,實(shí)際上是外部類生成了內(nèi)部實(shí)際調(diào)用私有方法的靜態(tài)方法access$000,內(nèi)部類可以通過這個(gè)靜態(tài)方法訪問到外部類中的私有方法。

Kotlin 中的內(nèi)部類

同樣的 Java 代碼,用 Kotlin 實(shí)現(xiàn):

class Outter {
 ? ?private fun printOut() {
 ? ? ? ?println("Out")
 ?  }
?
 ? ?inner class Inner {
 ? ? ? ?fun printIn() {
 ? ? ? ? ? ?printOut()
 ? ? ?  }
 ?  }
}

這里如果不加inner關(guān)鍵字,printIn()內(nèi)的printOut()會(huì)報(bào)錯(cuò)Unresolved reference: printOut 。

不加inner關(guān)鍵字,反編譯后的字節(jié)碼:

public final class java/Outter$Inner {
  // ...
  public <init>()V
 ? L0
 ?  LINENUMBER 8 L0
 ?  ALOAD 0
 ?  INVOKESPECIAL java/lang/Object.<init> ()V
 ?  RETURN
 ? L1
 ?  LOCALVARIABLE this Ljava/Outter$Inner; L0 L1 0
 ?  MAXSTACK = 1
 ?  MAXLOCALS = 1
  // ...
}

不加inner關(guān)鍵字,內(nèi)部類的構(gòu)造方法是沒有外部類實(shí)例參數(shù)的。如果加上inner,就和 Java 一樣:

  // 加上了 inner 的構(gòu)造方法
  public <init>(Ljava/Outter;)V
 ? L0
 ?  LINENUMBER 8 L0
 ?  ALOAD 0
 ?  ALOAD 1
 ?  PUTFIELD java/Outter$Inner.this$0 : Ljava/Outter;
 ?  ALOAD 0
 ?  INVOKESPECIAL java/lang/Object.<init> ()V
 ?  RETURN
 ? L1
 ?  LOCALVARIABLE this Ljava/Outter$Inner; L0 L1 0
 ?  LOCALVARIABLE this$0 Ljava/Outter; L0 L1 1
 ?  MAXSTACK = 2
 ?  MAXLOCALS = 2

而內(nèi)部類對(duì)于外部類私有方法的訪問,也是通過靜態(tài)方法access$XXX來實(shí)現(xiàn)的:

  public final static synthetic access$printOut(Ljava/Outter;)V
 ? L0
 ?  LINENUMBER 3 L0
 ?  ALOAD 0
 ?  INVOKESPECIAL java/Outter.printOut ()V
 ?  RETURN
 ? L1
 ?  LOCALVARIABLE $this Ljava/Outter; L0 L1 0
 ?  MAXSTACK = 1
 ?  MAXLOCALS = 1

總結(jié)

在 Kotlin 中,內(nèi)部類持有外部類引用和通過靜態(tài)方法訪問外部類私有方法都是與 Java 一樣的。唯一的不同是,Kotlin 中需要使用 inner關(guān)鍵字修飾內(nèi)部類,才能訪問外部類中的內(nèi)容。實(shí)質(zhì)是inner關(guān)鍵字會(huì)控制內(nèi)部類的構(gòu)造方法是否帶有外部類實(shí)例參數(shù)。

到此這篇關(guān)于Java中的Kotlin 內(nèi)部類原理的文章就介紹到這了,更多相關(guān)Java Kotlin 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java重寫(@Override)介紹以及舉例說明

    java重寫(@Override)介紹以及舉例說明

    這篇文章主要給大家介紹了關(guān)于java重寫(@Override)介紹以及舉例說明的相關(guān)資料,在Java中@Override注解用于表示方法重寫(覆蓋)了父類的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • springMVC?@RestControllerAdvice注解使用方式

    springMVC?@RestControllerAdvice注解使用方式

    這篇文章主要介紹了springMVC?@RestControllerAdvice注解使用方式,下面通過一個(gè)簡(jiǎn)單的示例,演示如何使用?@RestControllerAdvice,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Maven搭建springboot項(xiàng)目的方法步驟

    Maven搭建springboot項(xiàng)目的方法步驟

    這篇文章主要介紹了Maven搭建springboot項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Java實(shí)現(xiàn)對(duì)稱加密DES和AES的示例代碼

    Java實(shí)現(xiàn)對(duì)稱加密DES和AES的示例代碼

    這篇文章主要介紹了如何使用Java實(shí)現(xiàn)采用對(duì)稱密碼算法的應(yīng)用軟件,所用算法包括DES算法和AES算法,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-04-04
  • SpringCloud @FeignClient參數(shù)的用法解析

    SpringCloud @FeignClient參數(shù)的用法解析

    這篇文章主要介紹了SpringCloud @FeignClient參數(shù)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Mybatis 中的<![CDATA[ ]]>淺析

    Mybatis 中的<![CDATA[ ]]>淺析

    本文給大家解析使用<![CDATA[ ]]>解決xml文件不被轉(zhuǎn)義的問題, 對(duì)mybatis 中的<![CDATA[ ]]>相關(guān)知識(shí)感興趣的朋友一起看看吧
    2017-09-09
  • Java 通過位運(yùn)算求一個(gè)集合的所有子集方法

    Java 通過位運(yùn)算求一個(gè)集合的所有子集方法

    下面小編就為大家?guī)硪黄狫ava 通過位運(yùn)算求一個(gè)集合的所有子集方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • java通過url讀取遠(yuǎn)程數(shù)據(jù)并保持到本地的實(shí)例代碼

    java通過url讀取遠(yuǎn)程數(shù)據(jù)并保持到本地的實(shí)例代碼

    本文通過實(shí)例代碼給大家介紹了java通過url讀取遠(yuǎn)程數(shù)據(jù)并保持到本地的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • SpringBoot連接Hive實(shí)現(xiàn)自助取數(shù)的示例

    SpringBoot連接Hive實(shí)現(xiàn)自助取數(shù)的示例

    這篇文章主要介紹了SpringBoot連接Hive實(shí)現(xiàn)自助取數(shù)的示例,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-12-12
  • Springboot使用RabbitMQ實(shí)現(xiàn)關(guān)閉超時(shí)訂單(示例詳解)

    Springboot使用RabbitMQ實(shí)現(xiàn)關(guān)閉超時(shí)訂單(示例詳解)

    介紹了如何在Spring Boot項(xiàng)目中使用RabbitMQ實(shí)現(xiàn)訂單的延時(shí)處理和超時(shí)關(guān)閉,通過配置RabbitMQ的交換機(jī)、隊(duì)列和綁定關(guān)系,以及編寫監(jiān)聽方法,實(shí)現(xiàn)了訂單數(shù)據(jù)的發(fā)送和延時(shí)消費(fèi),感興趣的朋友一起看看吧
    2025-01-01

最新評(píng)論

吐鲁番市| 宣化县| 富顺县| 阜城县| 静安区| 长宁区| 松阳县| 永泰县| 新泰市| 海盐县| 建德市| 铁力市| 乌兰浩特市| 繁峙县| 张家口市| 偏关县| 宜川县| 江达县| 年辖:市辖区| 裕民县| 开平市| 洮南市| 永胜县| 麻城市| 昌黎县| 东安县| 行唐县| 枣阳市| 格尔木市| 崇义县| 青龙| 湘乡市| 云林县| 偃师市| 南投市| 东海县| 深圳市| 富平县| 泰安市| 清新县| 威信县|