Companion Objects on Bottom

The order here:

  • Property declarations and initializer blocks
  • Secondary constructors
  • Method declarations
  • Companion object

I realize this isn’t a hard and fast rule, but I’m curious what drove it?

My team and I tend to use the companion object most for a logger and constants that are consumed in the class. When they are the bottom, any major syntax issues turn the file an angry red instead of just starting where the first error occurs, so I’d like to recommend we put the companion object near the top.

I’ve found it simpler to put constants, loggers, and that sort of thing at the top level, above the class definition (and marked private so they don’t interfere with other files in the same package).

There isn’t much you actually need a companion object for: a main() method can be at the top level too (though that needs a change to how you run it), as can utility methods and factory methods. I don’t think there’s an easy way around it for the serialVersionUID, and it can be a good way of grouping factory methods, but other than that, I’ve ended up not really using companion objects.

And for those remaining things, putting them at the bottom of the file fits quite well.


Thanks! So far, I’ve avoided the top-level variables, but they make a lot of sense in this context.

Yeah, avoiding top level properties is something that most people coming from java or some similar language do.
As long as they are val and private there is no problem. They only become problematic if they are mutable and public. Then you run into the usual issues with global state.