mingo
mingo

Reputation: 33

Java and Scala integration with private modifiers

I've been defining private and protected methods from Scala classes, but when compiling to java bytecode, they just dissapear and all the methods become public! so when calling from java, I am able to call any of them. Is correct what I'm saying? and if so, wil this in the near future change with a new compiler?

Upvotes: 0

Views: 192

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369428

I've been defining private and protected methods from Scala classes, but when compiling to java bytecode, they just dissapear and all the methods become public!

Scala's access modifier semantics don't map to the JVM's access modifier semantics. Any way to translate them must necessarily be an approximation. Sometimes, the closest possible approximation is public.

That's just the way it is. Just look at Scala-native for comparison, which compiles to native binary machine code: all access modifiers, and all types are completely gone, because there simply is no way to represent them in native binary machine code. Even Java can't be properly represented in JVM bytecode (e.g. Java has Generics, but the JVM has no way to represent them).

so when calling from java, I am able to call any of them. Is correct what I'm saying?

Yes. When you use Java to interact with Scala code, you are circumventing any checking the Scala compiler does. There is no way around that.

and if so, wil this in the near future change with a new compiler?

No. It would require a change in the JVM Specification to allow languages to specify their own access modifier semantics. I don't see that happening.

Upvotes: 2

som-snytt
som-snytt

Reputation: 39577

Sometimes access is widened without any name mangling or obfuscation.

Here, you might expect the implementation to show default package access:

scala> :pa
// Entering paste mode (ctrl-D to finish)

package p { class C { private[p] def c = 42 }}

// Exiting paste mode, now interpreting.


scala> :javap p.C
[snip]
  public int c();

A special accessor is provided here for pattern matching:

scala> case class C(private val c: Int)
defined class C

scala> :javap -pv C
[snip]
  private final int c;
    descriptor: I
    flags: ACC_PRIVATE, ACC_FINAL

  public int c$access$0();

It is not a good idea to rely on any such implementation detail for purposes of general interop. However, Scala promises binary compatibility within a release series such as 2.12.x. Anything compiled with 2.12.1 must link with new code compiled with 2.12.2.

Upvotes: 0

Related Questions