Introduction to Packages
In the previous blog we have learned about the different ways of obstructing objects, and also destructing them. If you want to visit the blog Object Construction & Destruction in Java. Suppose we want to group classes in the collection or if we want to avoid naming conflicts, or provide control access then we use Packages. Packages allow to group classes in a collection, and it also prevents conflicts in names, etc. In this blog, we will learn how we can create the packages and how we can use them.
Naming Packages
The main and important purpose of using packages is to ensure the uniqueness of the class names. For example, if we wish to create two classes with the same name i.e. AtrowelStudent considering that both classes are placed in different packages, then there will be no conflict. In order to maintain the uniqueness of the packages we must use an Internet domain name which is considered to be unique, but written in the reverse order. For example, if we take atrowel.com as a domain name and if we write it in reverse i.e. com.atrowel then it becomes the package name. We can add the project name such as com.example.atrowelpackage. If we want to add the class name i.e. AtroerlStudent, then it will become a fully qualified name as com.example.atrowelpackage.AtrowelStudent
Importing Classes
Suppose the class is defined and wants to use all the other classes, then it can use them from its own package and also it can access all the public classes from other packages. There are two ways for accessing the public classes in other packages. The first way is using the fully qualified name followed by the class name. This way is tedious.
e.g.
The other way is to use an import statement. This way is the most commonly used way. The reason behind using the import statement is it gives us the shorthand to refer to the class in the package. Once the import is used then we don’t have to give the classes the full names.
We can import a particular class or even the whole package, we just need to add the import statement at the top of the code after the package statement. For example, we can import all the classes just by using the following statement.
e.g.
We can also use the specific class inside the package.
e.g.
We can also use asterisk(*) in the import statement, there will be no impact on the code. But if we write the class explicitly, the other programmer reading the code will know which class is used. Most of the time we import the package that we need without thinking too much about them. We should be careful when there are name conflicts in the package. For example, if java.util and java.sql packages are using Date class and suppose if we try to import both the packages in the code.
e.g.
If we want to use the Date class in our code then the compiler will give an error because it will get confused from which package the Date class should be used. We can solve this problem by importing that particular class in the import statement.
e.g.
But suppose we want to use the Date class in both packages, then we can do this by giving a fully qualified name to it.
e.g.
Static Import
We can also import the static methods and fields in the import statement. For example, if we add the directive at the beginning of the code, then no need to use the class name, we can just use its static methods and fields.
e.g.
In the above snippet we can see that we have imported the System class and have used its static method out.println() without using the System classes before the out.println() statement.
Adding Class into a Package
In order to add or place the class inside the package, we must put the name of the package at the top of the source code file, before the class definition in the code.
e.g.
If we don’t put the package name in the source code, then the class in that source file belongs to the unnamed package. The unnamed package means it doesn’t have any package name. We must place our source files in the subdirectory that matches the full package name. For example the source files in the com.example.atrowelpackage should be placed in the subdirectory com\example\atrowelpackage(Windows). All the class files will be placed in the same directory.
If we want to compile the program, then we need to change to the base directory and run the command.
When we compile the program compiler will automatically search the file com\example\atrowelpackage\AtrowelStudent.java and will compile it. We will take another example where we don’t have an unnamed package, but the classes are divided into several packages.
If we consider the above example, we still must compile and run the classes from the base directory(the directory containing the com directory).
e.g.
When the compiler compiles the source file, it doesn’t check the directory structure. For example, if the source file starts with the directive
We can still compile the file, even if the file is not contained in the directory i.e. com/atrowelcompany.
Access Specifiers
We have already learned about the public and private specifiers in our previous blog. public specifiers can be used by any class, private specifiers are used only by the class that defines them. If there is no public or private specifier, then the class or variable or method can be accessed by all methods of the same package. If the class has no access specifier, then the default specifier is set, which means it will be visible only within its own package. But for variables, this is not an appropriate way. Variables should be declared as private. Many times developers forget to write the private keyword before the variable, which makes it default and now that variable can be accessed by the methods of all classes. The problem here will be that it can be modified by all the methods of that class rather than the method that had the right to modify it. So the variables should be declared as private in order to maintain its integrity.