views:

180

answers:

3

I have a Java method that accepts a Long value:

(in Java)
public void setValue(Long value);

I understand that the Scala null does not extend any of the value types, including Long. Therefore, when I try to pass null to it, I get a compilation error:

(in Scala)
javaThing.setValue(null)

==> type mismatch; found  : Any required: java.lang.Long

EDIT: aargh! Ignore above snippet. I oversimplified the problem, and got into trouble. In fact, problem arises from my use of Option[Long], as follows:

javaThing.setValue(calcValue.getOrElse(null))

The issue is, I think, that getOrElse evaluates to the Any type when given a null argument.

Help!

A: 

As far as I remember, there isn't a way beyond choosing a value of long to work like null. Usually it's -1 that gets used.

AaronM
+1  A: 

I can't reproduce that here.

JavaTst.java:

public class JavaTst {
    public void setValue(Long value) {}
}

REPL:

scala> new JavaTst
res0: JavaTst = JavaTst@4e229e

scala> res0.setValue(null)

scala>

EDIT

Aha! In that case, this convoluted code will work:

res0.setValue(calcValue.map(new java.lang.Long(_)).getOrElse(null))

I suggest importing java.lang.Long to jlLong, to keep it shorter.

Daniel
The problem seems to be when you define the method in Scala: scala> class JavaTst() { def setValue(value: Long) {} }defined class JavaTstscala> new JavaTstres4: JavaTst = JavaTst@4fb529d6scala> res4.setValue(null)<console>:8: error: type mismatch; found : Null(null) required: Long res4.setValue(null) ^
pr1001
You are perfectly correct. I've corrected my faulty description of the problem, which has to do with the use of Option[Long]. Apologies for the miscommunication.
David
Hmmm. I don't understand the solution with calcValue.map(new java.lang.Long(_); what's going on there?
David
@David Scala's `Long` is an `AnyVal`, and, therefore, does not have `null` as a possible value. So I'm mapping it to a `java.lang.Long`, which does. Once that is accomplished, then Scala can infer the type `java.lang.Long` for `null`, which it couldn't for `Long`.
Daniel
So beautiful! ...... the solution, not you, Daniel. sorry.
David
+3  A: 

Explicitly casting using asInstanceOf will work:

scala> val l:java.lang.Long = Some(2L).getOrElse(null).asInstanceOf[java.lang.Long]
l: java.lang.Long = 2

scala> val n:java.lang.Long = None.getOrElse(null).asInstanceOf[java.lang.Long]    
n: java.lang.Long = null

So, something like this should work:

javaThing.setValue(calcValue.getOrElse(null).asInstanceOf[java.lang.Long])

It's subverting the type-system, but so is using null in the first place.

Kristian Domagala