国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java枚舉的values方法是拷貝操作,你知道嗎?

li21 / 2415人閱讀

摘要:還為該枚舉類生成了一個(gè)方法,這個(gè)方法就是本文要講的方法,我們來具體看下其操作獲取靜態(tài)變量。

Java中的枚舉類是我們平時(shí)寫代碼時(shí)經(jīng)常會用到的一個(gè)類型,在我們創(chuàng)建枚舉類之后,Java會默認(rèn)在該類中為我們生成values、valueof 等方法。

但你知道嗎,values方法可是個(gè)拷貝操作。

寫個(gè)例子驗(yàn)證下:

$ cat Type.java
public enum Type {
  T1,
  T2,
  ;
  public static void main(String[] args) {
    System.out.println(Type.values() == Type.values());
  }
}
$ java Type.java
false

如果values方法不是拷貝操作的話,那兩次方法調(diào)用返回的對象應(yīng)該是一樣的,但結(jié)果卻輸出了false,可見該方法應(yīng)該就是拷貝操作。

有同學(xué)可能會發(fā)現(xiàn),我們沒編譯,直接執(zhí)行的java Type.java,而且還成功了,java不是要先編譯后才能執(zhí)行嗎?

有關(guān)這個(gè)問題,可以看我上一篇文章:Java也可以不用編譯直接執(zhí)行了?

繼續(xù)回到本文的話題。

上文我們說到,values方法是拷貝操作,但這只是我們的猜測,有什么證據(jù)能明確證明嗎?

我們看下上面類對應(yīng)的字節(jié)碼:

$ javac Type.java
$ javap -c -p Type
Compiled from "Type.java"
public final class Type extends java.lang.Enum {
  public static final Type T1;

  public static final Type T2;

  private static final Type[] $VALUES;

  public static Type[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LType;
       3: invokevirtual #2                  // Method "[LType;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[LType;"
       9: areturn
  
  # 省略無關(guān)字節(jié)碼 #
  
  static {};
    Code:
       0: new           #4                  // class Type
       3: dup
       4: ldc           #10                 // String T1
       6: iconst_0
       7: invokespecial #11                 // Method "":(Ljava/lang/String;I)V
      10: putstatic     #12                 // Field T1:LType;
      13: new           #4                  // class Type
      16: dup
      17: ldc           #13                 // String T2
      19: iconst_1
      20: invokespecial #11                 // Method "":(Ljava/lang/String;I)V
      23: putstatic     #14                 // Field T2:LType;
      26: iconst_2
      27: anewarray     #4                  // class Type
      30: dup
      31: iconst_0
      32: getstatic     #12                 // Field T1:LType;
      35: aastore
      36: dup
      37: iconst_1
      38: getstatic     #14                 // Field T2:LType;
      41: aastore
      42: putstatic     #1                  // Field $VALUES:[LType;
      45: return
}

由字節(jié)碼可見,javac自動為我們生成了很多東西,其中就包括一個(gè)static代碼塊。

該代碼塊的大致邏輯是:

創(chuàng)建類型為Type的實(shí)例,new Type("T1", 0),賦值給靜態(tài)變量T1。

創(chuàng)建類型為Type的實(shí)例,new Type("T2", 1),賦值給靜態(tài)變量T2。

創(chuàng)建類型為Type數(shù)組,并將靜態(tài)變量T1、T2依次放到數(shù)組中,然后再將該數(shù)組賦值給靜態(tài)變量 $VALUES。

javac還為該枚舉類生成了一個(gè)values方法,這個(gè)values方法就是本文要講的方法,我們來具體看下其操作:

獲取靜態(tài)變量$VALUES。

調(diào)用$VALUES的clone方法。

將clone方法返回的對象強(qiáng)轉(zhuǎn)成Type數(shù)組。

返回該數(shù)組。

由此我們可以看到,values方法的確是拷貝操作。

上文我們說到,values等方法是javac動態(tài)生成的,是這樣嗎?

我們還是通過源碼來確認(rèn)下這個(gè)疑問。

// com.sun.tools.javac.comp.TypeEnter.MembersPhase
private void addEnumMembers(JCClassDecl tree, Env env) {
    ...
    // public static T[] values() { return ???; }
    JCMethodDecl values = make.
        MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
                  names.values,
                  valuesType,
                  List.nil(),
                  List.nil(),
                  List.nil(), // thrown
                  null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
                  null);
    ...
}

該方法向Enum類里添加了values方法,但還沒有方法體。

