Java private classes between sub-packages - java

My Java library is made of a few sub-packages (com.example.lib.api, com.example.lib.imp, com.example.lib.util,...).
The classes in api use classes A and B from imp. The classes in imp use class C in util.
I am forced to make A, B and C public, but I don't want them to be exposed to users of my library. Not hiding anything, my library is open source, but minimal APIs are simpler to understand.
Is there a way around it?

In Java 9 you will be able to control which packages are exported from a JAR. This way you can make them public, but not available to anyone else.
For now you can't control this. You either put everything in one package or rely on the documentation to make it clear they should not be used. e.g. jdk.internal assumes no one should use these except the JDK.

You cannot use a private class in any other package . Instead the class can be made public and the methods and variables can be made protected . So in this case the classes can be extended where they need and the contents in the class can be accessed only by the sub classes which extended it.

Related

How can I create a pseudo interface or class for "joining" real classes

I'd like to declare a variable that could be an object of x.y.z.z.y.Foo, x.y.z.z.y.Bar or x.y.z.z.y.Baz. If these classes were maintained by me, I'd create a class (e.g. x.y.z.z.y.Nice), so my variable would be declared as Nice variable. But the x.y.z.z.y package is a 3rd-party library (https://github.com/kubernetes-client/java, to be exact), so I can't make this library's classes implementing the Nice interface.
Is there a way to define some pseudo-interface/-class to have been assured that the variable could hold an object of certain classes of a 3rd-party library?
Thanks in advance!
I'd probably write a facade class to encapsulate the use of the 3rd-party package. Then that facade class and your other classes can all implement the Nice interface.
(A side benefit is that if you decide to switch to using some other 3rd-party package instead of the current one, you only have to change the facade class, not everything that uses it.)

Java packages and classes

I'm building a very simple library in Java, which will be packaged in a single Jar. It should only expose one class: World. The World class uses the subclasses of the Block class, which is in the same package (com.yannbane.a), and doesn't provide a lot of functionality itself, but needs to be extended. I planned to create another package, com.yannbane.a.blocks, which would have all the block types (subclasses).
The directory/package structure should, therefor, look like this:
com/
yannbane/
a/
World.java
Block.java
blocks/
Brick.java
Stone.java
However, in order for the subclasses of Block to actually extend the Block class, I needed to make the Block class public. This destroys my goal of having the Jar file only expose a single class, World. I also need to make the subclasses public so the World could use them.
How can I retain this package and directory structure but still have my Jar only expose the World class, not other classes?
If this is a matter of encapsulation, and all you want to expose to the world is the "World" class, then it does not matter if the unexposed classes are located in the same package or if they are inner classes in the same package.
At any rate, they will not be accessible to the users of your API. I believe encapsulation is more important here than the "logical" organization that you want to give your files. Because if you locate all your classes in the same package, then you will not have these problems and you will achieve the level of encapsulation that you are seeking. Perhaps what Java is telling you is that these classes are so inherently related that you should place them all in the same package.
Make the classes public but their constructors protected.
You still technically expose the classes - other packages are aware of them - but no other packages can instantiate those objects.
Even though the Block subclasses are in a different package from Block (com.yannbane.a and com.yannbane.blocks) they will be able to invoke the protected parent constructor, because protected members are accessible from the same package or from an inheriting object.

Do I need a rebuild for Java here?

I have a ClassA that is being used my many components and libraries in various areas of a project.
Now I need to add an extra member to this class but since it will not be needed/used by other areas it does not feel proper to extend the class.
If I add the member to ClassA instead of extending would I have any issues? Would everything need to be rebuild?
Adding a new member preserves binary compatibility, see also Chapter 13. Binary Compatibility of the Java Language specification.
Obviously you need to rebuild the modified class, but not classes which are using the modified one.
Unless your existing contacts and interactions between ClassA and other classes BREAK, there should be no issue. But if you change signature of a method that is used by other classes you could get a runtime error while locating the old version of method as it does not exist anymore.
If you change your Class A, obviously a rebuild is necessary. To minimize the impact you can extend the class A and use the subclass for your work. The other components and libraries will continue to keep using your Class A, while your code should now refer to the sublcass which has the added member.
Again, it depends on how you define your objects.

Non-public top level class in Java

What's the reason of making top-level class non-public in Java?
Let's say we have Foo.java, there could be
class Foo {
}
or
public class Foo {
}
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages). But anyway, are there any reasons why someone may want to do as in the first code sample?
UPD: What cons I see in the former solution: nobody cares that it's non-public. That class can be simply extended by some other public class in the same package later, then, non-public part of the class may bring you visibility/access issues.
Here is an example.
No one needs to know about existence of our ConcreteDocument.
DocumentIF.java
public interface DocumentIF {
}
ConcreteDocument.java
class ConcreteDocument implements DocumentIF {
}
DocumentFactory.java
public class DocumentFactory {
public DocumentIF createDocument() {
return new ConcreteDocument();
}
}
Typically, you make a class package-private because you don't want the class to be used outside the package. When a top-level class isn't public, it's private to the package.
Say you have a package with a number of classes that must communicate the same sort of data with one another. But this data structure is an implementation detail and so you don't want it being used by user code. Making the transfer class package private maintains this sort of package level encapsulation.
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages).
That seems to me to be reason enough to use it if you want to keep the class private to that one package.
Just noticed another use! It seems you can only have one public top-level class per code file, but any number of non-public top-level classes. Haven't verified it personally, but if true that could be quite useful to prevent cluttering your project folder and to group classes with related functionality that aren't needed outside of the package.
Classes without a public or protected modifier are only visible inside the package they reside. If you think of components and interfaces there is a reason for leaving out the public modifier. Let's say you have a public class MyCompontent that internally uses other classes, but does not want to publish those to the outside world (users of the component) it makes sense to leave out the visibility modifier.
It is considered good design to keep the visibility of a class to the most minimum required. The reasons that I can think of:
The class can easily change in the future without causing breakages in external packages as the external packages do not have access to the class. In this regard it might be even better to start off a class by making it a private inner class.
The class being package visible cannot be extended by classes in external packages. This again makes it easier for this class to change without causing breaking changes in external packages. If this class was not meant to be extended then it would be even better to make this final.
A public visible class becomes a part of the exported API of your library. If you are a library designer, it is better to keep your exported API as small as possible because you do not want to confuse your consumer with un-necessary classes/details. Item 1 would again hold good in this case.
The book "Effective Java" by Josh Bloch is an excellent reference for Idiomatic Java code and design.

How to use Java access modifier properly in library development

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 organize.
How do I do this? How do people handle this problem?
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.
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?
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.
i think i understand your question, and the answer is that there is no way to do that in java up to now!
there are some tricky ways but they invovle dirt coding.
look here
http://openide.netbeans.org/tutorial/api-design.html#design.less.friend

Categories