Pass null to a method expects Long
Asked Answered
H

3

5

I have a Scala method that takes 2 parameters:

def test(x:Long,y:Int){}

On some occasion I need to pass null instead of long ... something like that:

test(null,x)

The result:

scala> test(null,2) :7: error: type mismatch; found : Null(null) required: Long test(null,2)

Why do I need to pass null? Actually ,for some reason,I can't pass any default values. Thus, I need such a null.

*Note:*I know that the solution would be making it Option. However let's say I have no control over this method signature,can I do any work around?

Any ideas!

Thanks.

Herrin answered 30/11, 2012 at 1:46 Comment(3)
You could also use java.lang.LongCelloidin
Scala's Long in fact maps to the JVM primitive type long. So, a Scala Long cannot be null, because primitive types cannot be null. (Don't confuse scala.Long with java.lang.Long!).Unrighteous
the problem here is that jdbc is java and databases store null values for nullable longs. If you pass them as 0L in the scala system, you're asking for problems.Cutting
M
3

Since you can't change the signature, consider the mistake of Thinking Option[Foo] is the only/most natural way to express a missing function argument.

If the param to your function is a lower bound, then Long.MinValue might be a natural default.

If by "for some reason,I can't pass any default values" (whatever that could possibly mean) you mean you can't add defaults to the signature, and you're going the route suggested in another answer of adapting the method, you might as well change f(a,b) to g(b, a=Long.MinValue) or whatever before forwarding.

Instead of making clients of your adaptor method call g(b, None), let them call g(b). You're not passing the Option to the underlying f(a,b) anyway.

Mutt answered 30/11, 2012 at 3:36 Comment(0)
P
9

Null is a subtype of types which inherit from AnyRef, not from value types which inherit from AnyVal. This is why you are not able to pass null in. This corresponds to how, in java, you cant have a null of type long. (ignoring the boxed Long type).

However, this is an indication that the signature of the method should be changed to:

def test(x: Option[Long], y: Int)

which indicates that sometimes it goes no value for x. Since we have this nice Option class to deal with just this instance, there is little if any valid reasons to use null values, where you are relying on developers remembering to check for null values. Instead, with Option, the compiler will force you to take care of the fact that the value might not be there.

Planish answered 30/11, 2012 at 2:0 Comment(8)
I totally agree that it should be as an Option.However,I can't modify the method signature.I know what I'm saying is un logical.. but do you know any work around !!Herrin
Then you need to explicitly deal with it BEFORE you make the call then.Mute
Yes Dominic .. do you have any ideas how !!Herrin
If you have a method that needs to accept a null and cannot possibly accept a null, clearly something is broken. Seems like you either need to figure out what Long makes sense or not call this method.Planish
What I mean Echo, is just test for null before you call the method that takes just a Long (rather then a Option[Long]) and deal with the exception there. You could write a test(x: Option[Long], y: Int) = { //test for null here, and THEN call your other test method } In other words.... wrap the bad method with something that is a bit nicer.Mute
Thanks Dominic .. that would answer my question.Herrin
Thanks stew for your assistance.Herrin
This is probably the best option, but it's a pain if you are dealing with Oracle's PLSQL Array artifacts. In the case of Oracle arrays I'd have to have Array[Option[Long]]] to make Long arrays work. The addendum to this is that for consistency I'd also have to use Array[Option[String]]] and Array[Option[BigDecimal]]] for Scala Objects that are true AnyRefs and didn't have this problem.Cutting
M
3

Since you can't change the signature, consider the mistake of Thinking Option[Foo] is the only/most natural way to express a missing function argument.

If the param to your function is a lower bound, then Long.MinValue might be a natural default.

If by "for some reason,I can't pass any default values" (whatever that could possibly mean) you mean you can't add defaults to the signature, and you're going the route suggested in another answer of adapting the method, you might as well change f(a,b) to g(b, a=Long.MinValue) or whatever before forwarding.

Instead of making clients of your adaptor method call g(b, None), let them call g(b). You're not passing the Option to the underlying f(a,b) anyway.

Mutt answered 30/11, 2012 at 3:36 Comment(0)
U
0

The way to convert scala primitives to Java wrapper classes, is to use the static valueOf members on the Java Primitive wrappers. I had this issue where I needed to convert an Option[Double] to a java.lang.Double or null. This is what I did:

val value: Option[Double]
val orNull = value.map(java.lang.Double.valueOf(_)).orNull

Just passing literal null should work if you are calling a method that accepts java.lang.Long/Double/Integer

Unpolled answered 24/2, 2017 at 12:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.