Java language has thousands of built-in classes. Java packages are a nice way to organize classes, interfaces, enumerations with similar functionality to groups. Packages help to avoid name conflicts. A code with packages is easier to maintain. They are the way of encapsulation. It can be compared to pieces of paper sorted in different folders by content. You don’t need to search for some information through all the papers. You will use a particular folder. The same with code. You need to tell in what package to look to find code. Therefore, packages make search and usage of classes, annotations, interfaces, enumerations easier.
This code doesn’t compile, because we don’t know the package to search the class Date.
public class ImportExample {
public static void main(String[] args) {
System.out.println(new Date()); // DOES NOT COMPILE
}
}
We will get an error that the Date cannot be resolved to a type. The compiler cannot find the class Date(). The code can be fixed if you provide the fully qualified name:
public class ImportExample {
public static void main(String[] args) {
System.out.println(new java.util.Date());
}
}
Usually, your developer’s environment (Eclipse, NetBeans, etc) will give you a hint that you have missed an import. So, you can fix this error in another way. You will be able to compile after adding the import:
import java.util.Date;
public class ImportExample {
public static void main(String[] args) {
System.out.println(new Date());
}
}
As you can see, package names are hierarchical, sub realm names are separated by dots. To import then, we use the reserved word import. In the current case, we are importing just one class from the package java.util. But, there is also another way.
Wildcard
Let’s assume the situation that we need to import two classes from the same package. For example, ArrayList and Date from package java.util:
import java.util.Date;
import java.util.ArrayList;
public class ImportExample {
public static void main(String[] args) {
ArrayList<Date> list = new ArrayList<Date>();
list.add(new Date());
System.out.println(list.size());
}
}
What if developers need to import 3 or more classes from the same package together? For this purpose they can use the wildcard *, that matches all classes in the package:What if developers need to import 3 or more classes from the same package together? For this purpose they can use the wildcard *, that matches all classes in the package:
import java.util.*;
This will import all classes from the package java.util, but not from child packages like java.util.concurrent, java.util.regex, java.util.stream, etc.
Listing the classes used makes the code easier to read, but using the wildcard can shorten the import list. Including so many classes does not slow down your application. The compiler can figure out what is actually needed.
Let’s try to write all the imports together:
import java.util.Date;
import java.util.ArrayList;
import java.util.*;
In this case, your developer’s environment will notify you that the import of java.util.* is redundant.
It is illegal to use more than one wildcard in one import and it must be at the end. This does not compile:
import java.*.*; //DOES NOT COMPILE
Also, this type of import is wrong:
import java.util.ArrayList.*; //DOES NOT COMPILE
Naming Conflicts
Using of packages has one more reason. Class names don’t have to be unique across all of Java. There are two implementations for class the Date in Java language. They are in the packages java.util and java.sql.
If you include both imports, your code would not compile:
import java.util.*;
import java.sql.*;
public class ConflictsExample {
public static void main(String[] args) {
System.out.println(new Date()); // DOES NOT COMPILE
}
}
- You can fix imports on the top of your class:
import java.util.Date;
2. You can write a package that you want to use right in the code of your class:
System.out.println(new java.util.Date());
This code also doesn’t compile:
import java.util.Date;
import java.sql.Date;
This example will work even without imports:
public class ConflictsExample {
java.util.Date date;
java.sql.Date sqlDate;
}
Consequently, when we have a naming conflict, we need to use a fully qualified class name for at least one of the classes.
Creating a New Package
Let’s look at the new package creation. The directory structure on your operating system is related to the package name. Look at the example below.
Windows directory:
C:\temp\my\test\ClassA.java
The ClassA code:
package my.test;
import java.util.Date;
public class ClassA {
public void printDate() {
System.out.println(“Current date: ” + new Date());
}
}
Our ClassA is inside package mytest. To define a package we have to use Java reserved word package. We have to use this statement before the class declaration and before all our imports. It has to be the very first line of code in our file.
If you want to import the ClassA you have to write:
import my.test.ClassA;
or
import my.test.*;
Assuming that a class ClassB is using our class ClassA. The class ClassB is in another package my.test.usage:
package my.test.usage;
import my.test.ClassA;
public class ClassB {
public void callClassA() {
System.out.println(new ClassA().printDate());
}
}
Let’s look at more examples to understand how packages correspond with the directory structure.
Package: edu.mytest.subpackage.*
Windows path: C:\temp\edu\mytest\subpackage
Package: com.example.myapplication.*
Windows path: C:\temp\com\example\ myapplication
All packages and sub-packages have their own directory. Sub-packages are not imported by default. You have to import them explicitly. And vise versa, members of a sub-package have no access to its general package. They are considered as different packages. In other words, package my.test have to import package my.test.usage to have access to its java classes. Similarly, package my.test.usage have to import package my.test.
———————-
public class StaticExample {
public static void main(String[] args) {
System.out.println(Math.sqrt(9));
}
}
In code with static import we can remove class name before the method sqrt:
import static java.lang.Math.sqrt; // STATIC IMPORT
public class StaticExample {
public static void main(String[] args) {
System.out.println(sqrt(9));
}
}
In case you want to use several static methods or variables from the same package you can use a wildcard:
import static java.lang.Math.*; // STATIC IMPORT with WILDCARD
public class FutureExample {
public static void main(String[] args) {
System.out.println(sqrt(9));
System.out.println(abs(9));
System.out.println(PI);
System.out.println(E);
}
}
Build-in packages
Java platform has a lot of build-in packages that are free to use.
java.lang is a basic package. It is allowed to use without an import statement. This package contains fundamental types and basic functionality. Here is some of them:
- String, Object, Enum and wrappers for primitive types(Integer, Boolean, Byte, Double, etc);
- Class Math that contains methods for performing basic numeric operations (logarithm, square root, trigonometric functions, etc ) ;
- Interface Runnable and class Thread, as the ways to create a thread;
- StringBuilder and Exception for operations over Strings;
- Basic exceptions: RuntimeException, NullPointerException, NumberFormatException, IndexOutOfBoundsException, ClassNotFoundException, IllegalArgumentException, etc.
- Basic errors: Error, OutOfMemoryError, StackOverflowError, IllegalAccessError, AssertionError.
- Basic annotations: Deprecated, Override, SuppressWarnings.
- Popular interfaces: AutoCloseable, Cloneable, Iterable<T>, Comparable<T>.
java.util is a collection of data structure classes.
- Classes of collections framework(Collection<E>, List<E>, Iterator<E>, Set<E>, Map<K,V>, ArrayList<E>, HashMap<K,V>, LinkedList<E> , etc).
- Some date and time facilities (Calendar, Date) .
- Internationalization and miscellaneous utility classes (a string tokenizer, a random-number generator, and a bit array).
java.io is a package that provides facilities for system input and output through data streams, serialization and the file system (File, FileInputStream, FileOutputStream, Serializable, Console, InputStream, OutputStream, Closeable. Reader, Writer, etc).
java.nio defines buffers, which are containers for data.
java.net is a package that contains classes for implementing networking applications.
java.security contains classes and interfaces for the security framework ( key generation, encryption, decryption, networking operations, sockets, etc).
java.sql is a package that provides the API for accessing and processing data stored in a data source. Usually, this package is using for relational databases.
java.awt contains facilities for creating user interfaces and for painting graphics and images.
4 Responses