The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here:
A nested class is a member of its enclosing class and, as such, has access to other members of the enclosing class, even if they are declared private. As a member ofclass OuterClass {
…
class NestedClass {
…
}
}
OuterClass
, a nested class can be declaredprivate
,public
,protected
, or package private. (Recall that outer classes can only be declaredpublic
or package private.)
Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declaredstatic
are simply called static nested classes. Non-static nested classes are called inner classes.
class OuterClass {
…
static class StaticNestedClass {
…
}
class InnerClass {
…
}
}
Why Use Nested Classes?
There are several compelling reasons for using nested classes, among them:
- It is a way of logically grouping classes that are only used in one place.
- It increases encapsulation.
- Nested classes can lead to more readable and maintainable code.
Logical grouping of classes—If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such “helper classes” makes their package more streamlined.
Increased encapsulation—Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared
private
. By hiding class B within class A, A’s members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
More readable, maintainable code—Nesting small classes within top-level classes places the code closer to where it is used.
Static Nested Classes
As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference.
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
Static nested classes are accessed using the enclosing class name:
For example, to create an object for the static nested class, use this syntax:OuterClass.StaticNestedClass
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Inner Classes
As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object’s methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.
Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:
An instance ofclass OuterClass {
…
class InnerClass {
…
}
}InnerClass
can exist only within an instance ofOuterClass
and has direct access to the methods and fields of its enclosing instance. The next figure illustrates this idea.
An InnerClass Exists Within an Instance of OuterClass
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
Additionally, there are two special kinds of inner classes: local classes and anonymous classes (also called anonymous inner classes). Both of these will be discussed briefly in the next section.OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Month: October 2007
More on Classes
This section covers more aspects of classes that depend on using object references and thedot
operator that you learned about in the preceding sections on objects:
- Returning values from methods.
- The
this
keyword.
- Class vs. instance members.
- Access control.
Objects
A typical Java program creates many objects, which as you know, interact by invoking methods Through these object interactions, a program can carry out various tasks, such as implementing a GUI, running an animation, or sending and receiving information over a network. Once an object has completed the work for which it was created, its resources are recycled for use by other objects.
Here’s a small program, called
CreateObjectDemo
, that creates three objects: onePoint
object and twoRectangle
objects. You will need all three source files to compile this program.
This program creates, manipulates, and displays information about various objects. Here’s the output:public class CreateObjectDemo {public static void main(String[] args) {
//Declare and create a point object
//and two rectangle objects.
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);//display rectOne’s width, height, and area
System.out.println(“Width of rectOne: ” +
rectOne.width);
System.out.println(“Height of rectOne: ” +
rectOne.height);
System.out.println(“Area of rectOne: ” + rectOne.getArea());//set rectTwo’s position
rectTwo.origin = originOne;//display rectTwo’s position
System.out.println(“X Position of rectTwo: ”
+ rectTwo.origin.x);
System.out.println(“Y Position of rectTwo: ”
+ rectTwo.origin.y);//move rectTwo and display its new position
rectTwo.move(40, 72);
System.out.println(“X Position of rectTwo: ”
+ rectTwo.origin.x);
System.out.println(“Y Position of rectTwo: ”
+ rectTwo.origin.y);
}
}
Width of rectOne: 100
Height of rectOne: 200
Area of rectOne: 20000
X Position of rectTwo: 23
Y Position of rectTwo: 94
X Position of rectTwo: 40
Y Position of rectTwo: 72
The following three sections use the above example to describe the life cycle of an object within a program. From them, you will learn how to write code that creates and uses objects in your own programs. You will also learn how the system cleans up after an object when its life has ended.
Classes
The introduction to object-oriented concepts in the lesson titled Object-oriented Programming Concepts used a bicycle class as an example, with racing bikes, mountain bikes, and tandem bikes as subclasses. Here is sample code for a possible implementation of aBicycle
class, to give you an overview of a class declaration. Subsequent sections of this lesson will back up and explain class declarations step by step. For the moment, don`t concern yourself with the details.
public class Bicycle {
// the Bicycle class has three fields
public int cadence;
public int gear;
public int speed;
// the Bicycle class has one constructor
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
// the Bicycle class has four methods
public void setCadence(int newValue) {
cadence = newValue;
}
public void setGear(int newValue) {
gear = newValue;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}
A class declaration for a
MountainBike
class that is a subclass ofBicycle
might look like this:
public class MountainBike extends Bicycle {
// the MountainBike subclass has one field
public int seatHeight;
// the MountainBike subclass has one constructor
public MountainBike(int startHeight, int startCadence, int startSpeed, int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
// the MountainBike subclass has one method
public void setHeight(int newValue) {
seatHeight = newValue;
}
}MountainBike
inherits all the fields and methods ofBicycle
and adds the fieldseatHeight
and a method to set it (mountain bikes have seats that can be moved up and down as the terrain demands).
Language Basics
Variables
You’ve already learned that objects store their state in fields. However, the Java programming language also uses the term “variable” as well. This section discusses this relationship, plus variable naming rules and conventions, basic data types (primitive types, character strings, and arrays), default values, and literals.
Operators
This section describes the operators of the Java programming language. It presents the most commonly-used operators first, and the less commonly-used operators last. Each discussion includes code samples that you can compile and run.
Expressions, Statements, and Blocks
Operators may be used in building expressions, which compute values; expressions are the core components of statements; statements may be grouped into blocks. This section discusses expressions, statements, and blocks using example code that you’ve already seen.
Control Flow Statements
This section describes the control flow statements supported by the Java programming language. It covers the decisions-making, looping, and branching statements that enable your programs to conditionally execute particular blocks of code.
Expressions, Statements, and Blocks
Now that you understand variables and operators, it’s time to learn about expressions, statements, and blocks. Operators may be used in building expressions, which compute values; expressions are the core components of statements; statements may be grouped into blocks.
Expressions
An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value. You’ve already seen examples of expressions, illustrated in bold below:The data type of the value returned by an expression depends on the elements used in the expression. The expressionint cadence = 0;
anArray[0] = 100;
System.out.println(“Element 1 at index 0: ” + anArray[0]);
int result = 1 + 2; // result is now 3
if(value1 == value2) System.out.println(“value1 == value2”);
cadence = 0
returns anint
because the assignment operator returns a value of the same data type as its left-hand operand; in this case,cadence
is anint
. As you can see from the other expressions, an expression can return other types of values as well, such asboolean
orString
.
The Java programming language allows you to construct compound expressions from various smaller expressions as long as the data type required by one part of the expression matches the data type of the other. Here’s an example of a compound expression:
1 * 2 * 3
In this particular example, the order in which the expression is evaluated is unimportant because the result of multiplication is independent of order; the outcome is always the same, no matter in which order you apply the multiplications. However, this is not true of all expressions. For example, the following expression gives different results, depending on whether you perform the addition or the division operation first:
x + y / 100 // ambiguous
You can specify exactly how an expression will be evaluated using balanced parenthesis: ( and ). For example, to make the previous expression unambiguous, you could write the following:
(x + y) / 100 // unambiguous, recommended
If you don’t explicitly indicate the order for the operations to be performed, the order is determined by the precedence assigned to the operators in use within the expression. Operators that have a higher precedence get evaluated first. For example, the division operator has a higher precedence than does the addition operator. Therefore, the following two statements are equivalent:
x + y / 100
x + (y / 100) // unambiguous, recommended
When writing compound expressions, be explicit and indicate with parentheses which operators should be evaluated first. This practice makes code easier to read and to maintain.
Statements
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution. The following types of expressions can be made into a statement by terminating the expression with a semicolon (;
).
Such statements are called expression statements. Here are some examples of expression statements.
- Assignment expressions
- Any use of
++
or—
- Method invocations
- Object creation expressions
In addition to expression statements, there are two other kinds of statements: declaration statements and control flow statements. A declaration statement declares a variable. You’ve seen many examples of declaration statements already:aValue = 8933.234; // assignment statement
aValue++; // increment statement
System.out.println(“Hello World!”); // method invocation statement
Bicycle myBike = new Bicycle(); // object creation statement
Finally, control flow statements regulate the order in which statements get executed. You’ll learn about control flow statements in the next section, Control Flow Statementsdouble aValue = 8933.234; //declaration statement
Blocks
A block is a group of zero or more statements between balanced braces and can be used anywhere a single statement is allowed. The following example,BlockDemo
, illustrates the use of blocks:
class BlockDemo {
public static void main(String[] args) {
boolean condition = true;
if (condition) { // begin block 1
System.out.println(“Condition is true.”);
} // end block one
else { // begin block 2
System.out.println(“Condition is false.”);
} // end block 2
}
}
Control Flow Statements
The statements inside your source files are generally executed from top to bottom, in the order that they appear. Control flow statements, however, break up the flow of execution by employing decision making, looping, and branching, enabling your program to conditionally execute particular blocks of code. This section describes the decision-making statements (
if-then
,if-then-else
,switch
), the looping statements (for
,while
,do-while
), and the branching statements (break
,continue
,return
) supported by the Java programming language.
Operators
Now that you’ve learned how to declare and initialize variables, you probably want to know how to do something with them. Learning the operators of the Java programming language is a good place to start. Operators are special symbols that perform specific operations on one, two, or three operands, and then return a result.
As we explore the operators of the Java programming language, it may be helpful for you to know ahead of time which operators have the highest precedence. The operators in the following table are listed according to precedence order. The closer to the top of the table an operator appears, the higher its precedence. Operators with higher precedence are evaluated before operators with relatively lower precedence. Operators on the same line have equal precedence. When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
Operator Precedence
Operators
Precedence
postfix
expr++ expr—
unary
++expr —expr +expr –expr ~ !
multiplicative
* / %
additive
+ –
shift
<< >> >>>
relational
< > <= >= instanceof
equality
== !=
bitwise AND
&
bitwise exclusive OR
^
bitwise inclusive OR
|
logical AND
&&
logical OR
||
ternary
? :
assignment
= += -= *= /= %= &= ^= |= <<= >>= >>>=
In general-purpose programming, certain operators tend to appear more frequently than others; for example, the assignment operator “
=
” is far more common than the unsigned right shift operator “>>>
“. With that in mind, the following discussion focuses first on the operators that you’re most likely to use on a regular basis, and ends focusing on those that are less common. Each discussion is accompanied by sample code that you can compile and run. Studying its output will help reinforce what you’ve just learned.
Variables
As you learned in the previous lesson, an object stores its state in fields.
int cadence = 0;
int speed = 0;
int gear = 1;
The What Is an Object? discussion introduced you to fields, but you probably have still a few questions, such as: What are the rules and conventions for naming a field? Besides
int
, what other data types are there? Do fields have to be initialized when they are declared? Are fields assigned a default value if they are not explicitly initialized? We’ll explore the answers to such questions in this lesson, but before we do, there are a few technical distinctions you must first become aware of. In the Java programming language, the terms “field” and “variable” are both used; this is a common source of confusion among new developers, since both often seem to refer to the same thing.
The Java programming language defines the following kinds of variables:
Having said that, the remainder of this tutorial uses the following general guidelines when discussing fields and variables. If we are talking about “fields in general” (excluding local variables and parameters), we may simply say “fields”. If the discussion applies to “all of the above”, we may simply say “variables”. If the context calls for a distinction, we will use specific terms (static field, local variables, etc.) as appropriate. You may also occasionally see the term “member” used as well. A type’s fields, methods, and nested types are collectively called its members.
- Instance Variables (Non-Static Fields) Technically speaking, objects store their individual states in “non-static fields”, that is, fields declared without the
static
keyword. Non-static fields are also known as instance variables because their values are unique to each instance of a class (to each object, in other words); thecurrentSpeed
of one bicycle is independent from thecurrentSpeed
of another.
- Class Variables (Static Fields) A class variable is any field declared with the
static
modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated. A field defining the number of gears for a particular kind of bicycle could be marked asstatic
since conceptually the same number of gears will apply to all instances. The codestatic int numGears = 6;
would create such a static field. Additionally, the keywordfinal
could be added to indicate that the number of gears will never change.
- Local Variables Similar to how an object stores its state in fields, a method will often store its temporary state in local variables. The syntax for declaring a local variable is similar to declaring a field (for example,
int count = 0;
). There is no special keyword designating a variable as local; that determination comes entirely from the location in which the variable is declared — which is between the opening and closing braces of a method. As such, local variables are only visible to the methods in which they are declared; they are not accessible from the rest of the class.
- Parameters You’ve already seen examples of parameters, both in the
Bicycle
class and in themain
method of the “Hello World!” application. Recall that the signature for themain
method ispublic static void main(String[] args)
. Here, theargs
variable is the parameter to this method. The important thing to remember is that parameters are always classified as “variables” not “fields”. This applies to other parameter-accepting constructs as well (such as constructors and exception handlers) that you’ll learn about later in the tutorial.
Naming
- Variable names are case-sensitive. A variable’s name can be any legal identifier — an unlimited-length sequence of Unicode letters and digits, beginning with a letter, the dollar sign “
$
“, or the underscore character “_
“. The convention, however, is to always begin your variable names with a letter, not “$
” or “_
“. Additionally, the dollar sign character, by convention, is never used at all. You may find some situations where auto-generated names will contain the dollar sign, but your variable names should always avoid using it. A similar convention exists for the underscore character; while it’s technically legal to begin your variable’s name with “_
“, this practice is discouraged. White space is not permitted.
- Subsequent characters may be letters, digits, dollar signs, or underscore characters. Conventions (and common sense) apply to this rule as well. When choosing a name for your variables, use full words instead of cryptic abbreviations. Doing so will make your code easier to read and understand. In many cases it will also make your code self-documenting; fields named
cadence
,speed
, andgear
, for example, are much more intuitive than abbreviated versions, such ass
,c
, andg
. Also keep in mind that the name you choose must not be a keyword or reserved word.
- If the name you choose consists of only one word, spell that word in all lowercase letters. If it consists of more than one word, capitalize the first letter of each subsequent word. The names
gearRatio
andcurrentGear
are prime examples of this convention. If your variable stores a constant value, such asstatic final int NUM_GEARS = 6
, the convention changes slightly, capitalizing every letter and separating subsequent words with the underscore character. By convention, the underscore character is never used elsewhere.
Java Language Keywords
Here’s a list of keywords in the Java programming language. You cannot use any of the following as identifiers in your programs. The keywordsconst
andgoto
are reserved, even though they are not currently used.true
,false
, andnull
might seem like keywords, but they are actually literals; you cannot use them as identifiers in your programs.
abstract
continue
for
new
switch
assert
***
default
goto
*
package
synchronized
boolean
do
if
private
this
break
double
implements
protected
throw
byte
else
import
public
throws
case
enum
****
instanceof
return
transient
catch
extends
int
short
try
char
final
interface
static
void
class
finally
long
strictfp
**
volatile
const
*
float
native
super
while
*
not used
**
added in 1.2
***
added in 1.4
****
added in 5.0