Providing Java library, but hiding some classes
Asked Answered
E

6

14

I am developing an application in Java ME that I want to provide as a library. Is there no way to hide classes that I don't want everyone to use, but is essential still in order for the library to work?

UPDATE: I get that I can omit the public specifier, but how can I structure the library itself while developing without creating different packages? I like to view different packages as different folders simply which allows me to structure the code in a good way. However, in some cases I might need to access classes in other packages so this is rather tricky. What does packages really represents? One idea might be to create "interfaces", but these has to be declared public so that means that foreigners might also implement the interfaces intended only for some processes inside the library, correct?

Evanthe answered 10/7, 2011 at 18:10 Comment(4)
Making the class final will only prohibit subclassing it. It will still be exposed.Foreandafter
Depends on what you mean by 'want' and how much trouble you want to go to. Access modifiers are pretty easy to get around with reflection for example.Equidistance
Yes but when I include the jar file of my API in Eclipse all classes show up if I expand the content of the jar file. So declaring them final is one part of the solution I guess, to really prevent anyone from using them. But if I have an API, perhaps I want to have different packages inside the API also. But declaring them without the public modifier means that I can't access different parts of the API how I want. What is the "normal" reason for creating different packages? I mean, I could place all code in the same package but the library would not be very structured then...Evanthe
softwareengineering.stackexchange.com/questions/256987/…Key
C
5

For setting up your library API you'll want to protect anything you don't want exposed. Do do this just omit the access modifier:

class fooBar {
    // do stuff here    
}

This will set the class access as 'default' which allows access from within the same package as well as from any classes which subclass fooBar.

Within your classes you will also want to lock down any access on your methods and members by marking them either private, protected or omitting the modifier so that they are 'default' as required.

  • private will allow access from the containing class only;
  • 'default' (no modifier) allows from within the containing class and containing package; and
  • protected will allow access from within the same class, package and any subclasses.

For anything that you have exposed (public) it is also good practice to mark it as final if it's not designed to be overridden.

Basically, lock down everything as much as you can. Smaller API's are easier to use and harder to break. If you find something needs to be exposed in the future, do it in the future. It's much easier to expand an API rather than deprecate parts of it.

Clayberg answered 15/7, 2011 at 4:6 Comment(3)
Thanks! But as you say, I can only use the class fooBar from within the same package. What is the usual way of structuring a Java project? I have been creating packages based on different things that the classes do. For instance, I have one package which I call com.comms where I store routines and classes for transmitting via sockets. Then I have another package (like application level) that uses the comms package. But I guess, for creating an API like this, I should have all classes inside the same package?Evanthe
Yes, how can you do when you have a library with multiple packages?Tragedy
By default classes have default visibility and hence visibility is within package only. You can also set it to be protected explicitly and it will also serve same purpose,Basso
E
3

If Java 9 is possible, use Jigsaw modules. If not, put every class on the same package, with package-level access for hidden classes, and use Maven modules to organize them.

I've done exactly that in my project called coronata, a Wii Remote java library. Almost all classes are in package com.github.awvalenti.bauhinia.coronata, but on different modules (which appear as projects on the IDE).

Visible classes are public. They are in modules:

  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib

Hidden classes have package-level acesss. They are in modules:

  • coronata-common
  • coronata-implementation-bluecove
  • coronata-implementation-wiiusej
Efficient answered 18/10, 2017 at 11:33 Comment(0)
G
2

You can make the classes package protected which only other classes in the same package can see. If this isn't feasible, then you can use ProGuard to mangle the classes and hide their implementations.

Greathouse answered 10/7, 2011 at 18:36 Comment(1)
You can't use the protected modifier for classes, only for members. The only way to limit access to your class is omitting the public modifier making it visible within its package only.Morphinism
M
0

Lets consider an Example:

If you have a class A, that you want to hide, and a class B, that uses the functionality of class A, then you can do this:

class B{
//Attribute and Methods

    //Inner class A
    class A{
      //Methods and Attributes.
    }

}

After doing this, you can create an Object of class A inside a method of class B and hence use it. Though the class will be hidden from other classes, it could still be used.

Mcbroom answered 11/7, 2011 at 8:26 Comment(1)
Making a class internal does not hide it from the outside world. You can still import it and use it. The package-level access that you have used, though, will hide the classes from other packages.Efficient
N
-2

Yes, there is.

Simply don't declare those classes public. In other words, omit the public keyword like so:

class Internal { // rather than "public class Internal"
    ...
}

By default, classes are only accessible within the package where they are defined.

Numerate answered 11/7, 2011 at 6:42 Comment(0)
F
-4

You need to make the classes that you don't want exposed protected. This will make them non usable from client code. Read more in the official docs

Foreandafter answered 10/7, 2011 at 18:23 Comment(2)
The part you need: leave out the 'public' keyword in the class declaration, then the class is only accessible to other classes in the same package.Doorjamb
You can't use the protected modifier for classes, only for members. The only way to limit access to your class is omitting the public modifier making it visible within its package only.Morphinism

© 2022 - 2024 — McMap. All rights reserved.