Scala對象

@雲南犀鳥科技有限公司java

#對象 在搞對象以前,咱們還須要先把啥是對象搞清楚,在Scala裏面,使用object關鍵字,替代class關鍵字的類就叫作對象,不過,它有它本身的限制和特色。app

object Simple {
	
}

咱們編譯 scalac Simple.scala,會獲得Simple.class以及Simple$.class,意思是說scalac會把object生成兩個類麼?咱們先來看Simple.class函數

javap -c -v -private Simple學習

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 323 bytes
  MD5 checksum 7c951e41aaf72e2e0540dc79a9261584
  Compiled from "Simple.scala"
public final class Simple
  SourceFile: "Simple.scala"
  RuntimeVisibleAnnotations:
    0: #6(#7=s#8)
    ScalaSig: length = 0x3
     05 00 00
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple
   #2 = Class              #1             //  Simple
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               Lscala/reflect/ScalaSignature;
   #7 = Utf8               bytes
   #8 = Utf8               M9Q!\t\taaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd-\t1I\=SKDQ!EI\taP5oSRtD#A
   #9 = Utf8               SourceFile
  #10 = Utf8               RuntimeVisibleAnnotations
  #11 = Utf8               ScalaSig
{
}

Simple類變成final的了,其餘的咱們啥都沒看到,也就是說此類是不能被擴展的,那麼**javap -c -v -private Simple$**呢?this

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
  Last modified 2016-5-13; size 374 bytes
  MD5 checksum 1f50323fc335e68561440a8e37e8d0da
  Compiled from "Simple.scala"
public final class Simple$
  SourceFile: "Simple.scala"
    ScalaInlineInfo: length = 0x9
     01 01 00 01 00 0A 00 09 01
    Scala: length = 0x0

  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple$
   #2 = Class              #1             //  Simple$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               MODULE$
   #7 = Utf8               LSimple$;
   #8 = Utf8               <clinit>
   #9 = Utf8               ()V
  #10 = Utf8               <init>
  #11 = NameAndType        #10:#9         //  "<init>":()V
  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
  #13 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
  #14 = NameAndType        #6:#7          //  MODULE$:LSimple$;
  #15 = Fieldref           #2.#14         //  Simple$.MODULE$:LSimple$;
  #16 = Utf8               this
  #17 = Utf8               Code
  #18 = Utf8               LocalVariableTable
  #19 = Utf8               LineNumberTable
  #20 = Utf8               SourceFile
  #21 = Utf8               ScalaInlineInfo
  #22 = Utf8               Scala
{
  public static final Simple$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL


  public static {};
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class Simple$
         3: invokespecial #12                 // Method "<init>":()V
         6: return

  private Simple$();
    flags: ACC_PRIVATE
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #13                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #15                 // Field MODULE$:LSimple$;
         8: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       9     0  this   LSimple$;
      LineNumberTable:
        line 3: 0
}

重點看,public static final Simple$ MODULE$; 以及 private Simple$(); public static {};.net

首先,Simple$的構造器是私有的,可是Simple$提供了一個靜態的公開的常量MODULE$,這是否是和咱們的單列模式很像呢?scala

但是,咱們的Simple類和Simple$之間並無什麼聯繫呀?爲何呢?由於咱們在Simple類中啥都沒有作,如今讓咱們來作點事情。3d

object Simple {
    def say(){

    }
}

咱們反編譯來看看代理

javap -c -v -private Simple
Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 464 bytes
  MD5 checksum 8fe08ac15b83be21380cab9bfb5d2d2c
  Compiled from "Simple.scala"
public final class Simple
  SourceFile: "Simple.scala"
  RuntimeVisibleAnnotations:
    0: #6(#7=s#8)
    ScalaSig: length = 0x3
     05 00 00
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple
   #2 = Class              #1             //  Simple
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               Lscala/reflect/ScalaSignature;
   #7 = Utf8               bytes
   #8 = Utf8               e9Q!\t\taaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd-\t1I\=SKDQ!EI\taP5oSRtD#A\t
                             Q9AA
                                 M
                                  F!\tYq#\t!QK\5u
   #9 = Utf8               say
  #10 = Utf8               ()V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  say:()V
  #18 = Methodref          #12.#17        //  Simple$.say:()V
  #19 = Utf8               Code
  #20 = Utf8               SourceFile
  #21 = Utf8               RuntimeVisibleAnnotations
  #22 = Utf8               ScalaSig
{
  public static void say();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #18                 // Method Simple$.say:()V
         6: return
}

咱們看到,Scala對象Simple中的say方法變成了靜態的了,咱們如今用僞代碼來看看say方法到底幹了什麼。code

public static void say(){
	Simple$ Simple$.MODULE$;
	Simple$.say();
}

做用很明顯了,就是去調用Simple$的say方法,先來看看此時的Simple$

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
  Last modified 2016-5-13; size 442 bytes
  MD5 checksum 4fa739988d0dadd6cba59fd9101ef98c
  Compiled from "Simple.scala"
