Packages and Access Modifiers
Packages
Java provides a package to manage classes with similar features and similar nature. All Java APIs belong to a specific package (usually a package with names beginning with java).
Now let's look at creating a class that belongs to a specific package.
Account.java
package javabank; public class Account { private String accountNo; private double balance; public void deposit(double amount) { balance = balance + amount; } public void withdraw(double amount) { balance = balance - amount; } public long getBalance() { return balance; } public static void main(String[] args) { System.out.println("Package Test!"); } }
package javabank;
This first code makes the Account class belong to the package named javabank.
When compiling the Java source that declares the package, you must specify -d followed by the directory where the compiler will generate the bytecode. If you omit the -d option, the bytecode will not belong to the package.
Create the Account.java source file in the C:\javaApp\bank\src\javabank directory.
The bin directory is where the compiler generates the bytecode, and the src is where you keep Java source files.
Create a subdirectory with the package name in src and place a source file there. Most developers manage source files this way.
Note: Package names are usually in reverse order of domain names.
The package name preferably includes two or more dots.
If you want, the Log class belongs to the package named net.java_school.commons, create subdirectories like below and place source files there.
Let's get back to Account.java.
Go to C:\javaApp\bank\src\javabank and compile as below.
C:\javaApp\bank\src\javabank>javac -d C:/javaApp/bank/bin Account.java
The path separator following the -d option can also use the / (slash), even on Windows systems. Of course, you can also use the path separator in the Windows system \ (backslash).
After compiling, go to the C:\java App\bank\bin and check whether the Account's bytecode exists.
C:\ Command PromptC:\javaApp\bank\bin>dir 2008-03-07 12:06 PM <DIR> javabank
You will not see the Account's bytecode in the bin. Instead, you will see the javabank directory. You can find the Account's bytecode in this javabank subdirectory.
Suppose you specify the C:\javaApp\bank\bin directory with the -d option when compiling a java source file. In that case, the compiler will make subdirectories with the package name in the C:\javaApp\bank\bin directory and create Account.'s bytecode there.
JVM understands the javabank.Account bytecode is in the C:\javaApp\bank\bin directory.
If you make the Account.java that declares the package name javabank and compile it with the -d option, the fully qualified class name (FQCN) of the bytecode is javabank.Account.
If you write code that uses the Account bytecode in other Java sources, you should write javabank.Account, which is the FQCN of Account, in your code.
The same is true when you run the bytecode. To run the Account bytecode, you need to run it using the Account's FQCN in the C:\javaApp\javabank\bin directory because JVM understands javabank.Account bytecode is in the bin directory.
C:\ Command PromptC:\javaApp\bank\bin>java javabank.Account Package Test!
To run a bytecode in a directory that is not the bytecode, you need to tell JVM where the bytecode is. The way to tell JVM that the bytecode location is to use the Java interpreter's classpath or cp options.
When running the Java interpreter (java.exe), the class loader finds all bytecodes that make up the Java program and loads them into the memory. If it can not find even one bytecode, it prints an error message that the execution fails and can not find the bytecode.
If you do not specify the classpath or cp option, the class loader looks for your bytecodes only in the current directory.
The class loader already knows the path of Java APIs, such as the java.lang.String or the java.lang.System. So you don't need to specify the path of Java API bytecodes using the classpath or cp option.
Below is running javabank.Account in the C:\Program Files directory.
C:\ Command PromptC:\Program Files>java -classpath C:/javaApp/bank/bin javabank.Account Package Test!
-classpath followed by the path where the bytecode is.
In the above case, the classpath path is absolute.
The classpath path can be either absolute or relative.
C:\Program Files>java -classpath ../javaApp/bank/bin javabank.Account Package Test!
One dot is the current directory.
Two dots refer to the directory one level above.
The Java compiler (javac.exe) also has the classpath or cp options. You can replace the classpath option of javac.exe or java.exe with the cp option. The Java compiler uses these options to check whether your source uses other bytecodes properly.
When compiling, let's walk through an example where you need to use the classpath option.
The following is a new class to create.
Log.java3
package net.java_school.commons; public class Log { public static void out(String msg) { System.out.println(new java.util.Date() + " : " + msg); } }
Log's out method is a static method. We cover the static keyword in the 'static' chapter.
Compile Log.java.
C:\javaApp\commons\src\net\java_school\commons>javac -d ^ C:\javaApp\commons\bin Log.java
Next, modify the Account class to use the Log class.
The FQCN of the Log class is net.java_school.commons.Log and should be written to the source as well.
public void deposit(double amount) { balance = balance + amount; net.java_school.commons.Log.out(amount + " dollars have been deposited."); net.java_school.commons.Log.out("Balance is $ " + this.getBalance()); } public void withdraw(double amount) { balance = balance - amount; net.java_school.commons.Log.out(amount + " dollars have been withdrawn."); net.java_school.commons.Log.out("Balance is " + this.getBalance()); } public static void main(String[] args) { Account myAccount = new Account(); myAccount.deposit(10000); myAccount.withdraw(500); }
Recompile Account.java.
C:\ Command PromptC:\javaApp\bank\src\javabank>javac -d C:\javaApp\bank\bin ^ -classpath C:\javaApp\commons\bin Account.java
Run the javabank.Account.
C:\ Command PromptC:\javaApp\bank\bin>java -classpath .;C:\javaApp\commons\bin ^ javabank.Account
Our Java programs consist of two bytecode except for Java APIs. (javabank.Account and net.java_school.commons.Log)
Because these two bytecodes aren't the same directory, you need to specify the location of the two bytecode with the classpath option both at compile and run times.
Notice that a comma (.) is added to the classpath at runtime, unlike compile time. The class loader looks for bytecodes only in the classpath. So, you need to add the current directory with the Account bytecode to the classpath.
How to add external Java libraries to your Java program
Most external Java classes are jar-compressed files.
Let's create the log bytecode into a jar file using jar.exe.
Execute the following command in the directory where the Log bytecode is.
C:\ Command PromptC:\javaApp\commons\bin>jar cvf java-school-commons.jar .
Move the java-school-commons.jar file to the C:\devLibs directory.
To add the bytecode in the jar file to the classpath, you need to add the full path of the jar file to the classpath. It is impossible to add only specific bytecodes in the jar file to the classpath.
Run the javabank.Account.
C:\ Command PromptC:\javaApp\bank\bin>java -classpath ^ .;C:\devLibs\java-school-commons.jar javabank.Account
Access Modifiers
The access modifiers decide whether it is accessible from the outside. The access modifiers provide a two-step access control.
Level 1 access control is when class declarations use access modifiers.
The public access modifier in the class declaration of the Account
package javabank; public class Account { //... }
The package-private access modifier in the class declaration of the Account
package javabank; class Account { //... }
public
Any class can refer to this class.
package private
It can be referenced in same package classes.
The following is a code example in which example.BankSystem class refers to javabank.Account class.
package example; public class BankSystem { public void deposit(javabank.Account account, double amount) { account.deposit(amount); } }
Suppose you have created a Bank, Customer with the public access modifier in the javabank package. Any class can reference Bank, Customer, and Account. (+ Stands for public)
As shown in the figure, the BankSystem in the example package can refer to all classes in the javabank package. So, you can declare variables type of javabank.Account in the example.BankSystem source code. You can use the import statement to reduce javabank.Account to Account in the class body.
package example; import javabank.Account; public class BankSystem { public void deposit(Account account, double amount) { account.deposit(amount); } }
Suppose you have changed the public to the package-private access modifier in Bank, Customer, and Account class declaration.
In this case, BankSystem cannot refer to Bank, Customer, or Account. So, you will get compile errors if you write the code to BankSystem refer to Bank, Customer, and Account.
Level 2 Access Control is when field and method declarations use access modifiers.
Note: A field is a data structure declared in a class body.
It's easy to understand if you think everything is not a method in a class body.
public
The field or method is accessible from all packages.
protected
The field or method is only accessible from the same package.
In addition, subclasses can access protected fields and methods of the superclass even if the subclass belongs to a different package from the superclass. So, the protected access modifier is more accessible than the package-private access modifier. For the protected access modifier, it's a good idea to review the description below after studying inheritance.
In the figure below, # means protected.
package-private
The field or method is only accessible from the same package.
private
The field or method is not accessible from the outside.
Encapsulation: Make an object's data accessible only through public methods
Encapsulation allows you to see only the essential parts of the object when viewed from the outside.
When designing a class, We should keep the following as it is the basis of object-oriented programming.
- Declare variables as private if they store the object's properties.
- Declare public methods for private variables.
Below is encapsulated member class of a website.
User.java
package net.java_school.user; public class User { private String username; private String password; private String fullName; private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFullName() { return FullName; } public void setFullName(String fullName) { FullName = fullName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Eclipse
All subsequent chapter examples will use Eclipse.
With Eclipse, you can manage your sources with the directory structure you have practiced before, and you do not have to worry about the classpath when compiling.
http://www.eclipse.org
Download the Eclipse install file and install Eclipse IDE for Java EE Developers.
Run
Eclipse asks you where to specify your workspace.
Workspaces contain and manage one or more projects.
Specify your workspace.
Click the OK button.
You can see the following welcome message.
For reference, this article summarizes the welcome page tutorial.
Close the welcome page.
The following workbench appears.
Eclipse Terminology
Workbench
It refers to the entire window seen in Eclipse.
The window has four areas, which are called views.
Including all of the views is called a perspective.
The above is a Java perspective screen.
This perspective consists of the views needed to develop a Java program.
Use the Open Perspective menu bar button in the top right corner to change the perspective.
It shows the resources (packages, classes, external libraries) belonging to the Java project.
Hierarchy ViewIt shows Java's inheritance structure.
Outline ViewIt shows the structure of the source file in the editor.
Editor ViewIt has the source code editor.
Problems ViewIt shows compilation errors or warnings.
Javadoc ViewIt shows the Java documentation for the selected part in the Package Explorer or Outline View.
Declaration ViewIt shows briefly how the selected part of the editor is declared.
Practice the Java example using Eclipse
Make sure it is a Java perspective.
In Eclipse, the Java source must belong to the project.
Select File - New - Java Project from the menu bar or click the leftmost button on the toolbar to create a Java project.
Name the project HelloWorld.
Other settings do not have to be specified.
Eclipse manages sources in the src directory and bytecodes in the bin directory.
Click Finish, and the HelloWorld project will be created and displayed in the Package Explorer.
Click second on the toolbar menu below.
Type net.java_school.example in the package name and click Finish.
You will see the package in the Package Explorer view.
Select the net.java_school.example package with the mouse and click the last button on the right of the toolbar menu below.
Name a class, HelloWorld.
Check the public static void main (String [] args) checkbox.
Click on Finish and implement the main method in the editor, as shown below.
HelloWorld.java
package net.java_school.example; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World !"); } }
If you have saved the code, you do not have to compile it because Eclipse continues to compile your code in the background. Also, you can see compilation errors right at the Problem View while you write the code.
To run the bytecode, right-click the HelloWorld class in the Package Explorer, open the context menu, and select it as shown below.
The Console View prints Hello World!.