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方法。

相关文章
相关标签/搜索