What We Will Cover
Illuminations
Homework Questions?
Homework Discussion Questions
- How did the functional approach in assignment 3 compare to the object-oriented approach in assignment 4 in your opinion?
- What are the benefits of an object-oriented approach so far?
- If we were to add another shape class to program, would any changes be required for the existing shape classes? To
ShapeTester?
^ top
5.1: Static Methods and Variables
Learner Outcomes
At the end of the lesson the student will be able to:
- Code static fields and methods in a class
- Call static fields and methods from other classes
- Describe when to use static fields and methods
|
^ top
5.1.1: Static Methods
- Java has both
static methods and variables
- Static members do not belong to objects, but to the class itself
- So what does this mean?
- First of all, it means that you can call a static method without creating an object
Coding Static Methods
Calling Static Methods
- Although a static member does not require a calling object, it does belong to a class
- To call static methods, you can use the class name, a dot (period), the method name and a set of parenthesis with any required arguments
- For example, if the above method was defined in the
Circle class we would call it using:
double largeArea = Circle.area(largeRadius);
- It is possible to call static methods using an object reference
- However, that style is confusing and it is better to use the class name
- Note that static methods can NOT call regular methods
- This is why you cannot call regular methods from the
main() method
- If you try to call a regular method from a static method, you get a message like:
non-static method cannot be referenced from a static context
- Similarly, you cannot access instance variables from a static method
- If you try to use an instance variable, you get a message like:
non-static variable cannot be referenced from a static context
- Thus a good use of static methods is when you can obtain all the needed information for the calculation with parameters
- The following shows static methods defined in a class and a test class that calls the static methods
Example Defining static Methods
1
2
3
4
5
6
7
8
9
10
11
|
public class StaticExample {
public static final double PI = 3.14159265358979;
public static double area(double radius) {
return radius * radius * PI;
}
public String toString() {
return "PI=" + PI;
}
}
|
Example Calling static Methods
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class StaticExampleTest {
public static void main(String[] args) {
double radius = 3;
double result = StaticExample.area(radius);
System.out.println(result);
// This also works but the style is confusing
StaticExample se = new StaticExample();
result = se.area(radius);
System.out.println(result);
System.out.println(se);
}
}
|
^ top
5.1.2: Static Variables
- A class can have static variables as static methods
- Like static methods, a static variable belongs to the class as a whole and not to objects individually
- With instance variables, each object has its own copies
- However, with static variables all objects share a single variable
Coding Static Variables
Accessing Static Variables
- Any method can access the value of a static variable
- This includes static methods as well as instance methods
^ top
5.1.3: Example Using Static Methods and Variables
public ConstructionCounter() {
numObjs++;
}
Also need a method to retrieve the count
public static int getNumObjs() {
return numObjs;
}
Since the getNumObjs() method is static, we can call it without instantiating an object:
System.out.println("Initial count: " + getCount());
After instanting several objects, we call the method again to retrive the count of objects instantiated
We can experiment with the following example code
Also, the textbook has an example counting turns in a game
Example Using static Methods and Fields
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class ConstructionCounter {
private static int numObjs = 0;
public ConstructionCounter() {
numObjs++;
}
public static int getCount() {
return numObjs;
}
// For testing
public static void main(String[] args) {
System.out.println("Initial count: "
+ getCount());
ConstructionCounter c1 =
new ConstructionCounter();
ConstructionCounter c2 =
new ConstructionCounter();
System.out.println("Number constructed: "
+ getCount());
}
}
|
^ top
5.1.4: Mathematical Methods
Commonly Used Math Methods
| Name |
Description |
Example |
Result |
| abs |
absolute value |
Math.abs(-3.9)
Math.abs(3.9) |
3.9
3.9 |
| exp |
exponent |
Math.exp(1.0) |
2.718... |
| log |
natural log |
Math.log(10.0) |
3.20... |
| pow |
powers |
Math.pow(2.0, 3.0) |
8.0 |
| sqrt |
square root |
Math.sqrt(4.0) |
2.0 |
Rounding Methods of the Math Class
| Name |
Description |
Example |
Result |
| ceil |
ceiling: round up |
Math.ceil(3.3)
Math.ceil(3.7) |
4.0
4.0 |
| floor |
floor: round down |
Math.floor(3.3)
Math.floor(3.7) |
3.0
3.0 |
| round |
round: round off |
Math.round(3.3)
Math.round(3.7) |
3.0
4.0 |
Using Mathematical Methods
- How are mathematical methods evaluated?
- Whatever is within the parenthesis of the method call is evaluated first
- Thus, in the following example, we get the square root of
9.0
System.out.println(Math.sqrt(3.0 * 3));
If the method is used in an arithmetic expression, they are handled just like a number of the type returned
For example, in the following, the value 4.0 is stored in the double variable num:
double num = 1 + Math.sqrt(3.0 * 3.0);
System.out.println(num);
Note that the method evaluates the sqrt(3.0 * 3) before adding it to 1.0
Thus methods have a higher precedence than arithmetic operators
Static Imports
- Static import is a Java feature that simplifies references to static variables and methods of a class
- When you import the static members of a class, you can access the
static members without using the class name
- For example, you could import the static fields and methods of the
Math class as shown in the following example
Example of Static Imports
1
2
3
4
5
6
7
8
9
|
import static java.lang.Math.*;
public class MathImported {
public static void main(String[] args) {
System.out.println("E: " + E);
System.out.println("PI: " + PI);
System.out.println("pow(2, 3): " + pow(2, 3));
}
}
|
^ top
5.1.5: Static Initialization Blocks
- When you need more than one statement to initialize a static field, use a static initialization block
- A static initialization block is a normal block of code, enclosed in curly braces { }, and preceded by the keyword static
- The block runs as soon as any method of the class is called
- The following example shows the use of a static initialization block
Example of a Static Initialzation Block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class ConstructionCounter2 {
private static int numObjs;
static {
System.out.println(
"In the static initializer block");
numObjs = 0;
System.out.println("Initial count: "
+ getCount());
}
public ConstructionCounter2() {
numObjs++;
}
public static int getCount() {
return numObjs;
}
// For testing
public static void main(String[] args) {
ConstructionCounter2 c1 =
new ConstructionCounter2();
ConstructionCounter2 c2 =
new ConstructionCounter2();
System.out.println("Number constructed: "
+ getCount());
}
}
|
More Information
^ top
5.1.6: When to Use Static Methods and Variables
- When you need multiple objects of a class, use instance methods and variables
- If you only need a general purpose utility method, use static methods
- The Math class is a good example of when to use static methods and variables
- When you need constants shared by many classes, use
public final static fields
- For example:
Math.E (base of natural logarithms, approximately 2.72)
Math.PI (approximately 3.14159)
- Static methods play an important role in various design patterns
- For instance, in a Factory Method or the Singleton Pattern
- However, design patterns are beyond the scope of this course
More Information
^ top
5.1.7: Summary
Check Yourself
- How does the coding of a static method differ from the coding of an instance method?
- How does the coding of a static variable differ from the coding of an instance variable?
- Can static methods access instance methods and variables?
- Can instance methods access static methods and variables?
- How do you calculate the square root of a number like
27?
- When should you use static methods and variables rather than instance methods and variables?
^ top
Exercise 5.1
Take one minute to prepare an answer the following questions.
- What would be the results of attempting to compile and run the following program?
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class MyClass {
static MyClass ref;
String[] args;
public static void main(String[] args) {
ref = new MyClass();
ref.func(args);
}
public void func(String[] args) {
ref.args = args;
}
}
|
^ top
5.2: Working with Objects and References
Learner Outcomes
At the end of the lesson the student will be able to:
- Discuss the differences between primitive and reference types
- Use classes as method parameters
- Describe the keyword
this
- Discuss garbage collection and finalizers
- Prevent shadowing errors
|
^ top
5.2.1: Reference Types
Address Analogy
- By analogy, a reference variable is like the address of a house
- The address is a small identifier from which we can find a much larger object
- One of the advantages of addresses is that they are much easier to work with than actual houses
- For instance, if we want to locate people on a street by name, we could rearrange all the houses in alphabetical order by name
- An easier way is to make a list of last names with their addresses
- The address is the reference to the house object
- We get the same benefits when programming: it is often easier to work with references to objects rather than actual objects
- Other examples of references abound in real life: telephone numbers, e-mail addresses, social-security numbers, etc.
- Each reference type refers to and makes it easier to access a resource
Initial State
- You can initialize reference types to the value
null
Scanner input = null;
null is a keyword that means a "nothing" or "no value"
- If the reference type is a class variable, as opposed to a local variable, then Java initializes it to
null by default
References vs. Pointers
- Pointers are the most primitive and error-prone reference type
- They simply store a memory address
- In C/C++, you can actually manipulate pointers with arithmetic or even by assigning an arbitrary value
- A reference type in Java is like a pointer but without direct manipulation
- With references, you get the main benefits of a pointer but without many of the errors
- With fewer errors, you get better security
- Also, you get addional features like automatic dereferencing and garbage collection
More Information
- Binky Pointer Fun Video: a 3 minute video on pointers (references)
- Post video questions:
- What do pointers (references) initially point to?
- What is a "pointee" called in Java?
- How do you allocate a "pointee" in Java?
- What is meant by "dereferencing a pointer"?
- How do you make pointers point to the same "pointee"?
^ top
5.2.2: Classes as Method Parameters
- Java passes the value stored in a variable the same way for both primitive types and reference types
- When a method is called, the value of each argument is copied to its corresponding parameter
- Thus an argument's value can never be changed within a method
- However, copying a reference value to a parameter has certain implications
- The method gets access to the exact same object because it has a reference to the object
- You can see this situation in the following diagram:

