110

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

188

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
Sign up to request clarification or add additional context in comments.

Comments

31

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 Comment

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()).
15

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 () { /*...*/ }

Comments

-8
This is the Answer

class Hide private constructor(val someData: Data) {

}

By declaring the constructor private, we can hiding constructor.

2 Comments

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.
Your reply doesn't answer the question and thre correct answer was given multiple times two years ago?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.