Private constructor for public class


#1

I want to make sure that I am the only one who can create some type of object class. But I want the class to be public so that I can have methods for manipulating those objects. I don't want to use an interface for those methods because I want to make sure the object is really one of mine.

In java, I would implement it like this.

package com.example;

public enum Factory {
  INSTANCE;
  public Element createElement() {
  return new Element(“test”);
  }
  public static class Element {
  private final String name;
  private Element(final String name) { this.name = name; }
  public String getName() { return name; }
  }
}

final Element element = Factory.INSTANCE.createElement();

This achieves my goal: Element is public, but nobody can create one without going through my factory
unless they use reflection.

I don’t know how to achieve the same with kotlin. The java solution relies on the fact that you can have a public class with a private constructor,
and I don’t know if or how I can do that in kotlin.


#2

In Kotlin, if you need to provide custom visibility for constructor, you write it in class header, before constructor parenthesis. Your sample looks like this in Kotlin:

public object Factory {   public fun createElement(): Element = Element("test")

  public class Element internal (public val name: String)
}

Note that visibility of constructor in nested class is internal, not private, because otherwise it coundn't be used in outer class.


#3

Awesome, thanks.


#4

doesn’t work for me - is this info outdated? I had to add the word ‘constructor’ after the visibility modifier, making it like “secondary constructor syntax”.


#5

It is correct that you have to name it construtor explicitly, if you want to add visibility modifiers or annotations like @Inject to the constructor.


#6

class ClassName private constructor() {}

or If you are using multiple constructor

class ClassName() {
 private constructor(params: Params){}
}