I have some legacy Java code that defines a generic payload variable somewhere outside of my control (i.e. I can not change its type):
// Java code
Wrapper<? extends SomeBaseType> payload = ...
I receive such a payload value as a method parameter in my code and want to pass it on to a Scala case class (to use as message with an actor system), but do not get the definitions right such that I do not get at least a compiler warning.
// still Java code
ScalaMessage msg = new ScalaMessage(payload);
This gives a compiler warning "Type safety: contructor... belongs to raw type..."
The Scala case class is defined as:
// Scala code
case class ScalaMessage[T <: SomeBaseType](payload: Wrapper[T])
How can I define the case class such that the code compiles cleanly? (sadly, changing the code of the Java Wrapper class or the type of the payload parameter is not an option)
Updated to clarify the origin of the payload parameter
Added For comparison, in Java I can define a parameter just in the same way as the payload variable is defined:
// Java code
void doSomethingWith(Wrapper<? extends SomeBaseType> payload) {}
and call it accordingly
// Java code
doSomethingWith(payload)
But I can't instantiate e.g. a Wrapper object directly without getting a "raw type" warning. Here, I need to use a static helper method:
static <T> Wrapper<T> of(T value) {
return new Wrapper<T>(value);
}
and use this static helper to instantiate a Wrapper object:
// Java code
MyDerivedType value = ... // constructed elsewhere, actual type is not known!
Wrapper<? extends SomeBaseType> payload = Wrapper.of(value);
Solution
I can add a similar helper method to a Scala companion object:
// Scala code
object ScalaMessageHelper {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
new ScalaMessage(payload)
}
object ScalaMessageHelper2 {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
ScalaMessage(payload) // uses implicit apply() method of case class
}
and use this from Java to instantiate the ScalaMessage class w/o problems:
// Java code
ScalaMessage msg = ScalaMessageHelper.apply(payload);
Unless someone comes up with a more elegant solution, I will extract this as an answer...
Thank you!