public final class Simple$
  SourceFile: "Simple.scala"
    ScalaInlineInfo: length = 0xE
     01 01 00 02 00 0A 00 09 01 00 0D 00 09 01
    Scala: length = 0x0

  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple$
   #2 = Class              #1             //  Simple$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               MODULE$
   #7 = Utf8               LSimple$;
   #8 = Utf8               <clinit>
   #9 = Utf8               ()V
  #10 = Utf8               <init>
  #11 = NameAndType        #10:#9         //  "<init>":()V
  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
  #13 = Utf8               say
  #14 = Utf8               this
  #15 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
  #16 = NameAndType        #6:#7          //  MODULE$:LSimple$;
  #17 = Fieldref           #2.#16         //  Simple$.MODULE$:LSimple$;
  #18 = Utf8               Code
  #19 = Utf8               LocalVariableTable
  #20 = Utf8               LineNumberTable
  #21 = Utf8               SourceFile
  #22 = Utf8               ScalaInlineInfo
  #23 = Utf8               Scala
{
  public static final Simple$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL


  public static {};
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class Simple$
         3: invokespecial #12                 // Method "<init>":()V
         6: return

  public void say();
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       1     0  this   LSimple$;
      LineNumberTable:
        line 2: 0

  private Simple$();
    flags: ACC_PRIVATE
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #15                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #17                 // Field MODULE$:LSimple$;
         8: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       9     0  this   LSimple$;
      LineNumberTable:
        line 5: 0
}

咱們能夠看到,在Simple$類中存在一個靜態屬性MODULE$,而這個屬性的類型是Simple$,同時,在Simple$類中存在一個pulic的方法say.

因此,從上面的狀況來看,如今的Simple對象反而就像是Simple$的一個代理了,真正幹活的是Simple$類。

其實咱們能夠進行類推,只要把上述的say方法的簽名換成def main(args:Array[String]) 就能夠獲得咱們的程序入口了。

object Simple {
def main(args:Array[String]){

    }
}

javap -c -v -private Simple

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 561 bytes
  MD5 checksum e024e8adf8cb3a03df9e342eb7bdd43e
  Compiled from "Simple.scala"
