Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can haz no package-private class in Scala?

Tags:

scala

Sorry for the catchy title. ;-)

I want to create a package-private class with a package-private method in Scala, so my class looks somewhat like this:

package net.java.truevfs.ext.pace

import ...

private[pace] abstract class AspectController(controller: FsController)
extends FsDecoratingController(controller) {

  private[pace] def apply[V](operation: => V): V

  ... // lots of other stuff
}

However, if I use javap to check what the Scala compiler effectively creates, I get something like this:

$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController
Compiled from "AspectController.scala"
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{
    public abstract java.lang.Object apply(scala.Function0);
    ...
}

This means that although the Scala compiler might respect the access restrictions, I could still call this class from any Java code, which is a clear encapsulation violation.

Am I missing something? Is there a way to make this work as intended?

like image 249
Christian Schlichtherle Avatar asked Oct 09 '12 09:10

Christian Schlichtherle


People also ask

What is private class in Scala?

In Scala, members that are private are accessible not only inside the class itself, but also in the class' companion object (and vice versa: a private member in an object is accessible also in the object's companion class).

What is a package private class?

package-private (often just called package) means that other members of the same package have access to the item. package-private is the default access modifier and does not have a keyword, because package is used to specify the package for a class or interface.

How can you access a class declared as private outside its packages?

Can a class declared as private be accessed outside it's package? Not possible. Can a class be declared as protected? The protected access modifier cannot be applied to class and interfaces.

Can a package private class have public methods?

Yes. Well, obviously you can access those methods from within the same class.


1 Answers

In addition to @Régis' answer, the reason Scala compiler doesn't make the class package-private is because by Scala rules it can be accessed from other packages: namely, subpackages of net.java.truevfs.ext.pace. E.g.

package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController

class Subclass extends AspectController { ... }

is legal in Scala, but in Java classes from net.java.truevfs.ext.pace.subpackage can't access package-private classes from net.java.truevfs.ext.pace.

like image 130
Alexey Romanov Avatar answered Sep 19 '22 06:09

Alexey Romanov