Java Custom exceptions: Package convention? - java

When creating a custom exception class (e.g. a custom runtime exception), is there a specific convention for where within the folder/package structure to create it?
Should all the custom exception classes be within the same package?

An exception class should always be defined in the same package as the classes which are capable of throwing it. Never create a separate package just to hold exceptions.
In general, a package should encapsulate a single major unit of functionality. Exceptions are part of that functionality.
Subpackages should only be created to limit access to classes and/or methods. This is done by creating "package access" classes and/or methods: they are neither public, nor protected, nor private. Having no access modifier means they are visible only to classes in the same package. If you don't have any such classes or methods, you probably shouldn't be making a subpackage.
Subpackages should not be created for:
grouping a few classes that happen to have some things in common. (Notice there's no java.text.format or java.net.socket or javax.swing.button package in Java SE.)
breaking up a package because it seems to have too many classes in it. (There's nothing wrong with having fifty classes in one package.)

Related

Adding an external class with the same package name and breaking encapsulation

I've run into this statement when I was reading a book on Kotlin:
With Java, the encapsulation can be easily broken, because external code can define classes in the same packages used by your
code and thus get access to your package-private declarations...
I'm not sure if I get this totally correct but does it mean can I somehow define a class in the same package with, for example, a third-party module that I depend on and then access it's package-private data? Or does it mean something else?

design of Java classes and packages

I have a context class -> prototype.context -> which apps can create objects of, but cannot extend. The system developer can however extend the classes to more types. The package of system classes would be prototype.system and prototype.dbengine . These classes should have full access to context objects, but other classes should not.
If I keep the fields in context class as package access, these classes cannot access it, because they are from a different package. So how should I name the packages so that the classes are available to other developers, and also have full access to system classes?
What you want is actually a simulation of the C++ friend-class feature. A nice trick is described here: https://stackoverflow.com/a/18634125/2886891
If you absolutely have to use package-private access and/or cannot use protected, then really the only option you have short of using public is to stick everything into the same package.
This is because in Java, "subpackages" don't really exist -- for example, java.util is an entirely different package than java.util.concurrent; thus, whether java.util.concurrent is called that or java.concurrent doesn't make a difference from the standpoint of access scope. In either case, classes in java.util.concurrent won't be able to access package-private members from java.util. The naming is only for convenience, and doesn't indicate any actual hierarchy.
Thus, no matter how you name your packages, you won't be able to access package-private members from another package.
Have the system and dbengine classes extend the necessary classes in context and set fields/methods that the system and dbengine classes need to protected.

Library level access modifier

I am creating a library (android). I keeping things as packages like
com.domain.libname.datamodel; com.domain.libname.exceptions; etc.
I want the freedom of initializing some data model objects within my library which public can read, but public should not initialize those objects. Though 'package' access modifier does this within a package, i would like to do this across packages within the same project/library.
Is there a way? Or is it indicates i am not packaging things in the right manner?
The package structure in Java is flat: If you want something to be visible outside of your package it will be visible to all packages; there is no way to restrict visibility to "subpackages" or to packages with a certain prefix.
My opinion is that a package should implement a feature, so that classes that have to cooperate can do so without having to expose needless cruft to the outside. This means that you wouldn't have "artificial" packages like "datamodel" or "exceptions"; instead the data models and exceptions would be in the package that actually needs them to implement a set of use cases. But I can see how in a large application or library that can become impractical.

Package and visibility

I'm making an SDK and I'm trying to separate classes to different packages, those classes use some other shared classes. The issue is if I made the shared classes public everyone will be able to see them, not only my classes. What's the right way to make them only accessible by my application?
Example :
Package a
MyClass1
Package b
MyClass2
Package c
public MySharedClass
Because c is public MySharedClass will be able to access it, but the issue is that it will also will be visible to the world, how could I prevent that?
Create a package that is documented as an internal package, not to be used by clients.
There is no way in Java to make a class public only for certain packages: It either is public for everyone or package-private (public only in the declared package).
I think there's a proposal for modules to allow better control in the visibility of classes, but we'll have to wait, at least, for Java 8.
The packages are all "public" in Java, what you can protect is the classes within a package. For limiting the visibility of a class to only a given package, declare it like this (without the public visibility modifier):
class MyClass {
// ...
}
In that way, only the classes in the same package as MyClass will be able to see it.
Non trivial:
The shared classes could be defined by a generally accessible set of interfaces. The actual implementation should be loaded explicitly via a Classloader. After that, simply apply Java Security Management mechanisms to control access to the implementation classes. Anyone can see the interfaces and access to actual implementation will be restricted to your SDK.
(A varient of above is what every web/app server needs to do. How do you think Tomcat prevents you from accessing some other app's "public" classes?)
edit: note above is a runtime mechanism. There are static (post) compile approaches as well. APT for example, could be effective here. Naturally I am not addressing a restructuring of your package (in OP) and only addressing how to secure access to a general approach. But these are a bit 'hacky' -- the runtime mechanism of class loading is canonical and imo strictly more correct.
If the class is shared by classes from two different packages, it could be a good indication that these two classes should be in the same package, along with the shared class, which wouldn't be public and would thus only be usable by classes of the same package.
If it's really not an option, just document the shared class appropriately, to indicate that it's not supposed to be used outside of the SDK internal code, that it's subject to changes in future versions, and make it even clearer by naming the package "internal" or somthing like this.
protected modifier can use,in case of your class will access only in same package. otherwise there is no possibility.

Does Java provide 'friend' access modifier?

I wonder if Java provides 'friend' (as in C++) access modifier? Someone said we can tread 'friend' as default modifier in Java. Is it true?
The default access modifier in Java allows members to be accessed by any code in the same package.
There is no such keyword (in Java) named as -
“Friendly”
The default access modifier has no keyword, but it is commonly referred to as “friendly.” It means that all the other classes in the current package have access to the friendly member, but to all the classes outside of this package the member appears to be private. Since a compilation unit – a file – can belong only to a single package, all the classes within a single compilation unit are automatically friendly with each other. Thus, friendly elements are also said to have package access .
Friendly access allows you to group related classes together in a package so that they can easily interact with each other. When you put classes together in a package (thus granting mutual access to their friendly members; e.g. making them “friends”) you “own” the code in that package. It makes sense that only code that you own should have friendly access to other code that you own. You could say that friendly access gives a meaning or a reason for grouping classes together in a package. In many languages the way you organize your definitions in files can be willy-nilly, but in Java you’re compelled to organize them in a sensible fashion. In addition, you’ll probably want to exclude classes that shouldn’t have access to the classes being defined in the current package.
There isn't a friendly modifier in Java. In Java it is called package private. And it is the default modifier. It allows members of the same package to access it.
As others have said, there is no friend access, but package based access is available.
However OSGI, and the (hopefully) forthcoming Super Packages attempt to extends this concept to classes in a some higher lever grouping of classes.

Categories

Resources