- Also, you can see the effects of passing a reference in the following program
Passing an Object to a Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class PassObject {
public static void main(String[] args) {
PassObject pass = new PassObject();
Coffee java = new Coffee("Expresso");
System.out.println("In main(): "
+ java.getFlavor());
pass.changeData(java, "Latte");
System.out.println("In main(): "
+ java.getFlavor());
}
public void changeData(Coffee cup, String flavor) {
System.out.println("Changing the flavor: "
+ cup.getFlavor());
cup.setFlavor(flavor);
}
}
class Coffee {
private String flavor;
public Coffee(String newFlavor) {
flavor = newFlavor;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String newFlavor) {
flavor = newFlavor;
}
}
|
^ top
5.2.3: Returning an Object
- Methods can return a reference to an object
- You can see how a reference is returned in the following code
Returning an Object from a Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class ReturnObject {
public static void main(String[] args) {
ReturnObject obj = new ReturnObject();
Coffee java = obj.brew("Latte");
System.out.println("In main() I got: "
+ java.getFlavor());
System.out.println("Thank you!");
}
public Coffee brew(String flavor) {
System.out.println("Brewing coffee");
Coffee cup = new Coffee(flavor);
return cup;
}
}
class Coffee {
private String flavor;
public Coffee(String newFlavor) {
flavor = newFlavor;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String newFlavor) {
flavor = newFlavor;
}
}
|
^ top
5.2.4: Using this
- Each object maintains its own set of instance variables
- This permits each object to have its own state based on the values stored
- For example, consider a class
Date with 3 instance variable
public class Date {
private int month;
private int day;
private int year;
// member methods not shown
}
- A distinct area of memory is set aside each time an object of this class is created
- For example, if we create two objects referenced by variables named
a and b:
Date a = new Date(1, 1, 1970);
Date b = new Date(12, 25, 2002);
- Memory is set aside for both objects:

