Is constructor use allowed with case classes?

I have a case class (let's name it Stuff) that I want to be able to create anonymous subclasses of at run time by extending a trait (call it Marker). Here's a snippet of a REPL session that illustrates what I'm trying to do:

scala> trait Marker
defined trait Marker

scala> case class Stuff(i: Int)
defined class Stuff

scala> val a = Stuff(1)
a: Stuff = Stuff(1)

scala> val b = new Stuff(1) with Marker
b: Stuff with Marker = Stuff(1)

Note how a is instantiated using Stuff.apply(), while in b's case I'm calling the case class' constructor.

My question is: is instantiating case classes using a constructor kosher? It appears to me that it is, since the usual conveniences provided by case classes, such as ==, .equals(), and .hashCode(), all work. Am I missing anything that would brand what I'm doing a Bad Thing (TM)?

scala> a == b
res0: Boolean = true

scala> a.equals(b)
res1: Boolean = true

scala> a.hashCode == b.hashCode
res2: Boolean = true

Answers


Here's how Stuff.apply is implemented:

object Stuff {
  def apply(i: Int): Stuff = new Stuff(i)
}

So there's no harm at all in using new Stuff.


To the question

is instantiating case classes using a constructor kosher

the answer is definitely yes. Something like

val b = new Stuff(1)

poses no problems at all. Now, new Stuff(1) with Marker is different because an anonymous subclass of Stuff is created. I believe, though, that it's still unproblematic. The problems I know about appear when case classes inherit from other case classes, and you aren't doing that. But I may be unaware of something.

EDIT: just tested matching in the REPL:

scala> val b = new Stuff(1)
b: Stuff = Stuff(1)

scala> b match {case Stuff(x) => x}
res0: Int = 1

scala> b match {case Stuff(_) => true}
res1: Boolean = true

Need Your Help

How to rotate a bufferedimage, then copy the bufferedImage into a pixel array

java image awt java-2d affinetransform

I am trying to rotate a bufferedImage of a missile turret so that it looks like it's following a target. Basically, I can do it easily with the AffineTransform/ affinetransform