6

This question already has an answer here:

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?

marked as duplicate by gnat, GlenH7, Dan Pichelman, amon, user40980 Sep 26 '14 at 20:55

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

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

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.

  • 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 Sep 22 '14 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 Sep 22 '14 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. – Winston Ewert Sep 25 '14 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." – StarWeaver Sep 25 '14 at 21:50

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