views:

84

answers:

4

I'm developing a library which the other programmer will import and use it for their purposes.

I'm confused about the objective of Java access modifier.

The problem is that I have classes below

  • ClassA in package org.mylibrary
  • ClassB in package org.mylibrary.internal

ClassA needs to resolve ClassB so ClassB need to be public class.

However,from library user view, I don't intend ClassB to be visible outside my library. Because it shouldn't be and don't need to be initiated by the user.

I think of moving ClassB to package org.mylibrary and make it package-private class.

If I move it to the same package, it would be a mess and difficult to organize because I have many classes in this scenario so there will be many .java files in a big one package.

Normally I put the classes in packages grouped by category or layer and I think it's easy to orgranize.

How do I do this? How do people handle this problem?

+1  A: 

Assuming ClassB is a test package with unit tests:

Why does ClassB need to use it. Normally test classes use the regular classes, not vice versa.

In general, the recommendation for test classes is to put them into the same package as the regular classes, but maintain the .java files in a parallel directory hierarchy (i.e. you have src/org/mycompany/MyClass.java , and test-src/org/mycompany/MyClassTest.java ). That way, to Java both are in the same package and can access each other, and for release builds you just don't compile the test classes (or don't even check them out) - that way everything is nicely separate.

If this does not apply in your case, maybe you could edit your question with more detail?

sleske
Sorry for misleading. It's not unit test. The package name is example. I've changed it.
teerapap
See also http://junit.sourceforge.net/doc/faq/faq.htm#organize_1
trashgod
+1  A: 

It is difficult to give concrete advice since you give so little info about the roles of and relationship between ClassA and ClassB. However, one general solution (which is almost always used as part of eliminating dependencies) is to hide ClassB behind an interface. Then ClassA uses only that interface, so it is not anymore directly dependent on ClassB. ClassB can be made package private, its instances produced by e.g. a factory, or dependency injected into ClassA.

Péter Török
Thanks for this suggestion. So instead of expose the ClassB to public, a factory of ClassB should be public then?
teerapap
@teerapap, yes, or to be precise, a factory of `InterfaceB`.
Péter Török
+1  A: 

It would be a mess and difficult to organize because I have many classes in this scenario.

Do you mean that the java file look messy? You can split the internal classes in a different .java file.

ClassA.java

package org.application;

public class ClassA {
}

Internal.java

package org.application;

class ClassB {
}

class SomeOtherInternalClass {
}

Hope this helps.

bdhar
No, I don't mean the file look messy. I mean the package looks messy because there are many java files in the same package.
teerapap
A: 

A follow up to this question - how does one cope with poorly written libraries, which expose much of their internal dependencies to other packages in the same library? In particular, if I have some third party code that I don't wish to directly modify, how do I HIDE the public methods that I wish to restrict?

In .NET land, this is trivial, but I simply can't find an answer in java.

calandale
What you have written as "Your Answer" is not an answer at all. You should write your own new question, and you could reference this question with a link.
Stephen P