10

Suppose you were designing a Java library for other people to use. You compile the library into a JAR that they can import into their projects and use.

Needless to say, you intend for the library to be used in certain ways and through certain interfaces. For example, you might create several Facade classes to control the library, and in the documentation you state how the library should be used, what every class and method is used for, etc.

But is there a way to hide completely a certain class from the user? In every library there are certain classes (I suppose usually the majority of the classes), that are used internally by the library and are not supposed to be used directly by the code using the library.

Is there a way for me to state "this class is for internal use by this library inside this JAR or inside this package, it cannot be used outside of the boundaries of this library"? Is this technically possible? Or should I just state in the docs that certain libraries shouldn't be used by the user, and that's it?

1
  • This Q&A is a lot better than the duplicate. If someone with enough privileges would reverse them, that would be useful.
    – Suragch
    Commented Apr 18, 2017 at 12:15

1 Answer 1

13

Use package-private, which is what you get when you specify no access modifier at all. It limits a class or method to only be visible to the package it's in.

package animals;

public class Animal { ... };

public class Giraffe extends Animal {
    void run() { ... }
    public void jump() { ... }
}

class Platypus extends Animal { ... }

Any code that imports the animals package will be able to see the Animal class and the Giraffe class, but not the Platypus class. Additionally, that code will be able to call the Giraffe.jump() method, but not the Giraffe.run() method. However, inside the package, both of Giraffe's methods as well as the Platypus class are visible.

Note that this does not work for nested packages, so you can't have a package-private class in package A be visible to classes in package A.B. This is because nested packages aren't really nested, they're treated by java as two distinct packages and have no special relationship with each other. Packages A and A.B interact no differently than any other two packages would.

4
  • I see, thanks for answering. A question: what stops the end-user of my library to include one of his/her classes in package animals, and thus gain access to all the package-private stuff in animals?
    – Aviv Cohn
    Commented Sep 22, 2014 at 23:07
  • 4
    As in, what could stop them from decompiling your JAR, going into the source code, adding their own class into the package, and accessing your package private classes through that? Nothing. Public/private/protected/etc. are not about security, they're about encapsulation. If a client is that determined to break into your source, you're not going to be able to stop them without some sort of encryption scheme and that's another matter entirely.
    – Jack
    Commented Sep 22, 2014 at 23:11
  • 1
    @Jack, I don't think you need to have your classes in the same jar to be in the same package. Commented Sep 25, 2014 at 21:30
  • 2
    @Aviv i think i'd say that's a case of "if your user removes the safty and triggerguard, it's no longer your fault that holstering the gun occasionally shoots them in the leg."
    – Weaver
    Commented Sep 25, 2014 at 21:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.