13

I have a java class that looks like this:

public class Constants {
    public class Commands {
        public static final String CreateOrder = "CreateOrder";
    }
}

I want to access "CreateOrder" constant, In java I can access it easily like this:

String co = Constants.Commands.CreateOrder

But in Scala this doesn't work why??? How can I access "CreateOrder" from Scala, I can't alter the Java code.

Thanks.

5
  • Can you try Constants$Command$CreateOrder ? Commented Oct 13, 2013 at 13:43
  • Constants$Command$CreateOrder didn't work Commented Oct 13, 2013 at 13:51
  • 1
    Why is Commands non-static? Commented Oct 13, 2013 at 17:16
  • 1
    I'm using an other java banking lib and i didn't write the java code and cant change it. Commented Oct 13, 2013 at 19:43
  • This incompatibility is bugging me now. Has anyone found an alternative approach other than reflection? Commented Sep 6, 2018 at 22:19

3 Answers 3

9

As far as I know, there is no way to do what you want in Scala.

But if you absolutely cannot change the Java code then you could resort to some reflection trickery.

val value = classOf[Constants#Commands].getDeclaredField("CreateOrder").get(null)
Sign up to request clarification or add additional context in comments.

1 Comment

I spent hours searching for a solution to this problem. I'm using a 3rd party lib that has constants defined this way. This was the only thing that worked. The suggestion below by @Travis Brown to instantiate an object then access it did not work for me.
6

From the Java Language Specification:

Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs.

In the case of constant variables, you can use the Constants.Commands.CreateOrder syntax even though normally any reference to Constants.Commands would have to be associated with an instance of Constants, since it's not a static inner class.

This could be considered something of a crazy one-off syntactic special case in Java, and it's the kind of thing that the Scala language designers haven't bothered to bake into Scala's Java interoperability.

Your best bet (if your real Java class looks exactly like this) is to create an instance of Constants, at which point you can access the inner class's static field in a perfectly natural way:

scala> (new Constants).Commands.CreateOrder
res0: String = CreateOrder

If for some reason this isn't an option you'll have to go with the reflection-based approach in the other answer, unfortunately.

Comments

6

I think a third alternative to reflection and instantiation is to write a small piece of Java glue code. Like

public class Glue {
    public static String createOrder() { return Constants.Commands.CreateOrder; }
}

Then from Scala you should be able to write Glue.createOrder.

2 Comments

That's a good alternative to my reflection based answer. If you are able/allowed to add new Java code to an application, this is a superior option.
As a side note: When building with sbt, throwing a .java file into the mix works out of the box. It is often a quick work around the corner cases where Java and Scala perspectives don't match (I think visibility is another case)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.