// com.sun.tools.javac.comp.Lower
private void visitEnumDef(JCClassDecl tree) {
    ...
    Symbol valuesSym = lookupMethod(tree.pos(), names.values,
                                    tree.type, List.nil());
    ...
    if (useClone()) {
        // return (T[]) $VALUES.clone();
        JCTypeCast valuesResult =
            make.TypeCast(valuesSym.type.getReturnType(),
                          make.App(make.Select(make.Ident(valuesVar),
                                               syms.arrayCloneMethod)));
        valuesBody = List.of(make.Return(valuesResult));
    } else {
        // template: T[] $result = new T[$values.length];
        ...
        // template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length);
        ...
        // template: return $result;
        ...
    }
    ...
}

該方法向Enum類的values方法里添加了方法體。

怎么樣,現(xiàn)在一切都非常明朗了吧,values方法會拷貝數(shù)組$VALUES的值,然后返回給我們。

希望能對大家有所幫助。

完。

更多原創(chuàng)文章,請關(guān)注我微信公眾號:

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/76128.html

相關(guān)文章

  • ES6時(shí)代,會克隆對象

    摘要:原文你真的會克隆對象嗎開始之前在開始聊克隆之前,我們還是先來看看數(shù)據(jù)類型。值通過函數(shù)生成,是獨(dú)一無二的。同時(shí),中規(guī)定了對象的屬性名有兩種類型,一種是字符串,另一種就是類型。返回一個(gè)數(shù)組,包含對象自身的所有屬性的鍵名。 原文:你真的會克隆對象嗎 開始之前 在開始聊克隆之前,我們還是先來看看js數(shù)據(jù)類型。js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型。 基本數(shù)據(jù)類型:Number、Bool...

    xiaokai 評論0 收藏0
  • JavaScript 深拷貝性能分析

    摘要:它接受任意數(shù)量的源對象,枚舉它們的所有屬性并分配給。所以現(xiàn)在怎么辦有幾種方法可以創(chuàng)建一個(gè)對象的深拷貝。為了防止發(fā)生任何意外,請使用而不是。我想測量哪種方法是最高性能的。圖表以下是,和中不同技術(shù)的性能。 原文:Deep-copying in JavaScript - DasSur.ma 如何在 JavaScript 中拷貝一個(gè)對象?對于這個(gè)很簡單的問題,但是答案卻不簡單。 引用傳值 在...

    MyFaith 評論0 收藏0
  • 聽飛狐聊JavaScript設(shè)計(jì)模式系列04

    摘要:介一回,偶們來聊一下用中的類,有些盆友可能用過或者的,知道語法糖,可是在中并沒有,中需要用到構(gòu)造函數(shù)來模擬類。而且要注意一點(diǎn),構(gòu)造函數(shù)沒有語句,是自動返回。 本回內(nèi)容介紹 上一回聊到JS的Function類型,做了柯里化,數(shù)組去重,排序的題。 介一回,偶們來聊一下用JS中的類,有些盆友可能用過ES6或者TypeScript的,知道Class語法糖,可是在ES5中并沒有,ES5中需要用到...

    kgbook 評論0 收藏0
  • Java 面試準(zhǔn)備

    摘要:網(wǎng)站的面試專題學(xué)習(xí)筆記非可變性和對象引用輸出為,前后皆有空格。假定棧空間足夠的話,盡管遞歸調(diào)用比較難以調(diào)試,在語言中實(shí)現(xiàn)遞歸調(diào)用也是完全可行的。棧遵守規(guī)則,因此遞歸調(diào)用方法能夠記住調(diào)用者并且知道此輪執(zhí)行結(jié)束之返回至當(dāng)初的被調(diào)用位置。 ImportNew 網(wǎng)站的Java面試專題學(xué)習(xí)筆記 1. 非可變性和對象引用 String s = Hello ; s += World ; s.tr...

    chanjarster 評論0 收藏0
  • 【進(jìn)階4-2期】Object.assign 原理及其實(shí)現(xiàn)

    摘要:木易楊注意原始類型被包裝為對象木易楊原始類型會被包裝,和會被忽略。木易楊原因在于時(shí),其屬性描述符為不可寫,即。木易楊解決方法也很簡單,使用我們在進(jìn)階期中介紹的就可以了,使用如下。 引言 上篇文章介紹了賦值、淺拷貝和深拷貝,其中介紹了很多賦值和淺拷貝的相關(guān)知識以及兩者區(qū)別,限于篇幅只介紹了一種常用深拷貝方案。 本篇文章會先介紹淺拷貝 Object.assign 的實(shí)現(xiàn)原理,然后帶你手動實(shí)...

    layman 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<