Constant values used as default value in constructor parameters


#1

Hello,

I’ve been playing around the Kotlin and I’m really liking what I’m seeing. I think the language strikes a real nice balance between expressiveness and practicality, I particularly think the emphasis on making sure the code is readable and has few gotchas is a really good idea.
Anyway, I was playing around and couldn’t work out how to do the equivalent of the following (very common) Java code.

class MyMap {
  public static final DEFAULT_CAPACITY = 16;



  public MyMap() {
  this(DEFAULT_CAPACITY);
  }


  public MyMap(int capacity) {
  …

  }

}

The issue is defining a constant inside the class and using as a default constructor parameter. i.e. you might try this …

class MyMap(val capacity: Int = DEFAULT_CAPACITY) {
  val DEFAULT_CAPACITY = 16

}

But the value isn’t in scope … You might try to do it Scala style with a companion object …

class MyMap(val capacity: Int = MyMap.DEFAULT_CAPACITY) {
  
}
object MyMap {

  val DEFAULT_CAPACITY = 16

}

But it seems you can’t have companion objects named the same as your classes … meaning you need a specially named companion object just for that single constant value … which is a bit yuk.

You can of course, introduce it top-level …

val DEFAULT_CAPACITY = 16
class MyMap(val capacity: Int = DEFAULT_CAPACITY) {
  
}

But now you’ve cluttered up the global namespace with a constant that only makes sense for the MyMap class … you can hide the top-level item as private … but now people can’t explicitly get hold of the default capacity if they need it for some reason.

Anyone know any solutions I’ve not thought of?

Cheers

Tomsk


#2

This works. I'm not sure I like the fact you have to fully qualify the name of the constant.

class MyMap(val capacity: Int = MyMap.DEFAULT_CAPACITY) {   class object {   val DEFAULT_CAPACITY = 16   } }


#3

And now I shall answer my own question ... wonder if I get points.

I couldn’t find a lot of documentation about it, but seems there are ‘class objects’ that can fulfill this role. Presumably these are similar to companion objects in Scala … except that I actually prefer the Kotlin concept simply from the point of view of keeping the syntax for related things close together.

class MyMap(val capacity: Int = MyMap.DEFAULT_CAPACITY) {
  class object {
  val DefaultCapacity = 16

  }
}

Nice solution, I’m liking where Kotlin is going.

Tom


#4

Thanks Chris, looks like I found the right answer :-) Took quite a bit of digging ... doesn't seem to be anything official on class objects, that I could find.


#5

There's a bit about them here:

http://confluence.jetbrains.net/display/Kotlin/Classes+and+Inheritance#ClassesandInheritance-Classobjects