Mustafa
Mustafa

Reputation: 981

Scala can't access Java inner class?

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.

Upvotes: 13

Views: 3240

Answers (3)

0__
0__

Reputation: 67280

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.

Upvotes: 6

Travis Brown
Travis Brown

Reputation: 139038

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.

Upvotes: 6

sksamuel
sksamuel

Reputation: 16387

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)

Upvotes: 9

Related Questions