'New Topic in JDK 1.5', Generics // just for
reference
See the following for a short explanation. Supplied for
reference only. Not part of current course material.
Generics.html
A program can be
thought of as a list of instructions that
a computer is able to execute in a predictable manner.
At any given instant in the execution of this list of
commands,
one instruction is being processed by the CPU, the Central
Processing Unit.
From the
program's vantage point, it is the command that
has control of the processor and
indirectly the whole PC.
In this sense, the program has 'control' over the processor.
When a program is
running, the collective effect of the list
of instructions being processed, one at a time at the CPU
provides a sense that the program has control over the
the activities of the system.
You can think of
the CPU as the active component processing
a
list of passive instructions, like a buzz saw cutting through
wood. Alternatively, you can picture the CPU as a passive and
obedient robot whose actions are totally controlled by a list of
program instructions. Wherever you put the emphasis, both
descriptions allude to this concept of control.
Flow
Flow implies
movement. As each command in a program
is executed in
sequence by the central processing unit,
there is a flow of control developed.
At the assembly level
one set of instructions might tell the CPU to go to another
memory
location and execute the instruction there which in
turn may lead the CPU to execute
an instruction stored at
yet another location.
This dynamic sequence of events
describes the flow of
control. The flow of control is a description of the
order in
which commands are executed. Programming languages
supply different keywords that are used in control
statements to control the flow of execution of commands.
Control of Flow or Flow
Control
Some authors think
it is more accurate to name this topic
'Flow of
Control'. The topic is also been called 'Flow Control
The latter seems to be easier to say and remember.
Primitives
The most elemental
parts of a programming language
are the primitive
types. The primitives, called prime types,
cannot be broken down any smaller. A
char, that stores
the letter 'z' can't be broken down to anything smaller. It
is a prime type. The char can be treated as an operand
and be worked on by Java's
operators. A char variable
can be incremented, inverted, compared, assigned or
shifted etc.
Expressions
Groups of operators
and the operands that operators
work on, can be joined together in complex associations
called expressions. An
expression evaluates to something.
Regardless of how complex the grouping of operators and
operands are they ultimately resolve to a single value, or
a single variable
representing some value or a void in the
case of a method expression. In Java anything
that evaluates
to a variable, a value or a
void is by
definition an expression.
Java Expressions
Evaluate To:
// In Java an
expression evaluates to a variable, a value or a void
An instantiations of a class evaluates to a
reference value
that can be stored in a variable.
Sometimes an
expression
doesn't resolve
to a value, but only to a variable. You
can
think of 2 * x as resolving to the variable
2x. A method can
return specific values but also can
return void. A method
call is
also a type of expression. In the following
example
everything supplied as an
argument to the println method
is an expression
that ultimately resolves to a String
value.
Example
System.out.println( " The square root of 91 is " +
Math.sqrt(91) );
Statements
After the
expression, the next level of or programmatic
organization is called the statement. Statements are to
a program what sentences are to grammar.
While in
grammar, the period ends the sentence, in Java the
semi-colon or
curly brace end the statement. When a
Java expression is
concluded with a semi-colon or a
curly
brace , the expression becomes a
statement.
The Block Statement
A block defined by curly braces is also a
statement.
The block statement is also called the 'compound'
statement as
it is typically used to enclose multiple
statements.
You can optionally put a semicolon
after a
block if you
like. You can
think of a block as a statement that has
a semi-colon supplied
implicitly. Following is an empty
block with a semi-colon supplied explicitly.
Example
{ } ; // an
empty block statement
The Empty Statement
Even
a semicolon by itself is a statement, appropriately
called an empty statement. You
can't create a statement
like this in a
normal language like English. A period
by
itself is just a typo error. Following is an example of an
empty statement.
Example
;
//
the semi-colon by itself is an empty statement
An artifact created by the empty statement is
you can
put any number of these outside the scope
of the class
without a compiler
error occurring. The following code
shows variations on
block and empty
statements.
Example
class Empty
{
public static void main(String[]
args)
{
; // an empty
statement
{
}
// a pair of braces
is an empty block statement
{ }; // we can end the
block with a semi-colon
};
};
; // an empty statement outside a class
definition!
The empty statement
is useful in conditions where
you don't want
any action to be taken. In the following
example
the empty statement is used to do nothing
while the 'else clause is supplied with
the compound
statement comprised of curly braces enclosing several
statements.
Example
boolean Rain =
true;
if (Rain)
; // if rain do nothing
else{
getBeachBall( );
getLotion( );
go_swim( ); //
methods defined else where
}
Another place where
an empty statement can be useful
is in a 'for
loop'. The two empty statements in the
following 'for loop' runs forever.
Example
for( ;
; )
// a 'forever' for loop
Statements are typically grouped inside blocks, the
curly braces
used by the classes, constructors and
methods. An empty block when used with a
method
creates an empty or stub method.
Using
Blocks To Create Sub-Scopes
Sometimes a plain
unnamed block is
used which allows
the creation of sub-scopes scope where 'same named'
variables can co-exist in the same program without causing
name clashes. This
can be handy if you wanted to reuse
a section of code that has complex
expressions. Normally,
though if you sought to reuse such code you would put this
code into a method.
Example
//
each n is in it's own scope
{int n=7;
System.out.println(n);}
{int n=8;
System.out.println(n);}
{int n=9;
System.out.println(n);}
This isn't allowed
with nested scopes. The following
example doesn't compile.
Example
{
int n=7;
{ int n =11; } // won't compile
}
The static initializer
The block can also
be used to create a static initializer
that will
initialize a section of code when the class is
built. This is normally done to
improve
performance,
where code is readied at class-load time.
Example
class K{
final static double K; // assume there is a list of variables set to a
default
static
{
// the static initializer can be used to initialize them at class load
time
K=
1.101; // notice a final variable can be initialized
once but only once
}
public static void main(String[] args){
}
}
One of the most
used aspects of computer programs
is that they provide a means of supplying different
responses to different logical conditions. Java supplies
two devices to make these selections, the 'if else'
statement
and the 'switch'.
The simpler of the two is the 'if else' statement which
supplies one of
two courses of action for a program to
follow. In it's simplest form it just says ' if
something is
true do this'. With it's optional else part supplied, the
mode becomes 'if
something is true do this, else do that'.
The other device is
the switch which Java inherits
from C. In fact
Java's flow control devices are in
general similar to those found in C and C++. Java
doesn't use the 'goto' operator. Java does supply
the 'break' and 'continue' keywords that can be used
to supply some of the 'goto'
functionality. The switch
supplies several possible routes for control to follow
based on a given
condition.
The 'if else' Statement
The if else
statement has the following general form.
Form if 'if else' Statement
if ( boolean expression) Statement opt. [ else Statement ]
In the first case
it can be used in code to supply an
action if
something is true. We saw earlier an example
where nothing was done on the condition being true.
Example
if (true)
do( );
//
the action may be on the same line as the if( ) statement
// or
if (true)
do( );
Multiple
Statement Execution
The statement
following the test will execute if the
test
resolves to the boolean value true. By default,
only the single statement is executed. If the
programmer
wants more than one line of code
executed based on this condition a compound
statement needs to be supplied, enclosed in curly
braces.
Example
if (true){
doThis( ); // and
doThat( );
}
If something should
be executed in the case where the
test resolves to false then
the optional else statement
is supplied.
Example
if (true){
doThis( );
doThat( );
}
else {
doSomethingElse( );
}
'If' statements can
be nested to create more complex
decision trees.
In this case a new pair of options are
supplied to the a branch in the flow of
control.
Example
class
K1 {
public static void main(String[] args) {
if (true){
doThis( );
doThat( );
}
else if (true){
elseDoThis( );
elseDoThat( );
}
else {
doSomethingElse( );
}
}
static void doThis( )
{System.out.println("True: Do
This.");};
static void doThat( )
{System.out.println("True: Do
That.");};
static void elseDoThis( )
{System.out.println("False:True: Do elseDoThis.");};
static void elseDoThat( )
{System.out.println("False:True: Do ElseDoThat.");};
static void doSomethingElse( )
{System.out.println("False:False: Do SomethingElse");};
}
The switch Statement
Where the 'if
statement' supplies one of two alternatives
for the flow
of control, a switch statement is designed to
supply multiple options for the
execution path to follow.
A switch has an argument area in which an expression
is tested that resolves to
a byte, char, short or int integral
numeric value. This value is compared to the
value that
is associated with each of the different cases that are
supplied in the body of the switch statement.
The 'case'
statements each must use the keyword 'break'
to return from the executed statements
associated with a
given case. Otherwise the flow of control will continue to
execute into the the following cases. When subsequent
cases are executed as a result of
the the 'break' keyword
being omitted, the behavior that results is called
'fallthrough'.
Leaving out the 'break statement' is a very common error
that occurs
when using the switch statement.
//
omitting 'break' keywords results in 'fallthrough'
A default statement
can be supplied to handle the
condition where there is no matching case for the value
in the switch. If there is no default case supplied and
there are no matches, then no
statements is executed
in the switch statement. The switch statement has the
following form.
The Form of the 'switch' Statement
switch ( expression
resolving to byte, char, short or int ) {
case 1:
{ /*statements*/ } break;
case 2:
{ /*statements*/ } break;
case n:
{ /*statements*/ } break;
default: { /*statements*/ }
}
//
default executes when
there is no matching case
Note it is the value following each 'case' keyword that is
compared to the value supplied as an argument to the
switch
Example
class K1
{
public static void main(String[] args)
{
for(int i=1; i<4;i++)
{
switch ( i )
{
case 1: {case_1( ); }
break;
case 2: { case_2( ); }
break;
case 'n': {case_n( ); }
break;
default: { case_default( );
}
}
}
}
static void case_1( ){System.out.println("case
1"); }
static void case_2( ){System.out.println("case
2"); }
static void case_n( ){System.out.println("case
N"); }
static void case_default(
){System.out.println("default case"); }
}
OUTPUT
> java K1
case 1
case 2
default case
Imitation of switch behavior using if statements
Following is an example of the behavior of
the switch
construct being imitated using nested 'if
else'
statements.
We make use of the Math class method random( ) to
assist
us in generating a random number.
Anytime the
number four is generated, no cases match and
the else
branch that
represents the switch default case is
executed.
Example
class tif{
public static void main(String[]args){
int x=(int)(Math.random( )*4)+1;
if(x==1)
to("One");
else if(x==2)
to("Two");
else if(x==3)
to("Three");
else{to("default"); }
}
static void to(String s){
System.out.println(s);
}
}
More on the
'switch' The switch fallthrough feature is error-prone. Peter Van der Linden reports in his text 'Just Java' that the fallthrough feature of the switch is rarely used. He did an interesting survey where he viewed 320 switches in the Java source code, observing less than 1% used the fallthrough feature. The implication is the fallthrough behavior might have been better arranged so that fallthrough was left out by default and added optionally rather than the other way around. . |
A program can supply code that repeats a process a
predetermined
number of times or indefinitely until some
condition is met. Java supplies the
common 'for loop' for
iterating an action a specific number of times. Java also
provides
'while' and 'do' while loops for repeating iterative
processes until some condition is
met.
The 'for loop'
defines three zones in it's body. One each
for
initialiation, testing and incrementation. The first zone
is where starting values are
set. The
second zone resolves
to a boolean value that is true or false. If true, the loop
continues. The final zone is used to increment the starting
value. Following is the form the
for loop takes.
Form of the 'for loop'
for ( initialization
; test
condition ; increment )
//
a
determinate loop
The 'for loop' is
also called a 'determinate'
loop because
the number of times it will
repeat is
predetermined.
The
variables used in a for loop can be declared inside or
outside the 'for loop'.
Example
int i;
for ( i = 0; i< 99; i++)
//
or
for (int i = 0; i< 99; i++)
The initialization
and increment zones can contain
compound
initialization and increments while the
evaluation or testing zone needs to resolve to a
single
boolean value. When zones are compounded,
expressions are separated by commas.
Example
for
(int i = 0, j = 0 ; i < 100; i++ , j +=2 )
// the initiation
and increment zones can be compound
// but the test condition resolves to a single boolean value
As mentioned
earlier an infinite 'for loop' may be created
by leaving out the expressions of the for
loop. The resulting
for loop is left holding two empty statements.
Example
for ( ; ; )
//
in fact just leaving the middle condition empty runs
// the loop forever.
The next example
shows the initialization and increment
zones with
more than one comma separated expressions.
int i=0;
int j=0;
for( i=0, j=2;j<100&i<50 ;i++,j++)
System.out.println(i+" "+j);
Inside a for loop,
compound declarations can be performed
along with
initializations. What is not allowed is a nested
declaration. If a declaration occurs in
the for loop, it has to
be the first element in the initialization zone.
Bad
Compound for Loops
In the following
example, the
first for loop definition is fine.
The variable j is not in the initialization zone and z takes
it's type the same way x is declared. In the second case,
it appears to the compiler that k is
being declared twice
so this doesn't compile. The third loop also doesn't work
as the
type declaration of w is nested and so illegal. (You
may wish to uncomment each of the 'offending' loops to
get the compiler report on each problem.)
Example
class forTT{
public static void main(String[] args){
int
j=9; // 1. Good
for(int x=0, z=1; x<4;x++,j++){
System.out.println( x + " " + j);
}
/*
int
k=0; // 2. Not
OK. The compiler see's this
as a double declaration
for(int x=0, k=4; x<5;x++,k++){
System.out.println(x + " " + k);
}
int
q; // 3. Also not good! Can't nest
w's type declaration
for(q=0, int w=4; q<10;q++,w++){
System.out.println(q +
" " + w);
}
*/
}
}
Keep in mind there are only three regions in
the for loop
two which can be compounded by comma
seperation.
You can't nest a type
declaration in the initialization zone.
The while loop // indeterminate loops
The 'while' and the
'do...while' statement
are called
'indeterminate loops' because it is unknown when the
condition
will change that
results in their termination.
Following is the form
of the while loop. It takes a
boolean
expression.
Form of the 'while' Statement
while ( boolean expression ) Statement
While the boolean expression is true the statement is
executed. The
loop iterates 0 or more times. If the
expression is false control passes to the first line
of
code past the statement. If on first evaluation, the
expression resolves to false the
statement is never
executed. In the following example the loop never
stops and is like the
infinite for loop.
Example
int i =1;
while (true){
System.out.println( i ++) }
The do while loop
Sometimes a loop is
needed that runs based on a boolean
condition
however it needs to be executed at least once.
This is the function provided by the do
while loop. The do
while loop has the following form.
Form of the 'do ... while' Statement
do Statement while ( boolean expression )
In the next example the variable ' i ' will increment an
indefinite number of times if start is true. We see though
that is false. Still the loop will execute at least once, and
will be set to 1.
Example
class OneUp{
public static void main(String[] args){
boolean start=false;
int i=0;
do {
i=++i;
System.out.println(i);
}while(start);
}
}
OUTPUT
>java
OneUp
1
break & continue
The 'break' and
'continue' keywords offer granular control
over the flow control in loops. The 'continue' keyword
moves the flow of control to the
next iteration of a loop.
It is only used in loops. If used within nested loops,a
label can be joined to the 'continue' keyword to indicate
which loop will move to it's next
iteration. The next line
shows the form of continue.
Form of 'continue' in Use
continue opt. label
The 'break' keyword has a more extreme behavior than
continue. It
causes control to break right out of the loop
it is contained in.
If used with a
label, the break takes
you to the label and control
continues after the end of
the block of code
the label has been joined to. The form
the 'break' keyword takes is shown below.
Form of 'break' in Use
break opt. label
The next code
example shows how break and continue
work first
without and then with labels.
Using 'break' & 'continue' Code Sample
class
BC{
public static void main(String[] s){
int i;
for(i=1; i <8; i++){
if (i==5)
break; // breaks right out of the loop
System.out.println(i);
}
//***************************
System.out.println( ); // spacer
//***************************
int j;
for (j=1;j<8; j++){
if(j==5)
continue; // continues with the next iteration
System.out.println(j);
}
//***************************
System.out.println( ); // spacer
//***************************
int x;
int y;
/* In the following compound loop, when the system
* breaks to label A associated with the break, control
* continues at the end
of the block that the label is
* associated with, thus leaving the outer loop
*/
labelA:
for(x=0; x < 3; x++)
{
for(y=0; y < 3; y++)
{
if(y==1)
break
labelA;
System.out.println(x + " " + y );
}
} // end of labeled
block from where code continues
//***************************
System.out.println( ); // spacer
//***************************
int z;
int t;
labelB: for(z=0; z < 3; z++)
{
for(t=0; t < 3; t++)
{
if(t==1)
continue labelB;
System.out.println(z + " " + t );
}
} // continues to
labeled loop and
// proceeds with next iteration
}
}
Output
1 2 3 4 1 0 0 0 0
|
Exceptions deal
with the special case of where control
goes when
something goes wrong. Exceptions are dealt
with in a very formal and unified way in Java and so are
treated as a separate topic. The keywords 'throw' and
'throws are really flow control elements associated with
exception handling and are covered with exceptions.
The 'goto' keyword
is
reserved so we
don't have to worry
about it. The return keyword is used in methods to return
values
but is also used as a means of controlling flow.
The return keyword can be used to
exit a method before
it is completed based on some condition.
Example
class
Return{
public static void main(String[]args){
if (args.length ==0) {
System.out.println("Enter a number at the command line");
return;
}
System.out.println("Your number is " +args[0]);
}
}
1) Which of the
following is not a valid statement?
a) ;
b) { }
c) ( );
d) { };
2) Which of the
following lines needs be commented out in order
for the following code to compile? Select a, b, c or
d.
{
/*a*/
int i=3;
/*b*/
{ int i= 7;
/*c*/
i=13; }
/*d*/
{ int i= 11; }
}
3) A static initializer does not need which of the following.
a) braces
b) a block statement
c) the static keyword
d) an identifier
4) In the following if else statements what will the result be?
if (false)
System.out.println("A");
else if
(false)
System.out.println("B");
else if
(true)
System.out.println("C");
else
System.out.println("D");
a) A
b) B
c) C
d) D
5) True or False?
while(true){ }
and for( ; ; ){ } both do the same thing.
6) Which of the following keywords prevents
fall through in a switch statement?
a) switch
b) case
c) break
d) default
7) What will the following switch print out?
int x =0;
switch( x ) {
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("3");
}
a) 0
b) 1
c) 2
d) 3
8) Only one of the following for loops will compile? Which is it?
a)
for(int a=1; b=4; b<6; b++) { }
b) for(int x=0, int y=3; x<5; x++){ }
c) int z;
for(z=0, int t=4;
z<10;z++,t++){ }
d) for(int x=0, z=1; x<4;x++, z++){ }
9 ) What will the following code output?
labelA: for(int x=1; x < 3; x++){
for(int y=1; y < 3; y++){
if(y != 1)
continue labelA;
System.out.println(x + " " + y );
}
}
a) 1 1
b) 1 1
2 2
c) 1 1
2 1
d) 1 1
2 2
3 3
Code Sample
class
X9{
public static void main(
String argv[] ) {
boolean flip;
if(.5>Math.random())
flip=true;
else
flip=false;
if (flip)
System.out.println("\n"
+ "Heads");
else
System.out.println("\n"
+ "Tails");
System.out.println("\n");
//*********** a switch example **************
int
i;
for (i = 4; i > 0; i--) {
switch ( i ){
case 4:
System.out.println("Ready");
break;
case 3:
System.out.println("On your
marks");
break;
case 2:
System.out.println("Get set");
break;
case 1:
System.out.println("Go");
break;
default:
System.out.println("Restart");
}
try{
Thread.sleep(1000);
}
catch(InterruptedException io){
}
}
}
}
Q1 Modify the above
code to do the following. Create a
boolean
value, with the identifier 'holiday'. The code should
print
out to console, 'Rest' if the condition of the if...else
statement is true and
'Work' if it is false.
// see example in note
Considering the switch example in the code above . . .
Q2 What happens (in
example 2) if the condition in the for
loop of
the switch above is changed to i > -1? Explain what
happens here?
Q3 Comment out the
'break' keywords in the above switch.
What
happens? Why?
Q4 Adapt the above
switch code to print out a count down
for a
rocket take off. i.e. ten, nine eight ... blastoff!
Make
the thread
sleep for 1000 milliseconds between counts.
Q5 Write a for loop
that loops 10 times. Put in a print
statement that prints the index i at each loop. Include
an
'if' statement whose 'else' part causes the 5th iteration's
index not to be
printed
out. (Printing resumes on the 6th
iteration)
Q6 Copy the loop
you created in Q5 and change it so it stops
printing after the 5th iteration.