h\t\tC final class Simple
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  main:([Ljava/lang/String;)V
  #18 = Methodref          #12.#17        //  Simple$.main:([Ljava/lang/String;)V  #2 = Class              #1             //  Simple
  #19 = Utf8               Code/lang/Object
  #20 = Utf8               SourceFile     //  java/lang/Object
  #21 = Utf8               RuntimeVisibleAnnotations
  #22 = Utf8               ScalaSigeflect/ScalaSignature;
{  #7 = Utf8               bytes
  public static void main(java.lang.String[]);q*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd    flags: ACC_PUBLIC, ACC_STATIC
    Code:                   Q9AA
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0                 -e\"aC
         4: invokevirtual #18                 // Method Simple$.main:([Ljava/lang/String;)VeKL!a\t\rM#(/
         7: return
}

javap -c -v -private Simple$

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
	  Last modified 2016-5-13; size 507 bytes
	  MD5 checksum df7c21289480ea8adbbb7d405ffda09f
	  Compiled from "Simple.scala"
	public final class Simple$
	  SourceFile: "Simple.scala"
	    ScalaInlineInfo: length = 0xE
	     01 01 00 02 00 0A 00 09 01 00 0D 00 0E 01
	    Scala: length = 0x0
	
	  minor version: 0
	  major version: 50
	  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
	Constant pool:
	   #1 = Utf8               Simple$
	   #2 = Class              #1             //  Simple$
	   #3 = Utf8               java/lang/Object
	   #4 = Class              #3             //  java/lang/Object
	   #5 = Utf8               Simple.scala
	   #6 = Utf8               MODULE$
	   #7 = Utf8               LSimple$;
	   #8 = Utf8               <clinit>
	   #9 = Utf8               ()V
	  #10 = Utf8               <init>
	  #11 = NameAndType        #10:#9         //  "<init>":()V
	  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
	  #13 = Utf8               main
	  #14 = Utf8               ([Ljava/lang/String;)V
	  #15 = Utf8               this
	  #16 = Utf8               args
	  #17 = Utf8               [Ljava/lang/String;
	  #18 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
	  #19 = NameAndType        #6:#7          //  MODULE$:LSimple$;
	  #20 = Fieldref           #2.#19         //  Simple$.MODULE$:LSimple$;
	  #21 = Utf8               Code
	  #22 = Utf8               LocalVariableTable
	  #23 = Utf8               LineNumberTable
	  #24 = Utf8               SourceFile
	  #25 = Utf8               ScalaInlineInfo
	  #26 = Utf8               Scala
	{
	  public static final Simple$ MODULE$;
	    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
	
	
	  public static {};
	    flags: ACC_PUBLIC, ACC_STATIC
	    Code:
	      stack=1, locals=0, args_size=0
	         0: new           #2                  // class Simple$
	         3: invokespecial #12                 // Method "<init>":()V
	         6: return
	
	  public void main(java.lang.String[]);
	    flags: ACC_PUBLIC
	    Code:
	      stack=0, locals=2, args_size=2
	         0: return
	      LocalVariableTable:
	        Start  Length  Slot  Name   Signature
	               0       1     0  this   LSimple$;
	               0       1     1  args   [Ljava/lang/String;
	      LineNumberTable:
	        line 2: 0
	
	  private Simple$();
	    flags: ACC_PRIVATE
	    Code:
	      stack=1, locals=1, args_size=1
	         0: aload_0
	         1: invokespecial #18                 // Method java/lang/Object."<init>":()V
	         4: aload_0
	         5: putstatic     #20                 // Field MODULE$:LSimple$;
	         8: return
	      LocalVariableTable:
	        Start  Length  Slot  Name   Signature
	               0       9     0  this   LSimple$;
	      LineNumberTable:
	        line 5: 0
}

到這裏,咱們能夠稍微總結一下,object裏面的方法被編譯成了靜態的方法,同時,真正幹活的是object對象後面的那個家了$的類,其實咱們能夠把這個加了$的類佳做虛構類。

那問題來了,object裏面的屬性又是怎麼回事呢?

object Simple {
val name ="Yanne"
def main(args:Array[String]){

 }
}

javap -c -v -private Simple

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
\r2CA%\t)CBV]&\"B!AB1sON2aC,\tQCBABeJytes
  MD5 checksum 8818d17f3a9dd9e42dda2b-_91\"L]1\ta:fI4BA1\tqC
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  main:([Ljava/lang/String;)V
  #18 = Methodref          #12.#17        //  Simple$.main:([Ljava/lang/String;)Vonstant pool:
  #19 = Utf8               namele
  #20 = Utf8               ()Ljava/lang/String;imple
  #21 = NameAndType        #19:#20        //  name:()Ljava/lang/String;
  #22 = Methodref          #12.#21        //  Simple$.name:()Ljava/lang/String;
  #23 = Utf8               Codele.scala
  #24 = Utf8               SourceFilelect/ScalaSignature;
  #25 = Utf8               RuntimeVisibleAnnotations
  #26 = Utf8               ScalaSigaaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtG{-\t1I\=SKDQ!EI\taP5oSRtD#A\tQ9!!C+!a.Y7f+1CA
  public static void main(java.lang.String[]);\"BA\raM\4
    flags: ACC_PUBLIC, ACC_STATIC                       m\tAA[1wC&Q'RN\4\t\r}9!q    Code:#i-
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #18                 // Method Simple$.main:([Ljava/lang/String;)V
         7: return

  public static java.lang.String name();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #22                 // Method Simple$.name:()Ljava/lang/String;
         6: areturn
}

從上面編譯結果來看,對應的屬性name已經被編譯成了靜態方法name(),咱們叫作getter,並且name方法執行的內容是Simple$.MODULE$.name()方法,那麼,虛構類中的狀況是怎樣的呢?

javap -c -v -private Simple$

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
  Last modified 2016-5-13; size 663 bytes
  MD5 checksum 88c152f50df4f21b0519526a8f9b55db
  Compiled from "Simple.scala"
public final class Simple$
  SourceFile: "Simple.scala"
    ScalaInlineInfo: length = 0x13
     01 01 00 03 00 0A 00 09 01 00 13 00 14 01 00 0D
     00 0F 01
    Scala: length = 0x0

  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple$
   #2 = Class              #1             //  Simple$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               MODULE$
   #7 = Utf8               LSimple$;
   #8 = Utf8               <clinit>
   #9 = Utf8               ()V
  #10 = Utf8               <init>
  #11 = NameAndType        #10:#9         //  "<init>":()V
  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
  #13 = Utf8               name
  #14 = Utf8               Ljava/lang/String;
  #15 = Utf8               ()Ljava/lang/String;
  #16 = NameAndType        #13:#14        //  name:Ljava/lang/String;
  #17 = Fieldref           #2.#16         //  Simple$.name:Ljava/lang/String;
  #18 = Utf8               this
  #19 = Utf8               main
  #20 = Utf8               ([Ljava/lang/String;)V
  #21 = Utf8               args
  #22 = Utf8               [Ljava/lang/String;
  #23 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
  #24 = NameAndType        #6:#7          //  MODULE$:LSimple$;
  #25 = Fieldref           #2.#24         //  Simple$.MODULE$:LSimple$;
  #26 = Utf8               Yanne
  #27 = String             #26            //  Yanne
  #28 = Utf8               Code
  #29 = Utf8               LocalVariableTable
  #30 = Utf8               LineNumberTable
  #31 = Utf8               SourceFile
  #32 = Utf8               ScalaInlineInfo
  #33 = Utf8               Scala
{
  public static final Simple$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL


  private final java.lang.String name;
    flags: ACC_PRIVATE, ACC_FINAL


  public static {};
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class Simple$
         3: invokespecial #12                 // Method "<init>":()V
         6: return

  public java.lang.String name();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #17                 // Field name:Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple$;
      LineNumberTable:
        line 2: 0

  public void main(java.lang.String[]);
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=2, args_size=2
         0: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       1     0  this   LSimple$;
               0       1     1  args   [Ljava/lang/String;
      LineNumberTable:
        line 3: 0

  private Simple$();
    flags: ACC_PRIVATE
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #23                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #25                 // Field MODULE$:LSimple$;
         8: aload_0
         9: ldc           #27                 // String Yanne
        11: putfield      #17                 // Field name:Ljava/lang/String;
        14: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      15     0  this   LSimple$;
      LineNumberTable:
        line 6: 0
        line 2: 8
}

對應的val 類型屬性name在虛構類中變成了private final類型的,同時,在虛構類中也會生成同名的public函數。其實,這就是一個getter。

那,若是是var類型的屬性呢?

object Simple {
    var name ="Yanne"
    def main(args:Array[String]){

    }
}

javap -c -v -private Simple

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 827 bytes
  MD5 checksum 372cc57ba09d21cb6e4b7cbddd1e10d3
  Compiled from "Simple.scala"
public final class Simple
  SourceFile: "Simple.scala"
  RuntimeVisibleAnnotations:
    0: #6(#7=s#8)
    ScalaSig: length = 0x3
     05 00 00
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple
   #2 = Class              #1             //  Simple
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               Lscala/reflect/ScalaSignature;
   #7 = Utf8               bytes
   #8 = Utf8               Y:Q!\t\taaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd-\t1I\=SKDQ!EI\taP5oSRtD#A\tQ9!C+!a.Y7f+1CA
                                            A\"BA\raM\4
                                                       m\tAA[1wC&Q'RN\4\t}9!CAAa.Y7f?*\"IA1BIG1A!8ji\"9QEHA1a=%c!1qeQ!\nY\tQA\1nKBQ!K)\nA!\1j]Re
                                                                Y!\r!LCJ<7E
                                                                           ]AJ!a

(/Y=E\"dBA3\tD\"Qe$WMZ;UR!a\r
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  main:([Ljava/lang/String;)V
  #18 = Methodref          #12.#17        //  Simple$.main:([Ljava/lang/String;)V
  #19 = Utf8               name_$eq
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = NameAndType        #19:#20        //  name_$eq:(Ljava/lang/String;)V
  #22 = Methodref          #12.#21        //  Simple$.name_$eq:(Ljava/lang/String;)V
  #23 = Utf8               name
  #24 = Utf8               ()Ljava/lang/String;
  #25 = NameAndType        #23:#24        //  name:()Ljava/lang/String;
  #26 = Methodref          #12.#25        //  Simple$.name:()Ljava/lang/String;
  #27 = Utf8               Code
  #28 = Utf8               SourceFile
  #29 = Utf8               RuntimeVisibleAnnotations
  #30 = Utf8               ScalaSig
{
  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #18                 // Method Simple$.main:([Ljava/lang/String;)V
         7: return

  public static void name_$eq(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #22                 // Method Simple$.name_$eq:(Ljava/lang/String;)V
         7: return

  public static java.lang.String name();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #26                 // Method Simple$.name:()Ljava/lang/String;
         6: areturn
}

從上面的編譯結果來看,針對var類型屬性,會自動生成靜態的setter和getter。這個類裏面的生成規則是同樣的。那如今虛構類中的狀況是如何的呢?

javap -c -v -private Simple$

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
  Last modified 2016-5-13; size 781 bytes
  MD5 checksum 66580c4b3c9bb57066b03a759e69c8da
  Compiled from "Simple.scala"
public final class Simple$
  SourceFile: "Simple.scala"
    ScalaInlineInfo: length = 0x18
     01 01 00 04 00 0A 00 09 01 00 16 00 17 01 00 0D
     00 0F 01 00 13 00 14 01
    Scala: length = 0x0

  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple$
   #2 = Class              #1             //  Simple$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               MODULE$
   #7 = Utf8               LSimple$;
   #8 = Utf8               <clinit>
   #9 = Utf8               ()V
  #10 = Utf8               <init>
  #11 = NameAndType        #10:#9         //  "<init>":()V
  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
  #13 = Utf8               name
  #14 = Utf8               Ljava/lang/String;
  #15 = Utf8               ()Ljava/lang/String;
  #16 = NameAndType        #13:#14        //  name:Ljava/lang/String;
  #17 = Fieldref           #2.#16         //  Simple$.name:Ljava/lang/String;
  #18 = Utf8               this
  #19 = Utf8               name_$eq
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = Utf8               x$1
  #22 = Utf8               main
  #23 = Utf8               ([Ljava/lang/String;)V
  #24 = Utf8               args
  #25 = Utf8               [Ljava/lang/String;
  #26 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
  #27 = NameAndType        #6:#7          //  MODULE$:LSimple$;
  #28 = Fieldref           #2.#27         //  Simple$.MODULE$:LSimple$;
  #29 = Utf8               Yanne
  #30 = String             #29            //  Yanne
  #31 = Utf8               Code
  #32 = Utf8               LocalVariableTable
  #33 = Utf8               LineNumberTable
  #34 = Utf8               SourceFile
  #35 = Utf8               ScalaInlineInfo
  #36 = Utf8               Scala
{
  public static final Simple$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL


  private java.lang.String name;
    flags: ACC_PRIVATE


  public static {};
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class Simple$
         3: invokespecial #12                 // Method "<init>":()V
         6: return

  public java.lang.String name();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #17                 // Field name:Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple$;
      LineNumberTable:
        line 2: 0

  public void name_$eq(java.lang.String);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #17                 // Field name:Ljava/lang/String;
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       6     0  this   LSimple$;
               0       6     1   x$1   Ljava/lang/String;
      LineNumberTable:
        line 2: 0

  public void main(java.lang.String[]);
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=2, args_size=2
         0: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       1     0  this   LSimple$;
               0       1     1  args   [Ljava/lang/String;
      LineNumberTable:
        line 3: 0

  private Simple$();
    flags: ACC_PRIVATE
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #26                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #28                 // Field MODULE$:LSimple$;
         8: aload_0
         9: ldc           #30                 // String Yanne
        11: putfield      #17                 // Field name:Ljava/lang/String;
        14: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      15     0  this   LSimple$;
      LineNumberTable:
        line 6: 0
        line 2: 8
}

對應的var類型屬性已經再也不是final的了,而是能夠改變的,同時,也有配套的getter和setter。可是名字不是和javabean裏面的使用習慣是一致的,那麼,咱們如今能不能用scala.beans.BeanProperty來註釋呢?

object Simple {
   @scala.beans.BeanProperty var name ="Yanne"
    def main(args:Array[String]){

    }
}

javap -c -v -private Simple

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 1035 bytes
  MD5 checksum 540b87e6d10abfde7cf477e0423c369f
  Compiled from "Simple.scala"
public final class Simple
  SourceFile: "Simple.scala"
  RuntimeVisibleAnnotations:
    0: #6(#7=s#8)
    ScalaSig: length = 0x3
     05 00 00
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple
   #2 = Class              #1             //  Simple
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               Lscala/reflect/ScalaSignature;
   #7 = Utf8               bytes
   #8 = Utf8               ;Q!\t\taaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd-\t1I\=SKDQ!EI\taP5oSRtD#A\tQ9!C+!a.Y7f+1CA
                                           A\"BA\raM\4
                                                      m\tAA[1wC&Q'RN\4\t}9!CAAa.Y7f?*\"IA1BIG1A!8ji\"9QEHA1a=%c!1qeQ!\nY\tQA\1nKB#AJ)jS\"A
                                                          1b!2fC:B,1U-8Qe>XM;zt\"29W\r(b[$Ag!\tg$h*Y7f)\t\tSC&e\t
                                 \t
                                   ]:A\t5
                                         N
                                          CeBQAAm\nA!:hgB1 \nub!!B!seCA C\tY)B1K]3eKL!!H\"
          c
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  main:([Ljava/lang/String;)V
  #18 = Methodref          #12.#17        //  Simple$.main:([Ljava/lang/String;)V
  #19 = Utf8               setName
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = NameAndType        #19:#20        //  setName:(Ljava/lang/String;)V
  #22 = Methodref          #12.#21        //  Simple$.setName:(Ljava/lang/String;)V
  #23 = Utf8               getName
  #24 = Utf8               ()Ljava/lang/String;
  #25 = NameAndType        #23:#24        //  getName:()Ljava/lang/String;
  #26 = Methodref          #12.#25        //  Simple$.getName:()Ljava/lang/String;
  #27 = Utf8               name_$eq
  #28 = NameAndType        #27:#20        //  name_$eq:(Ljava/lang/String;)V
  #29 = Methodref          #12.#28        //  Simple$.name_$eq:(Ljava/lang/String;)V
  #30 = Utf8               name
  #31 = NameAndType        #30:#24        //  name:()Ljava/lang/String;
  #32 = Methodref          #12.#31        //  Simple$.name:()Ljava/lang/String;
  #33 = Utf8               Code
  #34 = Utf8               SourceFile
  #35 = Utf8               RuntimeVisibleAnnotations
  #36 = Utf8               ScalaSig
{
  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #18                 // Method Simple$.main:([Ljava/lang/String;)V
         7: return

  public static void setName(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #22                 // Method Simple$.setName:(Ljava/lang/String;)V
         7: return

  public static java.lang.String getName();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #26                 // Method Simple$.getName:()Ljava/lang/String;
         6: areturn

  public static void name_$eq(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #29                 // Method Simple$.name_$eq:(Ljava/lang/String;)V
         7: return

  public static java.lang.String name();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #32                 // Method Simple$.name:()Ljava/lang/String;
         6: areturn
}

從上面編譯的結果來看,咱們是能夠用scala.beans.BeanProperty來註釋的。

其實,上面的object都是孤立對象,由於沒有和他同名的class,孤立對象的規則是,會生成同名的class和一個虛構的class,同名的class裏面只有靜態屬性和靜態方法,而虛構類纔是真正的的幹活地方。

那麼,若是在同一個文件,有一個和object同名的class 又會怎樣呢?

object Simple {
   @scala.beans.BeanProperty var name ="Yanne"
    def main(args:Array[String]){

    }
}


class Simple {
  val age =10
  var address= "KM"
  def say()={println("Hello")}
}

一樣的,當你scalac Simple.scala 的時候,也會生成Simple.class 和Simple$.class 兩個class文件。咱們先來看看Simple$.class 和之前有什麼不一樣。

javap -c -v -private Simple$

Classfile /Users/Yanne/project/scala/deepscala/Simple$.class
  Last modified 2016-5-13; size 954 bytes
  MD5 checksum 77245177287d300dde1fa9be95f90d8a
  Compiled from "Simple.scala"
public final class Simple$
  SourceFile: "Simple.scala"
    ScalaInlineInfo: length = 0x22
     01 01 00 06 00 0A 00 09 01 00 1B 00 0F 01 00 17
     00 18 01 00 0D 00 0F 01 00 13 00 14 01 00 16 00
     14 01
    Scala: length = 0x0

  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple$
   #2 = Class              #1             //  Simple$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               MODULE$
   #7 = Utf8               LSimple$;
   #8 = Utf8               <clinit>
   #9 = Utf8               ()V
  #10 = Utf8               <init>
  #11 = NameAndType        #10:#9         //  "<init>":()V
  #12 = Methodref          #2.#11         //  Simple$."<init>":()V
  #13 = Utf8               name
  #14 = Utf8               Ljava/lang/String;
  #15 = Utf8               ()Ljava/lang/String;
  #16 = NameAndType        #13:#14        //  name:Ljava/lang/String;
  #17 = Fieldref           #2.#16         //  Simple$.name:Ljava/lang/String;
  #18 = Utf8               this
  #19 = Utf8               name_$eq
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = Utf8               x$1
  #22 = Utf8               setName
  #23 = Utf8               main
  #24 = Utf8               ([Ljava/lang/String;)V
  #25 = Utf8               args
  #26 = Utf8               [Ljava/lang/String;
  #27 = Utf8               getName
  #28 = NameAndType        #13:#15        //  name:()Ljava/lang/String;
  #29 = Methodref          #2.#28         //  Simple$.name:()Ljava/lang/String;
  #30 = Methodref          #4.#11         //  java/lang/Object."<init>":()V
  #31 = NameAndType        #6:#7          //  MODULE$:LSimple$;
  #32 = Fieldref           #2.#31         //  Simple$.MODULE$:LSimple$;
  #33 = Utf8               Yanne
  #34 = String             #33            //  Yanne
  #35 = Utf8               Code
  #36 = Utf8               LocalVariableTable
  #37 = Utf8               LineNumberTable
  #38 = Utf8               SourceFile
  #39 = Utf8               ScalaInlineInfo
  #40 = Utf8               Scala
{
  public static final Simple$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL


  private java.lang.String name;
    flags: ACC_PRIVATE


  public static {};
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class Simple$
         3: invokespecial #12                 // Method "<init>":()V
         6: return

  public java.lang.String name();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #17                 // Field name:Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple$;
      LineNumberTable:
        line 2: 0

  public void name_$eq(java.lang.String);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #17                 // Field name:Ljava/lang/String;
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       6     0  this   LSimple$;
               0       6     1   x$1   Ljava/lang/String;
      LineNumberTable:
        line 2: 0

  public void setName(java.lang.String);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #17                 // Field name:Ljava/lang/String;
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       6     0  this   LSimple$;
               0       6     1   x$1   Ljava/lang/String;
      LineNumberTable:
        line 2: 0

  public void main(java.lang.String[]);
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=2, args_size=2
         0: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       1     0  this   LSimple$;
               0       1     1  args   [Ljava/lang/String;
      LineNumberTable:
        line 3: 0

  public java.lang.String getName();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokevirtual #29                 // Method name:()Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple$;
      LineNumberTable:
        line 2: 0

  private Simple$();
    flags: ACC_PRIVATE
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #30                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #32                 // Field MODULE$:LSimple$;
         8: aload_0
         9: ldc           #34                 // String Yanne
        11: putfield      #17                 // Field name:Ljava/lang/String;
        14: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      15     0  this   LSimple$;
      LineNumberTable:
        line 9: 0
        line 2: 8
}

咱們雖然在同名的class下增長了val,var類型屬性以及方法,可是,虛構類(Simple$)是徹底沒有反應的,也就是說,虛構類裏面永遠是對object的反應,而對class是無動於衷的。

咱們如今來看看Simple.class

javap -c -v -private Simple

Classfile /Users/Yanne/project/scala/deepscala/Simple.class
  Last modified 2016-5-13; size 1905 bytes
  MD5 checksum d9961f1b0349ef14e9754696f3e291ca
  Compiled from "Simple.scala"
public class Simple
  SourceFile: "Simple.scala"
  RuntimeVisibleAnnotations:
    0: #6(#7=s#8)
    ScalaInlineInfo: length = 0x1D
     01 00 00 05 00 3B 00 2F 00 00 23 00 18 00 00 2C
     00 14 00 00 21 00 25 00 00 2E 00 2F 00
    ScalaSig: length = 0x3
     05 00 00
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Utf8               Simple
   #2 = Class              #1             //  Simple
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             //  java/lang/Object
   #5 = Utf8               Simple.scala
   #6 = Utf8               Lscala/reflect/ScalaSignature;
   #7 = Utf8               bytes
   #8 = Utf8               q;Q!\t\taaU5na2,'\"Aq*W;z}\ra!I!AB*j[BdWA1BD)\tQ\"AtGd-\t1I\=SKDQ!EI\taP5oSRtD#A\tQ9!C+!a.Y7f+1CA
                                            A\"BA\raM\4
                                                       m\tAA[1wC&Q'RN\4\t}9!CAAa.Y7f?*\"IA1BIG1A!8ji\"9QEHA1a=%c!1qeQ!\nY\tQA\1nKB#AJ)jS\"A
                                                           1b!2fC:B,1U-8Qe>XM;zt\"29W\r(b[$Ag!\tg$h*Y7f)\t\tSC&e\t
                                  \t
                                    ]:A\t5
                                          N
                                           CeBQAAm\nA!:hgB1 \nub!!B!seCA C\tY)B1K]3eKL!!H\"
           ca"\t
                E!EA$!\"A#\t)#%!CmZ31\"aC'\n9c!aA%oi\"1
                                                       Q\n1
                                                           A!Y4fA!9!
                                                                    a\n)aB1eIJ,7)\r\"V-\tG\r:fgN|F%Z92bBT\rA1

                             $GM]3tgBQA#m
                                         1a]1z)\t
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               Simple$
  #12 = Class              #11            //  Simple$
  #13 = Utf8               MODULE$
  #14 = Utf8               LSimple$;
  #15 = NameAndType        #13:#14        //  MODULE$:LSimple$;
  #16 = Fieldref           #12.#15        //  Simple$.MODULE$:LSimple$;
  #17 = NameAndType        #9:#10         //  main:([Ljava/lang/String;)V
  #18 = Methodref          #12.#17        //  Simple$.main:([Ljava/lang/String;)V
  #19 = Utf8               setName
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = NameAndType        #19:#20        //  setName:(Ljava/lang/String;)V
  #22 = Methodref          #12.#21        //  Simple$.setName:(Ljava/lang/String;)V
  #23 = Utf8               getName
  #24 = Utf8               ()Ljava/lang/String;
  #25 = NameAndType        #23:#24        //  getName:()Ljava/lang/String;
  #26 = Methodref          #12.#25        //  Simple$.getName:()Ljava/lang/String;
  #27 = Utf8               name_$eq
  #28 = NameAndType        #27:#20        //  name_$eq:(Ljava/lang/String;)V
  #29 = Methodref          #12.#28        //  Simple$.name_$eq:(Ljava/lang/String;)V
  #30 = Utf8               name
  #31 = NameAndType        #30:#24        //  name:()Ljava/lang/String;
  #32 = Methodref          #12.#31        //  Simple$.name:()Ljava/lang/String;
  #33 = Utf8               age
  #34 = Utf8               I
  #35 = Utf8               address
  #36 = Utf8               Ljava/lang/String;
  #37 = Utf8               ()I
  #38 = NameAndType        #33:#34        //  age:I
  #39 = Fieldref           #2.#38         //  Simple.age:I
  #40 = Utf8               this
  #41 = Utf8               LSimple;
  #42 = NameAndType        #35:#36        //  address:Ljava/lang/String;
  #43 = Fieldref           #2.#42         //  Simple.address:Ljava/lang/String;
  #44 = Utf8               address_$eq
  #45 = Utf8               x$1
  #46 = Utf8               say
  #47 = Utf8               ()V
  #48 = Utf8               scala/Predef$
  #49 = Class              #48            //  scala/Predef$
  #50 = Utf8               Lscala/Predef$;
  #51 = NameAndType        #13:#50        //  MODULE$:Lscala/Predef$;
  #52 = Fieldref           #49.#51        //  scala/Predef$.MODULE$:Lscala/Predef$;
  #53 = Utf8               Hello
  #54 = String             #53            //  Hello
  #55 = Utf8               println
  #56 = Utf8               (Ljava/lang/Object;)V
  #57 = NameAndType        #55:#56        //  println:(Ljava/lang/Object;)V
  #58 = Methodref          #49.#57        //  scala/Predef$.println:(Ljava/lang/Object;)V
  #59 = Utf8               <init>
  #60 = NameAndType        #59:#47        //  "<init>":()V
  #61 = Methodref          #4.#60         //  java/lang/Object."<init>":()V
  #62 = Utf8               KM
  #63 = String             #62            //  KM
  #64 = Utf8               Code
  #65 = Utf8               LocalVariableTable
  #66 = Utf8               LineNumberTable
  #67 = Utf8               SourceFile
  #68 = Utf8               RuntimeVisibleAnnotations
  #69 = Utf8               ScalaInlineInfo
  #70 = Utf8               ScalaSig
{
  private final int age;
    flags: ACC_PRIVATE, ACC_FINAL


  private java.lang.String address;
    flags: ACC_PRIVATE


  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #18                 // Method Simple$.main:([Ljava/lang/String;)V
         7: return

  public static void setName(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #22                 // Method Simple$.setName:(Ljava/lang/String;)V
         7: return

  public static java.lang.String getName();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #26                 // Method Simple$.getName:()Ljava/lang/String;
         6: areturn

  public static void name_$eq(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: aload_0
         4: invokevirtual #29                 // Method Simple$.name_$eq:(Ljava/lang/String;)V
         7: return

  public static java.lang.String name();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #16                 // Field Simple$.MODULE$:LSimple$;
         3: invokevirtual #32                 // Method Simple$.name:()Ljava/lang/String;
         6: areturn

  public int age();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #39                 // Field age:I
         4: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple;
      LineNumberTable:
        line 10: 0

  public java.lang.String address();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #43                 // Field address:Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LSimple;
      LineNumberTable:
        line 11: 0

  public void address_$eq(java.lang.String);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #43                 // Field address:Ljava/lang/String;
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       6     0  this   LSimple;
               0       6     1   x$1   Ljava/lang/String;
      LineNumberTable:
        line 11: 0

  public void say();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #52                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
         3: ldc           #54                 // String Hello
         5: invokevirtual #58                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
         8: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       9     0  this   LSimple;
      LineNumberTable:
        line 12: 0

  public Simple();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #61                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #39                 // Field age:I
        10: aload_0
        11: ldc           #63                 // String KM
        13: putfield      #43                 // Field address:Ljava/lang/String;
        16: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      17     0  this   LSimple;
      LineNumberTable:
        line 13: 0
        line 10: 4
        line 11: 10
}

從上面看到,在class中定義的全部屬性所有體如今了這個裏面。

到這裏,咱們基本完成了對象的學習了,其實對應於孤立對象,咱們如今的同名的object和class出如今同一個文件中,那麼這種狀況就是伴生,obejct就是class的伴生對象,class是object的伴生類

新概念

**對象**
**孤立對象**
**虛構類**
**伴生對象**
**伴生類**

從上面的伴生對象來看,實際上,伴生對象不是單列的,只有孤立對象是單列的,由於孤立對象的全部屬性(Field和method)都是靜態的,那麼,有沒有辦法讓伴生對象也能夠是單列的呢?

第一種方法固然只用孤立對象啦,不要再用伴生類。可是這不太現實呀,伴生類不少狀況下是必需要存在的,那怎麼辦呢?

咱們看看下面的例子:

object Simple {
  val sm=new Simple
   @scala.beans.BeanProperty var name ="Yanne"
    def main(args:Array[String]){

    }
}


class Simple private {
  val age =10
  var address= "KM"
  def say()={println("Hello")}
}

上面的用法是將伴生類的構造器變成私有的了。而且在伴生對象中生成了一個伴生對象的實例。

伴生類與伴生對象是能夠相互訪問私有屬性的,爲啥呢?😄 看編譯後代碼就很清楚了

特殊的apply方法

object Simple {
  val sm=new Simple
   @scala.beans.BeanProperty var name ="Yanne"
    def main(args:Array[String]){

    }
  def apply()={
           new Simple
        }
}


class Simple  {
  val age =10
  var address= "KM"
  def say()={println("Hello")}
}

這樣子的話,咱們就可使用Simple() 這種實例化一個Simple對象了,這是爲啥呢? 實際上你能夠把這個當作是()的重載,他背後就是調用了apply方法。

相關文章
相關標籤/搜索