欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

Java 中的內(nèi)部類

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

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

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

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

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

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

OutterJava.class

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

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)容來看,多了一個靜態(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òu)造方法需要一個外部類參數(shù),并把這個外部類實例保存到了this$0中。
  • 調(diào)用外部類私有方法,實際上是調(diào)用了OutterJava.access$000方法。

小結(jié):

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

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

Kotlin 中的內(nèi)部類

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

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

這里如果不加inner關鍵字,printIn()內(nèi)的printOut()會報錯Unresolved reference: printOut 。

不加inner關鍵字,反編譯后的字節(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關鍵字,內(nèi)部類的構(gòu)造方法是沒有外部類實例參數(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)部類對于外部類私有方法的訪問,也是通過靜態(tài)方法access$XXX來實現(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關鍵字修飾內(nèi)部類,才能訪問外部類中的內(nèi)容。實質(zhì)是inner關鍵字會控制內(nèi)部類的構(gòu)造方法是否帶有外部類實例參數(shù)。

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

相關文章

  • JNDI具體用法詳解

    JNDI具體用法詳解

    JNDI是java命名和目錄接口,本文主要介紹了JNDI具體用法詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java線程的五種狀態(tài)介紹

    Java線程的五種狀態(tài)介紹

    本文主要為大家詳細介紹一下Java實現(xiàn)線程創(chuàng)建的五種寫法,文中的示例代碼講解詳細,對我們學習有一定的幫助,感興趣的可以跟隨小編學習一下
    2022-08-08
  • IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解

    IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解

    查看JAVA字節(jié)碼有兩種方式一種是使用 jdk命令 javap,還有一種就是 使用 插件了,今天給大家分享IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • MyBatis配置與CRUD超詳細講解

    MyBatis配置與CRUD超詳細講解

    這篇文章主要介紹了MyBatis配置與CRUD,CRUD是指在做計算處理時的增加(Create)、讀取(Read)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫。CRUD主要被用在描述軟件系統(tǒng)中數(shù)據(jù)庫或者持久層的基本操作功能
    2023-02-02
  • Mybatis中注入執(zhí)行sql查詢、更新、新增及建表語句案例代碼

    Mybatis中注入執(zhí)行sql查詢、更新、新增及建表語句案例代碼

    這篇文章主要介紹了Mybatis中注入執(zhí)行sql查詢、更新、新增以及建表語句,主要說明一個另類的操作,注入sql,并使用mybatis執(zhí)行,結(jié)合案例代碼詳解講解,需要的朋友可以參考下
    2023-02-02
  • springboot的logging.group日志分組方法源碼流程解析

    springboot的logging.group日志分組方法源碼流程解析

    這篇文章主要為大家介紹了springboot的logging.group日志分組方法源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Spring MVC---數(shù)據(jù)綁定和表單標簽詳解

    Spring MVC---數(shù)據(jù)綁定和表單標簽詳解

    本篇文章主要介紹了Spring MVC---數(shù)據(jù)綁定和表單標簽詳解,具有一定的參考價值,有興趣的可以了解一下。
    2017-01-01
  • 老生常談spring boot 1.5.4 日志管理(必看篇)

    老生常談spring boot 1.5.4 日志管理(必看篇)

    下面小編就為大家?guī)硪黄仙U剆pring boot 1.5.4 日志管理(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • JAVA調(diào)用JavaScript的方法示例

    JAVA調(diào)用JavaScript的方法示例

    本文主要介紹了JAVA調(diào)用JavaScript的方法示例,主要介紹了兩種方式,一種是使用Java的ScriptEngine接口,另一種是使用Java的URLConnection類來獲取JS文件,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Java中的CompletableFuture使用解析

    Java中的CompletableFuture使用解析

    這篇文章主要介紹了Java中的CompletableFuture使用解析,為什么CompletableFuture要定制化線程池,因為默認的線程池是ForkJoinPool,這個線程池的最大線程數(shù)默認是你的電腦的線程數(shù)數(shù)減1,假如我線程電腦是4核8線程的,ForkJoinPool的最大線程數(shù)就是7,需要的朋友可以參考下
    2024-01-01

最新評論