今天在kotlin的companion object踩了一小坑

1,039 阅读1分钟

直接上代码

class Person{
    companion object {
        var age:Int =0

        fun newInstance(age:Int): Person {
            this.age = age
            return Person()
        }
    }
    fun printAge() {
        println("${this} == age:$age")
    }
}

在上面代码中,在companion object中定义了一个newInstance(age:Int)方法,这个方法中修改了age值,然后实例化了一个Person实例.在Person类中printAge()方法用于打印当前对象和age值

测试

fun main(args: Array<String>) {

    val p1 = Person.newInstance(age = 10)
    val p2 = Person.newInstance(age = 20)
    p1.printAge()
    p2.printAge()
}

通过Person.newIntance()实例化了两个Person对象p1和p2.然后分别调用了他们的printAge()方法.小坑坑即将出现,天真的我认为他们会打印各自的age值, 10 和 20.但是..... ,来看打印结果

demo.Person@27c170f0 == age:20
demo.Person@5451c3a8 == age:20

看到没,看到没,看到没.虽然是实例化了两个对象没错,但是他们的age值竟然一样.为什么?来看看Peson.kt 和main()方法转换成的Java内容

public final class Person {
   private static int age;
   public static final Person.Companion Companion = new Person.Companion((DefaultConstructorMarker)null);

   public final void printAge() {
      String var1 = this + " == age:" + age;
      System.out.println(var1);
   }

   public static final class Companion {
      public final int getAge() {
         return Person.age;
      }

      public final void setAge(int var1) {
         Person.age = var1;
      }

      @NotNull
      public final Person newInstance(int age) {
         this.setAge(age);
         return new Person();
      }

      ...省略若干代码....

     
   }
}

//main方法
public final class KotlinDemoKt {
   public static final void main(@NotNull String[] args) {
      Intrinsics.checkParameterIsNotNull(args, "args");
      Person p1 = Person.Companion.newInstance(10);
      Person p2 = Person.Companion.newInstance(20);
      p1.printAge();
      p2.printAge();
   }
}

**在调用Person.newInstance()方法时,实际时隐藏了Person的Companion实例,Companion是静态类,而在companion object中定义的age变量变成了Person中的私有静态类.看到没时私有静态的.问题就在个私有静态的问题.所以所有通过Person.newInstance()实例化并修改了age值的对象,他们是共享同一个个age内存的.哦了,解释完毕.下班~~~~~~~~**