Today I encountered a strange problem with case class constructors. I wanted to make a constructor private and it seems that it isn't problem. So I've tried it in one of my projects and it works. But in another project I can invoke private constructor and it compiles. I thought it is something with my ide, so I made a standalone class and compile it with scalac. And it compiles. Here is the code:
package com.test
object Main {
def main(args: Array[String]) {
val bar = Bar("12345")
// bar.doStuff()
println(bar)
}
}
case class Bar private(foo: String){
private def doStuff():Unit = println("stuff")
}
The funny thing is that if I uncomment bar.doStuff() it won't compile. So I assume private works in this case, but somehow doesn't work for constructor. What am I doing wrong? Scalac is 2.11.8
Yes, we can declare a constructor as private. If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.
A private constructor in Java is used in restricting object creation. It is a special instance constructor used in static member-only classes. If a constructor is declared as private, then its objects are only accessible from within the declared class. You cannot access its objects from outside the constructor class.
No, Constructors can be public , private , protected or default (no access modifier at all).
Private constructors allow us to restrict the instantiation of a class. Simply put, they prevent the creation of class instances in any place other than the class itself.
The notation val bar = Bar("12345")
is shorthand for val bar = Bar.apply("12345")
, in other words, it calls the apply
method of the (automatically generated) companion object of the case class.
The companion object has access to the private constructor, so that's why it works.
(Why do you want to make the constructor of a case class private
? That doesn't sound like a good idea).
If you want Bar("abc")
to not compile, here's a simple workaround.
Quickly tested in 2.12.3. Doesn't work in 2.11.8
case class Bar private (value: String)
object Bar {
private def apply(v: String) = new Bar(v) // makes the method private
def create(value: String): Bar = ... // your own implementation
}
val bar = Bar("abc") // compile error
val bar = new Bar("abc") // compile error
val bar = Bar.create("abc") // ok
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With