107

In Java it's possible to hide a class' main constructor by making it private and then accessing it via a public static method inside that class:

public final class Foo {
    /* Public static method */
    public static final Foo constructorA() {
        // do stuff

        return new Foo(someData);
    }

    private final Data someData;

    /* Main constructor */
    private Foo(final Data someData) {
        Objects.requireNonNull(someData);

        this.someData = someData;
    }

    // ...
}

How can the same be reached with Kotlin without separating the class into a public interface and a private implementation? Making a constructor private leads to it not being accessible from outside the class, not even from the same file.

4 Answers 4

186

You can even do something more similar to "emulating" usage of public constructor while having private constructor.

class Foo private constructor(val someData: Data) {
    companion object {
        operator fun invoke(): Foo {
            // do stuff

            return Foo(someData)
        }
    }
}

//usage
Foo() //even though it looks like constructor, it is a function call
30

This is possible using a companion object:

class Foo private constructor(val someData: Data) {
    companion object {
        fun constructorA(): Foo {
            // do stuff

            return Foo(someData)
        }
    }

    // ...
}

Methods inside the companion object can be reached just like if they were members of the surrounding class (e.g. Foo.constructorA())

1
  • 3
    Adding to this for completeness. From Java you can only call methods inside a companion object only with Companion like Foo.Companion.constructorA(). To make it natural from Java, annotate the method with @JvmStatic and the method will act like a static method (called like Foo.constructorA()). Commented Sep 27, 2019 at 6:30
14

See kotlin documentation here:

https://kotlinlang.org/docs/reference/classes.html#constructors

https://kotlinlang.org/docs/reference/visibility-modifiers.html#constructors

class DontCreateMe private constructor () { /*...*/ }
-8
This is the Answer

class Hide private constructor(val someData: Data) {

}

By declaring the constructor private, we can hiding constructor.
2
  • While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained.
    – Borja
    Commented Mar 4, 2020 at 8:16
  • Your reply doesn't answer the question and thre correct answer was given multiple times two years ago?
    – Marvin
    Commented Mar 4, 2020 at 21:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.