Object Is used to declare objects. You can declare three types of objects.

  • Generating anonymous Classes (Anonymous Objects)
  • Object declaration (name object)
  • Associated object

Object expressions (anonymous object objects)

The use of object can be used in several ways

  • Only one simple object is generated
fun foo(a) {
    val adHoc = object {
        var x: Int = 0
        var y: Int = 0
    }
    print(adHoc.x + adHoc.y)
}
Copy the code
  • Inheriting certain classes generates anonymous objects
class A{
    var t : A0? =  null;
    fun setListener(a:A0){
        t = a
    }
}

open class A0{
    fun doSome(a){
        print("some"); }}fun test(a){
    A().setListener(object :A0(){})
}
Copy the code

Some important features

  1. Anonymous classes that can implement multiple inheritance.
open class A(x: Int) {
    public open val y: Int = x
}

interface B { / *... * / }

val ab: A = object : A(1), B {
    override val y = 15
}
Copy the code
  1. Code in an object expression can access variables from the scope that contains it
fun countClicks(window: JComponent) {
    var clickCount = 0
    var enterCount = 0
    window.addMouseListener(object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            clickCount++
        }
        override fun mouseEntered(e: MouseEvent) {
            enterCount++
        }
    })
}
Copy the code

Anonymous objects are initialized as soon as they are used.

Object declaration (Naming object objects)

Object keyword followed by a name, declares an object, I’ll call this object named object, for example

object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        / /...
    }

    val allDataProviders: Collection<DataProvider>
        get() = / /...
}
/ / callDataProviderManager. RegisterDataProvider (...)Copy the code

Object Named objects can have superclasses. But it cannot be generated in a local scope.

Named objects are delayed and are initialized only when they are first accessed.

I initialized it in static{} after converting the KT file to Java. If so, it should be initialized when the class is loaded

The companion object

class MyClass {
    companion object Factory {
        fun create(a): MyClass = MyClass()
    }
}
val instance = MyClass.create()
Copy the code

Onpanion is initialized at class load parsing time.

After converting to Java

Java code for a simple object

   public static final void foo() {
      <undefinedtype> adHoc = new Object() {
         private int x;
         private int y;
         public final int getX() {
            return this.x;
         }
         public final void setX(int var1) {
            this.x = var1;
         }
         public final int getY() {
            return this.y;
         }
         public final void setY(int var1) {
            this.y = var1; }}; int var1 = ((<undefinedtype>)adHoc).getX() + ((<undefinedtype>)adHoc).getY(); System.out.print(var1);
   }
Copy the code

You can see that foo() is static and uses the object method to wrap the object.

Have inherited anonymous class after conversion. The anonymous objects declared by the direct package object are converted to their corresponding objects, and the calling method is also converted to static.

// Other class methods have not changed.
public static final void test(a) {(new A()).setListener((A0)(new A0() {
      }));
   }
Copy the code

Inherited structure named object

public final class DefaultListener extends MouseAdapter {
   public static final DefaultListener INSTANCE;

   public void mouseClicked(@NotNull MouseEvent e) {
      Intrinsics.checkParameterIsNotNull(e, "e");
   }

   public void mouseEntered(@NotNull MouseEvent e) {
      Intrinsics.checkParameterIsNotNull(e, "e"); } static { DefaultListener var0 = new DefaultListener(); INSTANCE = var0; }}Copy the code

Changes the class to final type, and initializes the object in the code block. This should be initialized when the class is loaded.

public final class MyClass {
   public static final MyClass.Factory Factory = new MyClass.Factory((DefaultConstructorMarker)null);

   public static final class Factory {
      @NotNull
      public final MyClass create(a) {
         return new MyClass();
      }
      private Factory(a) {}// $FF: synthetic method
      public Factory(DefaultConstructorMarker $constructor_marker) {
         this(a); }}}Copy the code

You can see that a singleton implementation of a static inner class + a static variable is used.

Factor is a static container class in which methods return objects and outer layers invoke the inner container to generate objects using properties initialized by static variables.

This design is based on the fact that the JVM does not load static inner classes while loading external classes. The inner class is loaded only when its properties and methods are called. Starts initializing static properties. There’s something about lazy loading, and there’s no thread-safety issue. This is more common in open source projects.

Focus on

  • Anonymous Classes (anonymous Objects) : Perform immediate, normal initialization where they are used.
  • Object declaration (name object) : Delay initialization until first use. (after the compilation for the Java found in static {} block of code to initialize, estimate when the compiler do special processing, is a first used to initialize and ordinary class had no difference)
  • Once the Companion Object class is loaded, it begins to be externalized

For object declaration (named object object) initialization problem, if you know the trouble to inform friends.