- However, each object does not contain a copy of the member methods
- Instead, only one copy of each member method is needed
- Every object of that type uses these same methods
-
- For example, the method:
a.getMonth()
Is called as if it had the parameter this
getMonth(this)
this contains a reference to the object that called the method

this is passed automatically, so you do NOT explicitly use it in method calls
However, you can use the this parameter inside the class
It is used with the dot '.' operator like any other object reference
this.month
Use of the this reference is optional unless needed to clarify variable scope
For instance, we could define a constructor of Date:
public Date(int month, int day, int year) {
this.month = month;
this.day = day;
this.year = year;
}
We now need this to differentiate between member variables and local variables
Another use of this is to pass it as a parameter to a method
System.out.println(this);
Since this is an object reference, Java will implicitly call the toString method
You can also return this from a method call
return this;
Returns a reference to the current object
However, using this as an argument or return value is generally poor practice
The reason is that passing or returning this breaks encapsulation
Note that this is a final variable (constant)
Thus, you cannot assign a new object value to this
^ top
5.2.5: Garbage Collection
- What happens to an object that is no longer used?
- Garbage collection returns the memory for reuse by the program
- An object is marked for garbage collection if there are no references to the object in the program
- Java performs garbage collection automatically
- You can manually choose to run the garbage collector as well
System.gc();
^ top
5.2.6: Summary
- All nonprimitive data types are known as reference types
- Programs use variables of reference types to store locations of objects in the computer's memory
- You can pass an object to a method by coding a reference type as a method parameter
public static void changeData(MyData data)
When an object is created, it gets memory space for all its instance variables
This replication of data storage is not implemented for methods
Methods of the object must know which set of data to work upon
To keep track of which object's memory to use, a special variable is passed to all instance methods: this
It is possible to use the this variable inside a class:
this.month
When an object is no longer referred to by any reference variable in a program, the unused memory is automatically reclaimed ("garbage collected")
Check Yourself
- What is a reference type?
- What value does a reference variable have if it is not referencing any object?
- How do you code a reference parameter to a method?
- How do you code a reference as a method's return type?
- What is
this?
- What condition must exists for an object to be garbage collected?
^ top
Exercise 5.2
Take one minute to prepare an answer the following question.
Given the following code, which statements can be placed at the indicated position without causing compile errors?
public class SolarSystem {
int planets;
int suns;
public void gaze() {
int i;
// insert statements here
}
}
^ top
5.3: Using and Misusing References
Learner Outcomes
At the end of the lesson the student will be able to:
- Discuss what is meant by a privacy leak
- Prevent privacy leaks
|
^ top
5.3.1: About References and Privacy Leaks
- As we discussed before, two important features of classes are encapsulation and information hiding
- We accompish information hiding by using the keyword
private
- However, using the
private modifier is not all we need to do
- We can still get privacy leaks in poorly designed classes
- The following class is one such example
Example of a Class with Privacy Leaks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import java.util.Date;
public class Period1 {
private Date start;
private Date end;
public Period1(Date newStart, Date newEnd) {
if (newStart.compareTo(newEnd) > 0){
System.err.println("Fatal error");
System.exit(1);
}
start = newStart;
end = newEnd;
}
public void setStart(Date newStart) {
start = newStart;
}
public void setEnd(Date newEnd) {
end = newEnd;
}
public Date getStart() {
return start;
}
public Date getEnd() {
return end;
}
public String toString() {
return "start: " + start + " -- end: " + end;
}
// rest of class omitted
}
|
^ top
5.3.2: Attacking the Privacy
- At first glance, our
Period class may seem safe
- We check that the start date comes before the end date
- Thus the class should perform as expected
- However, one attack is shown in the following test class
Example of a Class Attacking the Privacy Leak
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.util.Date;
public class PeriodTest1 {
public static void main(String[] args) {
Date start = new Date();
Date end = new Date();
Period1 p = new Period1(start, end);
System.out.println(p);
end.setTime(1000L); // attack
System.out.println(p);
}
}
|
Explanation of the Attack
- The problem occurs when we use classes as method parameters:

