Reputation: 12283
Consider the following contrived Java example:
public class Example {
private final Object value;
private final List<?> aListOfTheseThings;
public <T> Example(final T t, final List<T> aListOfTheseThings) {
this.value = t;
this.aListOfTheseThings = aListOfTheseThings;
}
}
What I care about in this Example:
Example
is not parameterizedt
(This is a contrived example, I do not really care about (2)
but I really do care about having a type parameter there which is not mentioned in the definition of the class).
Now in Scala I tried the following:
class Example private[this](
private val value: AnyRef,
private val aListOfTheseThings: List[_]) {
def this[T](t: T, aListOfTheseThings: List[T]) {
this(t, aListOfTheseThings)
}
}
...but this is not possible. Apparently a type parameter is not valid in a constructor (in this
).
Any chance of translating the above Java code into Scala?
Upvotes: 4
Views: 2331
Reputation: 39366
Nyavro's suggestion of a helper apply
method is a good one. Another option that might be appropriate in some cases is subclassing:
trait Example {
val value: Any
val things: List[_]
}
class SameTypeExample[T](val value: T, val things: List[T]) extends Example
The advantage of subclassing is that the constraint that value
and things
store the same type is not lost, and can be re-discovered by pattern matching:
def handle(example: Example) = example match {
case st: SameTypeExample[t] =>
st.value :: st.things
}
Subclassing is a general technique in Scala for temporarily hiding information that was present at construction time.
Upvotes: 7
Reputation: 8866
Maybe this help:
sealed trait Example
object Example {
def apply[T <: AnyRef](t:T, aListOfTheseThings: List[T]): Example =
new ExampleImpl(t, aListOfTheseThings)
private class ExampleImpl(
val value: AnyRef,
val aListOfTheseThings: List[_]) extends Example
}
This makes private constructor of class Example
. value and aListOfTheseThings
are not accessed via Example
trait (unless you make it accessible)
Upvotes: 8