3

Consider the following classes:

//A.java:
public interface A {
    public static final String HIGHER = "higher";
}

//B.java:
public class B implements A {
    public static final String LOWER = "lower";
}

In java code I have access to both HIGHER and LOWER fields:

//JavaClient.java:
public class JavaClient {
    public static void main(String[] args) {
        System.out.println(B.HIGHER);
        System.out.println(B.LOWER);
    }
}

But I cannot do the same thing in Scala!

//ScalaClient.scala:
object ScalaClient {
  def main (args: Array[String]) {
    println(B.HIGHER)    // Compilation error
    println(B.LOWER)     // OK
  }
}

This is very unexpected for me. Why Scala cannot see inherited psf field? How to workaround?

Note: In my real code I don't have access to interface A, since it is protected and nested in another class.

Nyavro
  • 8,806
  • 2
  • 26
  • 33

2 Answers2

3

Just access HIGHER as A.HIGHER. So far as Scala is concerned, static members in Java are members of companion objects, and the companion object of B doesn't extend the companion object of A: that's why you can't use B.HIGHER.

Note: In my real code I don't have access to interface A, since it is protected and nested in another class.

In this case, however, you have a problem. The one thing I can think of is to expose the constant explicitly from Java code, e.g. (assuming you can change B):

public class B implements A {
    public static final String LOWER = "lower";
    public static final String HIGHER1 = HIGHER;
}
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
0

You can fix the problem in two ways.

1) Just remove the static word in interface A & interface B and it should work.

Or

2) Create a trait (trait is a feature in Scala, which closely resembles java interface but there are many differences)

trait A { }

object A { 
  final val Higher = "higher"
}

Now you can access A.Higher from your caller Scala class.

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • 2
    This answer is simply wrong. 1) Removing `static` will cause compilation error, since interfaces can't have non-`static` fields; 2) If it didn't, it would change the meaning of the code; 3) Scala can access Java's `static` members. – Alexey Romanov Nov 15 '15 at 20:13
  • Below code is compiling (removing static for variable declaration in interface) : interface A{ public final String HIGHER = "higher"; } – Ravindra babu Nov 15 '15 at 20:25
  • Because fields in interfaces are implicitly `static` - you literally can't make a non-static field in plain Java. – Clashsoft Nov 15 '15 at 20:30
  • Yes, Since it is implicit, no need to mention it as explicit. – Ravindra babu Nov 15 '15 at 20:31
  • I came to solution like suggested by you: object C extends A { final val EXPOSE = A.HIGHER } – Nyavro Nov 16 '15 at 03:08
  • Ah sorry, didn't remember this. In this case, of course, removing `static` won't work because it doesn't change anything. – Alexey Romanov Nov 16 '15 at 06:41