- Because the value of reference variable is copied to the parameter, changes to the reference variable change the internals of the class
- The solution is to make a defensive copy of mutable parameters to the constructor
- You can see the changes in the updated class that follows
Updated Example Class with Privacy Leaks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
import java.util.Date;
public class Period2 {
private Date start;
private Date end;
public Period2(Date newStart, Date newEnd) {
start = new Date(newStart.getTime());
end = new Date(newEnd.getTime());
if (start.compareTo(end) > 0){
System.err.println("Fatal error");
System.exit(1);
}
}
public void setStart(Date newStart) {
start = newStart;
}
public void setEnd(Date newEnd) {
end = newEnd;
}
public Date getStart() {
return start;
}
public Date getEnd() {
return end;
}
public String toString() {
return "start: " + start + " -- end: " + end;
}
// rest of class omitted
}
|
^ top
5.3.3: Protecting Privacy with Immutability
- The new constructor above defends against the previous attack
- However, it is still possible to attack through the accessor methods
- The new attack is shown in the following test class
Example of a Class Attacking the Privacy Leak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.util.Date;
public class PeriodTest2 {
public static void main(String[] args) {
Date start = new Date();
Date end = new Date();
Period2 p = new Period2(start, end);
System.out.println(p);
end.setTime(1000L); // attack
System.out.println(p);
p.setEnd(end);
end.setTime(1000L); // attack
System.out.println(p);
}
}
|
Protecting Against the Attack
- We could protect against this attack using the same technique as used in the constructor:
public void setEnd(Date newEnd) {
Date temp = new Date(newEnd.getTime());
if (start.compareTo(temp) > 0){
System.err.println("Fatal error");
System.exit(1);
}
end = temp;
}
- However, a better and easier way to to make our class immutable:
Immutable object: an object whose member variables cannot change after it is created.
- Recall that class
String is immutable
- This means that a
String object cannot change one it has been constructed
- If you look carefully at the methods of class
String, you will notice that no method changes the state of the string
- We can use the same technique to protect our class
Making a Class Immutable
- Do not provide any mutator methods.
- Make the class final so it cannot be extended.
We will discuss extending classes when we cover inheritance.
- Make all non-constant member variables private.
- Make all member variables of a class type final.
Variables that are final can still be set by the constructor.
- Make certain there are no privacy leaks for any mutable objects your class may have.
Updated Example Class with Privacy Leaks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
import java.util.Date;
public final class Period3 {
private final Date start;
private final Date end;
public Period3(Date newStart, Date newEnd) {
start = new Date(newStart.getTime());
end = new Date(newEnd.getTime());
if (start.compareTo(end) > 0){
System.err.println("Fatal error");
System.exit(1);
}
}
public Date getStart() {
return start;
}
public Date getEnd() {
return end;
}
public String toString() {
return "start: " + start + " -- end: " + end;
}
// rest of class omitted
}
|
^ top
5.3.4: Another Privacy Attack
- Making our class immutable above defends against the previous attack
- However, it is still possible to attack through the accessor methods
- The new attack is shown in the following test class
Example of a Class Attacking the Privacy Leak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.util.Date;
public class PeriodTest3 {
public static void main(String[] args) {
Date start = new Date();
Date end = new Date();
Period3 p = new Period3(start, end);
System.out.println(p);
end.setTime(1000L); // attack
System.out.println(p);
p.getEnd().setTime(1000L); // attack
System.out.println(p);
}
}
|
Protecting Against the Attack
Example Class with No Privacy Leaks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
import java.util.Date;
public final class Period4 {
private final Date start;
private final Date end;
public Period4(Date newStart, Date newEnd) {
start = new Date(newStart.getTime());
end = new Date(newEnd.getTime());
if (start.compareTo(end) > 0){
System.err.println("Fatal error");
System.exit(1);
}
}
public Date getStart() {
return new Date(start.getTime());
}
public Date getEnd() {
return new Date(end.getTime());
}
public String toString() {
return "start: " + start + " -- end: " + end;
}
// rest of class omitted
}
|
Test Class for the Example Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.util.Date;
public class PeriodTest4 {
public static void main(String[] args) {
Date start = new Date();
Date end = new Date();
Period4 p = new Period4(start, end);
System.out.println(p);
end.setTime(1000L); // attack
System.out.println(p);
p.getEnd().setTime(1000L); // attack
System.out.println(p);
}
}
|
^ top
5.3.5: Copy Constructors
Example Class with a Copy Constructor (Partial)
public class Person {
private String name;
private Date born;
private Date died; // null indicates still alive.
// copy constructor
public Person(Person original) {
if (original == null) {
System.out.println("Fatal error.");
System.exit(0);
}
name = original.name;
born = new Date(original.born);
if (original.died == null)
died = null;
else
died = new Date(original.died);
}
// other members not shown
}
Comments About the Copy Constructor
- Note that the
Date class used by the textbook was custom and included a copy constructor
- The copy constructor copies from the member variables of the
original object
- The String instance variable is copied directly since a String is immutable
- However the
Date objects are mutable and independant copies are made from the original dates
- This prevents a change in a
Date of the original object from changing the Date in the copied object
- The copy must be independant
^ top
5.3.6: Summary
- Two important features of classes are encapsulation and information hiding
- We accompish information hiding by using the keyword
private
- However, using the
private modifier is not all we need to do
- We can still get privacy leaks in poorly designed classes
- Privacy leaks can occur when we use classes as method parameters
- Changes to the passed paramter can affect the original object if the object is mutable
- Immutable objects do not suffer from this problem
- To prevent problems we must make defensive copies of all mutable parameters
- For example:
public Period2(Date newStart, Date newEnd) {
start = new Date(newStart.getTime());
end = new Date(newEnd.getTime());
if (start.compareTo(end) > 0){
System.err.println("Fatal error");
System.exit(1);
}
}
- In addition, we must make defensive copies for accessor methods returning a mutable object:
public Date getEnd() {
return new Date(end.getTime());
}
- An aid to controlling privacy leaks is the copy constructor
- A copy constructor is a constructor with a single parameter of the same type as the class
- The purpose of a copy constructor is to create an exact copy of the parameter that is a separate and independent object
- We looked at an example of a copy constructor
Check Yourself
- What is a privacy leak?
- What technique do you use to prevent privacy leaks?
- What is meant by the term immutable object?
- Can immutable objects cause privacy leaks?
^ top
Exercise 5.3
Take one minute to identify the privacy leaks in the Employee class shown below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
import java.util.Date;
public class EmployeeTest {
public static void main(String[] args) {
Date hired = new Date();
Employee ed = new Employee("Ed", hired);
System.out.println(ed);
}
}
class Employee {
private String fullName;
private Date hireDate;
public Employee(String name, Date hired) {
fullName = name;
hireDate = hired;
}
public void setFullName(String name) {
fullName = name;
}
public String getName() {
return fullName;
}
public void setHireDate(Date hired) {
hireDate = hired;
}
public Date getHireDate() {
return hireDate;
}
public String toString() {
return "Name: "+ fullName + ", date hired: "
+ hireDate;
}
}
|
^ top
5.4: Working with Packages
Learner Outcomes
At the end of the lesson the student will be able to:
- Describe the general procedure for creating a directory structure for a package
- Add classes to a package and compile classes in that package
- Make classes in a package available to other classes
- Create a JAR file for an application
- Run applications out of a JAR file
|
^ top
5.4.1: Packages and import Statements
import packagename.ClassName;
or
import packagename.*;
Using the '*' wildcard will import all classes in a package
Some examples:
import java.text.NumberFormat;
import java.util.Scanner;
import java.util.*;
import javax.swing.*;
^ top
5.4.2: Package Names and Directories
- A package name is a form of path name to a directory
- To store your classes in packages, you must create a directory structure for the packages
- Then, you must store each class in the correct directory
- For instance, if you have an application name
store, then you would have a root directory for the application named store
- In the root directory you might place a Java file with the
main() method that starts and runs the application
- In addition, any subdirectories for the application are placed in the root directory of the application, such as
business and util in the following example
- Each subdirectory then contains Java files and other subdirectories
Example Directory Structure
store
Artzy.java
edparrish
business
Product.java
Customer.java
database
ProductionDB.java
util
MyUtils.java
Using package Statements
- Each package name must correspond exactly to the directory names
- For instance, after you place the
MyUtils.java class in the directory structure, you must specify a package of:
package edparrish.utils;
- The package statement must be the first statement in the file
- The following is a complete class example
- You must store the package in the directory:
edparrish/utils/
Class in Package edparrish.utils
1
2
3
4
5
6
7
8
9
10
11
12
|
// comments can preceed package, but nothing else
package edparrish.utils;
public class MyUtils {
public static double average(double[] values) {
double total = 0.0;
for (int i = 0; i < values.length; i++) {
total += values[i];
}
return total / values.length;
}
}
|
Using import Statements
- To use the
MyUtils.java file you must specify an import statement like:
import edparrish.utils.MyUtils
For a complete example:
1
2
3
4
5
6
7
8
9
|
import edparrish.utils.MyUtils;
class MyUtilsTest {
public static void main(String[] args) {
double[] testVals = {1.0, 2.0, 3.0};
double x = MyUtils.average(testVals);
System.out.println(x);
}
}
|
More About Package Names
- Note that Sun recommends using reversed Internet domain names to uniquely identify packages
com.edparrish.business
Since each Internet name is unique, this ensures a unique package name
Even if you do not follow this convention, you should be careful about using generic package names
For instance, business is too generic, but edparrish.business is specific enough that it is unlikely to conflict with other packages
Also note that package names are always lower case by convention
Further Information
^ top
5.4.3: Compiling Classes in a Package
- Some Java tools cannot compile classes that have been organized into packages
- To compile classes in these cases, you can either:
- Compile from the command line
- Set a CLASSPATH for the system
- Note that before you compile a class that imports another class, you must compile the class it imports.
Compiling Classes from the Command Line
- Make sure that the classes have all of the appropriate
package and import statements.
- Start the command prompt and navigate to the root directory for the package (the parent directory).
- Use the
javac command to compile the classes.
- Be sure to include the subdirectories in the path that correspond to the package name.
- Syntax:
C:\parentDir>javac packagePath/ClassName.java
For example:
C:\store>javac edparrish/utils/MyUtils.java
Setting a Class Path
- To help the Java compiler find classes that are not part of the JDK, you set the CLASSPATH
- The CLASSPATH is an operating system environment variable that Java searches for class names
- Thus, the way you set your CLASSPATH variable depends on your operating system
- Note that the CLASSPATH variable is usually spelled as one work in all uppercase letters
- You can set the CLASSPATH either temporarily or "permanently"
- To set a CLASSPATH only while compiling, you can use:
javac -classpath /path/to/app/root packagePath/ClassName.java
- If you have problems adding a CLASSPATH, try putting double quotes around the path names
More Information
^ top
5.4.4: Summary
- You can organize classes in your application by using a
package statement to add them to a package
package edparrish.business;
Then, you use import statements to make the classes in that package available to other classes
import edparrish.business.Product
To compile classes in a package, you must sometimes use the command line
Syntax:
C:\parentDir>javac packagePath/ClassName.java
For example:
C:\store>javac edparrish/business/Product.java
Rather than moving to the package (application) root, you can specify a CLASSPATH
To compile you would use something like:
javac -classpath /path/to/app/root packagePath/ClassName.java
- When you compile a class that contains a package statement, it becomes part of the package and is not accessible to classes outside the package
- To make a package available, you can either:
- Add the directory structure and classes to the application
- Create a JAR file and add the JAR to the application's root directory
Check Yourself
- What is a package?
- What are two way to access a class in a package?
^ top
Exercise 5.4
Take one minute to prepare an answer the following question.
- Given the following class, which of the following are valid ways to call methods of the class from outside the package
com.edparrish.mystuff?
package com.edparrish.mystuff;
public class GoodStuff {
// ...
}
- With a reference to the class
GoodStuff
- With a reference to the class
mystuff.GoodStuff
- With a reference to the class
com.edparrish.mystuff.GoodStuff
- By importing
com.edparrish.mystuff.GoodStuff and referring to the class as Goodstuff
- By importing package
com.edparrish.* and referring to the class as mystuff.GoodStuff
^ top
Wrap Up
Due Next: A4-Shape Classes (3/11/09)
A5-Paradise Roller (3/18/09)
^ top
Home
| Blackboard
| Announcements
| Schedule
| Room Policies
| Course Info
Help
| FAQ's
| HowTo's
| Links
Last Updated: March 29 2009 @18:00:19
|