Java Study Guide *
-
Source Files *
-
Package *
-
Import *
-
Comments *
-
Java Names *
-
Reserved words *
-
Types *
-
Primitive types *
-
Reference Types *
-
Special Reference Types *
-
String *
-
Array Reference Types *
-
Wrapper Classes *
-
Type Conversions and Casts *
-
instanceof operator
*
-
Literals *
-
Logical ( Boolean ) *
-
Integers *
-
Hexadecimal (Base 16) Literals *
-
Octal ( Base 8 ) Literals *
-
Floating Point Literals *
-
Character Literals *
-
Reference Type Literal *
-
Class Declarations *
-
Scope *
-
Modifiers *
-
Subclassing *
-
Implementation *
-
Initialization *
-
Initializer blocks *
-
Constructors *
-
Initializer Order *
-
Exceptions in Initializers *
-
Initialization of Variables *
-
Default Values *
-
Initializing Arrays *
-
Finalization *
-
Class Member Declarations *
-
Species of Members *
-
Scope *
-
static ( Class ) Members
*
-
Instance Members *
-
Variables *
-
final ( Constants )
*
-
transient and volatile
*
-
Nested Member Classes ( Inner Classes ) *
-
static (top level) classes
*
-
inner interfaces *
-
non - static inner class *
-
Variable Declaration *
Methods *
-
static Methods *
-
Instance Methods *
-
final *
-
abstract *
-
native *
-
synchronized *
-
Method Return Type *
-
Method Name *
-
Method Parameters *
-
Method Signature *
-
Overriding methods *
-
super reference. *
-
this reference *
-
Overloading Methods *
-
Variable Shadowing *
-
Local Declarations *
-
Block Local Scoping *
-
Initialization of Local Variables *
-
Local Classes *
-
Anonymous Classes *
-
Operators *
-
Assignment Operator ( = ) *
-
Flow of Control *
-
Labeled Statements and Blocks *
-
switch *
-
for loop *
-
break Statement *
-
continue Statement *
-
return Statement *
-
Exception handling *
-
try - catch - finally
*
-
throw Statement;
*
-
Interfaces *
-
Interface variables *
-
Interface methods *
-
Threads *
-
Creation *
-
Running a Thread *
-
Thread termination *
-
Thread synchronization *
-
synchronized methods *
-
synchronized blocks *
-
Thread states *
-
wait and notify
*
-
join ( ) and isAlive
( ) *
-
Summary of Thread Methods *
Java
Study Guide
Sources:
-
Mughal & Rasmussen
-
Brogden
-
Flanagan
-
Jaworski
-
Grand
Source
Files
-
Each Source File may have only one public class or interface.
-
If a Source File has a public class or interface, the file
name must exactly match the class name, including case.
Package
-
If a package statement appears, it must be the first non-blank,
non-comment line in the source file.
-
Package source files must appear in a subdirectory with the
same name as the package.
Import
-
Classes in the same directory without a package statement
are considered to be in the "default" package, and do not require explicit
importation.
-
The java.lang package is always automatically imported. All
other packages must be explicitly imported, or fully qualified names must
be used each time.
-
The asterisk ( * ) can be used to import all the classes
in a package, but not the classes in sub packages. E.g. java.awt.*;
Comments
-
Comments in java files always use a forward ( / ) slash.
-
Comments cannot be nested.
//
Comment extends to end of line
/* Comment
can be multiline
and
extends to closing */
/**
Multiline
Javadoc
comment */
Java
Names
-
Names in java must start with a letter or the characters
_ (underscore) or $ (dollar sign).
-
All names are sensitive to case.
-
You cannot use any of the reserved words for names.
Reserved
words
These words have meaning in the language
| abstract |
boolean |
break |
| byte |
case |
catch |
| char |
class |
continue |
| default |
do |
double |
| else |
extends |
final |
| finally |
float |
for |
| if |
implements |
import |
| instanceof |
int |
interface |
| long |
native |
new |
| package |
private |
protected |
| public |
return |
short |
| static |
super |
switch |
| synchronized |
this |
throw |
| throws |
transient |
try |
| void |
volatile |
while |
| |
|
|
These are reserved but not used
const
goto
These are reserved literal values
null
true
false
These are listed in two books(2 & 3) but not two others
(1 & 4) as reserved but not used.
| byvalue |
cast |
future |
| generic |
inner |
operator |
| outer |
rest |
var |
Types
Primitive
types
| Family |
Datatype |
Size |
Max, Min |
| Logic |
boolean |
1 bit or N/A |
N/A |
| Integers |
byte |
8 bits or 1 byte |
-27 to
27 - 1 or-128 to 127 |
|
short |
16 bits or 2 bytes |
-215 to
215 - 1 or -32768 to 32767 |
|
int |
32 bits or 4 bytes |
-231 to
231 - 1 or about +- 2.1 billion |
|
long |
64 bits or 8 bytes |
-263 to
263 - 1 or +- 9.2 e 18 |
| Floating Point |
float |
32 bits or 4 bytes |
Approx. +- 1 e +-
40 |
|
double |
64 bits or 8 bytes |
Approx. +- 1 e +-
300 |
| Textual ( Unicode) |
char |
16 bits or 2 bytes |
0 to 216-1
or 0x0 to 0xFFFF |
Reference
Types
-
All other variables not declared as primitive types are object
references.
-
All classes descend from the Object type, and can be cast
to this type.
Special
Reference Types
String
-
String is a special type of object defined in
java.lang.
-
String literals are declared using double quotes ( e.g.
"String literal" )
-
String literals and String types are immutable, i.e. they
never change.
Array
Reference Types
-
Arrays are objects.
-
Arrays have one instance variable .length
, which returns the size of the array.
-
Array indexes begin at zero and go to .length
- 1 .
Wrapper
Classes
Each primitive type has a wrapper class.
| Primitive Type |
Wrapper Class |
| boolean |
Boolean |
| byte |
Byte |
| short |
Short |
| int |
Integer |
| long |
Long |
| float |
Float |
| double |
Double |
| char |
Character |
Instances of Wrapper classes are immutable, i.e. their
value cannot be changed.
Type
Conversions and Casts
-
Java will implicitly perform widening conversions.
-
For primitive types, this is a promotion up the number hierarchy
byte -> short
-> int -> long
-> float -> double,
and char -> int
-> etc.
-
For reference types, these are promotions up the class hierarchy.
-
Narrowing type conversions require explicit casts.
-
Arrays can be cast to Object.
-
Reference arrays may be cast to reference arrays of a superclass.
instanceof
operator
Object classes can be compared using the instanceof
operator
<object> instanceof < Class
>
Any instanceof comparison
to a null object will produce false.
Comparisons of individual objects can be done using getClass
e.g. obj1.getClass() == obj2.getClass()
Literals
Logical
( Boolean )
-
The two boolean literals are true
and false ( case sensitive ).
Integers
-
The default type for integer literals is int.
(e.g. 89459 ).
-
long literals are specified by appending an L
or l (e.g. 294375L
).
-
There is no way to specify a literal as specifically short
or byte.
-
Integer literal can be assigned using Hexadecimal or Octal
values.
Hexadecimal
(Base 16) Literals
-
Hexadecimal literals begin with a 0
(zero) followed by an upper or lower case X.
(e.g. 0xffff )
-
The case of the digits does not matter? 0xFFFF
= 0xffff
.
-
Hexidecimal numbers with more than two digits are always
greater than the decimal representation (e.g. 0x123
> 123 )
Octal
( Base 8 ) Literals
-
Octal literals begin with a 0
zero ( e.g. 0123)
-
Octal numbers with more than two digits are always less than
their decimal representation (e.g. 0123 < 123
)
Floating
Point Literals
Floating point literals are assumed when...
-
the number has a decimal point.
-
the number is in scientific notation. (e.g.
5e-1 or 5E-1 )
-
The default type for floating point is double.
-
double literals can be specified
by appending d or D
-
float literals can be specified
by appending f or F
Character
Literals
Can be specified ...
-
between single quotes ( e.g. 'c'
).
-
as Unicode escape using a 4 digit Hexidecimal value ( Note
the missing 0x ) between single quotes (e.g. '\u1F1F'
)
-
as an octal value ( Note the lack of a preceding zero ) between
single quotes (e.g. '\377' )
-
as a character escape between single quotes (e.g. '\n'
)
public class TestChar {
static char One = 'Z'; // char literal
static char Two = 0x5a; // Hex Value
static char Four = '\u005a'; // Unicode Literal
static char Five = '\132'; //Octal Value Character Literal
// static char Three = \u005a;
// Thinks that you are referring to a variable called
Z!
static {
System.out.println(One + "," + Two + "," + Four + ","
+ Five);
// Output is Z,Z,Z,Z
}
public static void main (String ars [] ){ }
}
Reference
Type Literal
-
Reference types can have the literal value null.
Class
Declarations
Scope
-
public - This class can is
available to any other part of the program inside or outside of its package.
-
(none) - This class is available only inside the package
where it is declared.
Modifiers
abstract or final
-
abstract - An instance of this class cannot be created
directly, but must be subclassed. Classes with at least one abstract method
must be explicitly declared abstract.
-
final - This class cannot
be subclassed.
-
By definition, the modifiers are mutually exclusive.
-
The order in which the scope and modifier appear does not
matter. (e.g. public final class ... is
equivalent to final public class ... )
Subclassing
-
extends - A class may subclass
one and only one superclass in its extends clause.
-
??A class cannot extend an interface??
Implementation
-
implements - A class may
implement any number of interfaces using the implements clause.
-
Interface names are separated by commas.
-
??A class cannot implement another class??
Initialization
Initializers - blocks of code or expressions
that create the initial state.
Initializer
blocks
-
A class may specify blocks of code to be run as initialization.
static
{ } // will be run upon creation of the class
or
{ } //
will be run upon creation of an instance of the class
-
Static blocks are run upon class startup, while unlabeled
blocks are run during creation of an instance of the class.
-
There may be any number of blocks, and they will be run in
the order in which they appear in the source file.
Constructors
Constructors look like methods ...
-
and have the same name as the class
-
except that they have no return type.
-
A class may have any number of constructors as long as the
parameter lists differ.
-
A constructor may call another constructor in the class,
using the this syntax, or in its superclass,
using the super syntax, as long as it is
the first statement in the constructor.
-
Java implicitly inserts the statement super
( ); as the first statement of every constructor unless the first statement
explicitly calls to another constructor.
-
If no constructors are declared for a class, the compiler
will create a default no arguments constructor.
-
If a class does not declare any constructors, and its super
class does not have a no-arguments constructor ( perhaps because it explicitly
declares other constructors), the compiler will generate an error, because
it will generate a default constructor for the class, which tries to call
the no-arguments constructors for the super class, which does not exist,
because the constructors that were declared prevented a default constructor
from being created.
e.g.
class
A {
A ( int
n ) { }
}
class
B extends A { }
// Should
generate the compiler error
// "No
constructor matching A ( ) found in A "
-
Superclass constructors are run before the subclass constructor.
( 5 )
-
Declaring a constructor as private will prevent any other
class from creating an instance of a class. static member function may
still create an instance of the class ( because they have access to private
members ).
Initializer Order
-
Upon reference to a class, the order in which code executes
to create an initial state is:
static initializers ( only the first time the class
is loaded )
superclass initializers
superclass constructors
instance initializers
constructors
e.g.
class
A {
public
A() { System.out.println("Constructor in A");}
static
{ System.out.println("Static Initializer in A");}
{ System.out.println("Instance
Initializer in A"); }
} //
End class A
class
B extends A {
public
B() { System.out.println("Constructor in B");
}
static
{ System.out.println("Static Initializer in B");
}
{ System.out.println("Instance
Initializer in B");}
} //
End class B
class
D {
static
{System.out.println("Static Initializer in D");
}
}
public
class ConstructionTest {
static
{System.out.println("Static Initializer in ConstructionTest");
}
public
static void
main (String [] args) {
new
B(); }
} //
End ConstructionTest
The output from this program is:
Static Initializer in ConstructionTest
Static Initializer in A
Static Initializer in B
Instance Initializer in A
Constructor in A
Instance Initializer in B
Constructor in B
Note that the class D is not loaded, but if the main method
is changed to
public
static void
main (String [] args) {
new
B( );
new
D ( ); }
The output becomes:
Static Initializer in ConstructionTest
Static Initializer in A
Static Initializer in B
Instance Initializer in A
Constructor in A
Instance Initializer in B
Constructor in B
Static Initializer in D
-
Initializer expressions and blocks cannot have cannot have
forward references to variables defined further in the code.
e.g.
class
A {
static
int B = 1;
static
int C = B * D; //
Compiler Error
static
int D = 1;
}
-
The order of initializers is important to the logic.
e.g.
class
A {
static
int B = 1;
static
int C = ValueOfC(); //
Logic Error
static
int D = 1;
static
int ValueOfC(){
System.out.println(D);
return
B * D;
}
}
public
class ForwardTest {
public
static void
main (String [ ] args){
new
A();
}
}
While class A may appear to have a forward reference,
this program compiles. The error occurs in the logic. When the call to
ValueOfC is made, D is not properly initialized and the value output by
program is zero, the default value for D. Thus C acquires the value 1 *
0 = 0, because of the incorrect order of initialization.
Exceptions
in Initializers
-
Initializer expressions and static initializer blocks must
catch and handle any checked exceptions that might be thrown by their execution.
-
Instance initializer blocks do not have to catch checked
exceptions if they are declared in the throws clause of every constructor
in the class.
-
Initializers for anonymous classes may throw any exception
( ?? where is it caught?)
Initialization
of Variables
Default
Values
-
At the field level ( not declared locally ), all variables
are automatically initialized to default values when created.
| DataType |
Default Value |
| boolean |
false |
| char |
'\u0000' |
| Integer ( byte, short, int, long
) |
0 |
| Floating-point ( float, double
) |
+0.0F
or +0.0D |
| Object Reference Type |
null |
-
Variables can be initialized at creation using the assignment
operator ( = ).
e.g. int i = 100 ;
-
Instances of reference types are created using the new operator
and one of the object's constructors.
e.g. String s = new String ( "This
is a String") ;
Initializing
Arrays
-
Arrays are created with the new operator and a size.
e.g. int [ ] i = new int [
10 ] ;
-
Elements of arrays created this way are initialized to their
default values i.e. null or zero.
-
Arrays can also be initialized using curly braces.
e.g. int [ ] i = { 1, 2, 3,
4 };
or int [ ] i = new int [ ] {1,
2, 3, 4 };
-
When done this way, the size of the array cannot be specified
by the programmer.
e.g. int [ ] i = new int [4]
{1, 2, 3, 4 }; // Statement will fail
-
Multi Dimensional arrays can also be initialized using new,
but the dimensions must be specified from left to right.
e.g. int [ ] [ ] = new int [ 4 ]
[ ] ; // will work
but int [ ] [ ] new int [ ] [
4 ] ; // will fail
-
Multi dimensional arrays can also be specified using curly
braces.
e.g. int [ ] [ ] = { {1,2} , {3,4}
}
-
Since multidimensional arrays are really arrays of arrays,
each dimension can be a different length.
e.g.
int [ ] [ ] = { {1,2} , {3, 4,
5, 6}, null , { } , new int [ 10 ] };
// all valid assignments
Finalization
Finalizer methods
A object finalizer method ...
-
overrides the do nothing finalize method of Object:
protected void finalize ( )
throws Throwable { }
-
can be overloaded, but only the one named
finalize ( ) will be called by the garbage collector.
-
must have a void return type
( because of overriding ).
-
can only be declared public
or protected ( again because of overriding
).
-
can call its superclass finalizer as the last statement using
super.finialize();
-
can catch exceptions normally within its method body, but
any unhandled exceptions will ignored by the garbage collector.
-
Because of the way the garbage collection system works, there
is no guarantee that this method will ever be called.
-
If this object is garbage collected, the finalize method
is guaranteed to be called before the object is collected.
-
This method may keep this object from being destroyed by
restoring a reference to itself.
-
If this method is invoked and it prevents the object from
being destroyed, it will never be invoked again, even when the object is
finally destroyed.
Class
Member Declarations
Species
of Members
A class member can be one of three species, variable,
method, or nested class.
Scope
-
public - available in throughout
the program to all classes in all packages.
-
protected - available only
to classes in the same package or to subclasses of this class.
-
(none) – {called default or Package} available only to classes
in the same package.
-
private - available only
within the class in which it is defined.
static
( Class ) Members
-
Declaring a member as static
means it is available to class as a whole and no specific instance of the
class is needed to reference the member.
-
Outside of the class definition static members are referenced
using the syntax <ClassName>.<Member>
Instance
Members
-
Not declaring a member as static
means there is one instance for each instance of the class.
-
An instance of a class may reference itself using the implicit
variable this.
Variables
final
( Constants )
-
Declaring a variable as final
means that its value cannot be changed after it is assigned.
transient
and volatile
-
Declaring a variable as volatile
means that it will be accessed by more than one thread at a time.
-
Declaring a variable as transient
means it should not be serialized.
Nested
Member Classes ( Inner Classes )
-
A nested class cannot have the same name as an enclosing
class or package.
static
(top level) classes
Nested classes declared as static...
-
have access to all static
members of the enclosing class. ( including private
members ).
-
do not have any instance of the enclosing class associated
with them. ( as compared to non-static nested classes )
inner
interfaces
-
Inner interfaces may only be declared as static
( top level).
-
Inner interfaces are implicitly static and abstract.
-
??Inner interfaces may only have public or package access.??
non
- static inner class
Nested classes defined without the static
modifier...
-
have access to all members of the enclosing class, both static
and non - static, public and private.
-
are always associated with an instance of the enclosing class.
-
cannot define any static
members.
-
Many instances of a non - static nested class may be associated
with one instance of the enclosing class.
-
Non - static inner classes have an implicit reference to
their associated instance of the enclosing class. They may obtain the reference
using the special syntax of <Enclosing Class
Name>.this (e.g. EnclosingClass.this
).
-
Non-static inner classes must be created using a special
syntax of the new operator.
e.g.
TopLevel.Inner1.Inner2 TII =
new TopLevel ( ).new Inner1 ( ).new Inner2 ( );
Variable
Declaration
-
Variables of the same type may declared on the same line
by using commas to separate variable names (e.g. int
i , j , k )
-
Arrays are declared using square brackets (e.g.
int [ ] i ; or int i [ ]; are equivalent.
)
-
Note there is a subtlety when combining these two rules...
int [ ] i , j ; creates
two integer arrays.
int i [ ] , j ; creates
one integer array i and one single integer j.
-
Arrays of arrays can be declared using multiple sets of brackets
( e.g. int [ ] [ ] i; )
Methods
static
Methods
-
static methods cannot access
any non - static members without an instance of the class.
Instance
Methods
final
-
Methods declared as final
cannot be overridden by subclasses.
-
final methods can be overloaded
by subclasses.
abstract
-
Methods declared as abstract
must be overridden in a subclass.
-
abstract methods must end
with a semicolon rather than a block.
-
Declaring a method as abstract
means that the class itself must be explicitly declared abstract.
-
An abstract method cannot
be declared final, private,
or static.
native
-
native methods must end with
a semicolon rather than a block.
-
native methods are platform
specific.
synchronized
-
static synchronized
methods obtain a lock associated with a class before execution.
-
Non-static synchronized methods
obtain a lock on the object instance before execution.
-
Two different static synchronized
methods of the same class cannot execute at the same time.
-
A static and non-static synchronized
method may execute at the same time?
Method
Return Type
-
Methods that return arrays may specify the array brackets
before or after the formal parameters. ( 5, p143 )
e.g. These are all valid and equivalent methods:
int [ ] [ ] [ ] A ( ) { }
int [ ] [ ] A ( ) [ ] { }
int [ ] A ( ) [ ] [ ] { }
int A ( ) [ ] [ ] [ ] { }
Method
Name
-
It is an error to declare a method with the same name as
a variable in the class or superclasses.
Method
Parameters
-
All method parameters are passed by value, including reference
type variables. However since a reference to an object is passed, that
object can be referenced.
e.g.
class
B {
int
Bint = 100;
}
class
C {
int
i = 100;
B Bobj
= new B ( );
void
CallD {
D (i
, Bobj );
}
void
D (int x, B y ) {
x=10;
y.Bint
= 10; //
Changes the value of the object's member
y =
new B ( );
}
public
static void main(String [ ] args ) {
C Ctest
= new C ( );
Ctest.CallD;
System.out.println
( Ctest.i ) ; // Outputs 100
System.out.println
(Ctest.Bobj.Bint ) ; // Ouputs 10
}//
End Main
} //
End Class C
Method
Signature
-
A method's signature is composed of its name, and its parameters
number, type, and order. The name of the parameters does not make any difference.
e.g.
int
A(int B, int
C, long D) { } //
Reference method
int
A(int D, int
B, long C) { } //
Same signature
int
A(long B, long
C, int D) { } //
Different, types
int
A(int B, long
D) { } // Different, number
int
A(int B, long
D, int C) { } //
Different, order
-
A method's return type does not count into its signature.
e.g.
int
A(int B, int
C, long D) { } //
Reference method
long
A(int D, int
B, long C) { } //
Same signature
-
Declaring parameters final does not enter into its signature.
e.g.
int
A(int B, int C, long D) { } // Reference method
int
A(final int B, final int C, final long D) { } //
Same signature
Overriding
methods
If a class declares a method with the same signature as
a method in its superclass, it can override that method, provided...
-
the superclass method is not declared final. However if a
superclass method is declared private, the method name may be reused in
the subclass, but it will have no access to the superclass method.
-
they have the same return type.
-
it does not "narrow" accessibility.(i.e. cannot make a public
-> protected -> package
-> private. ) However, it may widen accessibility.
-
it does not "widen" the exceptions thrown. It may only throw
all or a subset of the exceptions thrown by the superclass method.
e.g.
class
ExceptionA extends Exception { }
class
ExceptionAA extends ExceptionA { }
In Superclass
void
C ( ) throws ExceptionA { } //
Superclass method
Possible methods In Subclass
void
C ( ) throws ExceptionA { } //
Overrides
int
C ( ) throws ExceptionA { } //
Error, different return type
private
void C ( ) throws
ExceptionA { }
//Error,
narrowed accessibility
protected
void C ( ) throws
ExceptionA { } // Overrides
void
C ( ) throws Exception { } //
Error, widens exceptions
void
C ( ) throws ExceptionAA { } //
Overrides
void
C (int
z ) throws
ExceptionA { }
// Does
not override, but overloads
-
There is no way to directly access the superclass version
of an overridden method from outside the class hierarchy.
super
reference.
-
A class has an implicit reference to its superclass which
can be accessed using the super keyword.
-
The super reference cannot
be accessed from outside the class hierarchy.
-
The super reference cannot
be assigned to a variable, or cast to another type.
-
The super reference cannot
be chained to access the superclass of the immediate superclass. e.g. super.super.SomeMethod
( ) is not legal syntax.
this
reference
-
Each object has an implicit reference to itself, accessed
through the this keyword.
-
This reference may be assigned a variable or cast to a compatible
type.
Overloading
Methods
-
Methods with the same name, but different signatures, are
considered to be overloaded.
-
Changing return types or exceptions thrown, does not change
the signature, and therefore cannot be used to overload methods.
-
Overload methods may have different return types.
e.g.
void
A( ) { } // reference
int
A ( ) { } // Error, return type does not change
signature
long
A ( int i ) { } //
OK, different signature
Variable
Shadowing
-
If a variable has the same name as a variable in its superclass,
that superclass variable becomes shadowed, and super
syntax must be used to access that variable.
-
Overridden methods are invoked according to the current
class of the object, not the reference type, but shadowed variables are
invoked according to the reference type not the current class.
e.g.
class
A {
int
B = 10;
int
C ( ) { return 10;}
}
class
D extends A {
int
B = 100;
int
C ( ) { return 100;
}
}
public
class TestShadow {
public
static void
main(String [] args){
D Dtype = new
D ();
A Atype = Dtype; //
Upcast to A class
System.out.println (Dtype.B);
System.out.println (Dtype.C(
) );
System.out.println (Atype.B);
// Shadowed Value
System.out.println (Atype.C(
) ); // Still overridden value
}
}
The output from this program is:
100
100
10
100
Local
Declarations
Block
Local Scoping
-
Declarations within a block of code are only valid within
that block or in a nested sub block. This applies to all blocks, including
loops, ifs, and error handlers.
e.g.
int
i;
{
int
j;
{
int
k;
i=1;
// ok
j=1;
// ok
k=1;
// ok
}
i=1;
// ok
j=1;
// ok
k=1;
//Error, k not defined in this block
}
i=1;
// ok
j=1;
// Error, j not defined in this block
k=1;
//Error, k not defined in this block
-
Block Local Scoping applies to local class definitions as
well.
Initialization
of Local Variables
-
Local Variables are not automatically initialized to default
values. If there is not an explicit initialization, the compiler will flag
it as an error.
Local
Classes
Local Classes ...
-
are define in context of a block, and as such, have block
local scoping, i.e. the name of the class is only valid within the block
or nested sub block.
-
cannot declare any static
members.
-
cannot have any accessibility, the same as for local variables.
-
If a local class is defined within a static
context, it may only access the static
members of the enclosing class or superclasses. If it is defined in a non-static
context, it may access any member of the enclosing class or superclasses.
-
Local classes may access local variables or method parameters
declared as final visible from the context
in which it is defined, but may not change their value.
-
If a local class is defined within a non-static context,
instances of the class are passed an implicit ( hidden) reference to the
enclosing class. This reference can be accessed using the special
<EnclosingClassName>.this syntax.
-
A method may return an instance of a local class, but since
the class is not visible outside the block, the reference must be upcast
to one of its visible supertypes to be returned.
e.g.
class
SuperA {
String T = "Shadowed
SuperA";
String S ="SuperA";
}
class
SuperInner {
String T = "Super
Inner";
void
PrintClass ( ){
System.out.println("Class
SuperInner");
}
}
public
class OuterA extends
SuperA {
String T = "OuterA";
public
static void
main(String [] args){
OuterA A = new
OuterA ( );
SuperInner SI = A.TestInnerClass("Final
Variable");
SI.PrintClass();
}
SuperInner TestInnerClass (final
String B){
class
InnerClass extends SuperInner {
String T = "Innner
Class";
{System.out.println(OuterA.this.T);}
{System.out.println(OuterA.this.S);}
{System.out.println(T);}
{System.out.println(super.T);}
{System.out.println(B);}
void
PrintClass ( ){
System.out.println("Class
InnerClass");
}
}
return
new InnerClass ();
}
}
The output of this program is:
OuterA
SuperA
Inner Class
Super Inner
Final Variable
Class InnerClass
Notice that the object returned is an instance of the
inner class cast to a reference of the superclass, as demonstrated by the
last line of output, which is from the overridden version of the method.
Anonymous
Classes
Anonymous classes ...
-
can extend a class or abstract
class ,or implement an interface.
-
can be defined and used anywhere a class reference would
normally be used, i.e. in expressions, parameters, return statements, etc.
)
-
cannot define constructors ( but can use instance initializers.
)
-
cannot define any static
members.
-
cannot have any accessibility modifiers.
-
are defined using an extension of the new
syntax.
-
can access any local variable defined as final
in its scoping.
-
Anonymous classes defined in a static
context may only access static members
of the enclosing class.
-
Anonymous classes defined in a non-static context may access
any member of the enclosing class. They can also access the implicit reference
to their enclosing class using the <EnclosingClassName>.this
syntax.
e.g.
class
SuperA {
String T = "Shadowed
SuperA";
String S ="SuperA";
}
class
SuperAnonymous {
String T = "Super
Anonymous";
void
PrintClass ( ){
System.out.println("Class
SuperAnonymous");
}
}
public
class OuterA extends
SuperA {
String T = "OuterA";
public
static void
main(String [] args){
OuterA A = new
OuterA ( );
SuperAnonymous SI = A.TestAnonymousClass("Final
Variable");
SI.PrintClass();
}
SuperAnonymous TestAnonymousClass
(final String B){
return
new SuperAnonymous () {
String T = "Anonymous
Class";
{System.out.println(OuterA.this.T);}
{System.out.println(OuterA.this.S);}
{System.out.println(T);}
{System.out.println(super.T);}
{System.out.println(B);}
void
PrintClass ( ){
System.out.println("Class
AnonymousClass");
} //
End of Anonymous PrintClass method
} //
End of Anonymous Class
; //
Actually the end of the return statement
} //
End of TestAnonymousClass
}
The output from this program:
OuterA
SuperA
Anonymous Class
Super Anonymous
Final Variable
Class AnonymousClass
Operators
-
Operator precedence goes like this
Multiplication / Division / Modulus
Addition / Subtraction
Shift
Relational ( < , >= , instanceof, etc.)
Equality / Not Equal
AND ( & )
XOR ( ^ )
OR ( | )
Conditional AND ( && )
Conditional OR ( | | )
-
Floating Point operation do not throw Arithmatic Exceptions
Assignment Operator
( = )
-
Assignments can be chained. (e.g. X
= Y = Z = 10; )
-
Assignments return the value of the assignment.
e.g. System.out.prinln ( Y =
10 ) ; prints 10 and gives Y the value 10.
Flow
of Control
Labeled
Statements and Blocks
-
Labels have their own separate namespace, and do not conflict
with other names in the code.
-
Labels must conform to the legal naming rules.
-
Labels are terminated with a colon.
-
Labels may be associated with a block of code.
-
Multiple labels may be associated with the same statement.
-
??Labels can be reused as long as they are not nested.
-
Labels can be reused sequentially any number of times.
-
Nested labels shadow the enclosing label in the blocks which
they define. ( According to my example )
-
??Labels are defined throughout the block in which they appear.
e.g.
public
class TestLabel {
static
final int SFV = 100;
public
static void main (String [] args){
boolean
b = true;
main:
while
(b ) {
break
main;
}
System.out.println("Break
first loop");
main:
while
(b ) {
break
main;
}
System.out.println("Break
second loop");
main:; //
legal but cannot be the target
// of
control transfer since it does not create
// an
enclosing context and there is no goto
main:{
if
(b) break main;
System.out.println("In
Block");
}
System.out.println("End
of block");
main:{
if
(!b) break main;
main:{
if
(b) break main;
System.out.println("In
Nested Block");
}
System.out.println("End
Nested Block");
if
(b) break main;
System.out.println("In
block");
}
System.out.println("End
of block");
main: SecondLabel: ThirdLabel:{
if
(b) break SecondLabel;
}
} //
end main
} //
end class
The output of this program is:
Break first loop
Break second loop
End of block
End nested block
End of block
switch
-
switch statements cannot
have duplicate case labels.
-
A switch statement can have
at most one default label.
-
case labels, including the
default may appear in any order.
-
Execution will fall through to the next label unless a break
is used.
-
Multiple case labels can
be specified for the same set of statements.
-
Case labels can be integer literals, char,
or static final variables (int?).
-
Case labels cannot be expressions.
-
The switch expression must be assignable to an int
datatype (i.e. char, byte, short, or int
)
-
The compiler will error if the range of the switch
expression type cannot cover all the constants used in the case
labels.
e.g.
public
class TestSwitch {
static
final int SFV = 100;
public
static void main (String [] args){
byte
b = 10;
switch
(b){
default:
{ }
case
1: case
2: case
3:
{}
case
SFV:
{ }
// case
300: causes a compiler error
{ }
}//
end switch
} //
end main
} //
end class
for
loop
-
Any and all sections of a for
loop may be empty.
-
Multiple statements may be used in the initialization and
increment section when separated by commas.
-
Variables declared in the initialization section are local
to the loop.
break
Statement
-
The break is used to transfer
control out of a surrounding context.
-
Used without a label, the context is the immediate surrounding
loop or switch.
-
With a label, control is transferred out of the labeled block,
loop, or switch.
-
If the break is enclosed by a try-catch-finally, the finally
clauses will execute before control is transferred out.
continue
Statement
-
The continue statement is
used to transfer control immediately to the end of a loop. In a do and
while loops, execution resume with the loop conditional. In for loop, execution
resumes with the increment expression.
-
Used without a label, control is transferred to the currently
surrounding loop.
-
Used with a label, control is transferred to the surrounding
loop with the corresponding label.
-
If the continue is enclosed in a try-catch-finally, the finally
clause will execute before control is transfered.
return
Statement
-
The return statement transfers
control immediately back to the calling method.
-
If the method type is void, a return
statement is not mandatory, but if it is used, it may not have any value
associated with it.
-
If the method type is not void, the method must return a
value assignable to the methods type.
-
Non value returns may be used in constructors and initializers.
-
If the return statement is enclosed in a try-catch-finally,
the finally clause will execute before control is transferred back to the
invoking method.
Exception
handling
-
Error and Exception are subclasses of java.lang.Throwable,
so all Exceptions are assignable to Throwable and can be caught as throwable.
.
-
Error classes are system related, and generally irrecoverable.
-
Subclasses of Exception are called 'checked', and must be
dealt with, except for those that derive from the Exception subclass RuntimeException,
which are called 'unchecked'.
-
Checked exceptions must either be caught and handled, or
stated in the throws clause of the method.
try
- catch - finally
-
TCF must use blocks , i.e. it cannot use single statement
notation.
e.g. illegal syntax
try
something( );
catch
(Exception e ) recover();
finally
whew ( ) ;
-
The catch block will catch exceptions that are assignable
(upcastable ) to its exception type.
-
Once a catch block is executed, all other catch blocks in
the TCF are skipped, even if another exception is thrown.
-
The compiler will flag an error if a superclass of an exception
is caught before the subclass, because that subclass catch will never execute.
-
The finally block will always execute, even if the exception
is not caught or another is thrown.
-
The blocks of a TCF obey the block scoping rules, and the
argument of a catch block is scoped only in its block.
-
If after exiting a TCF (including the finally) an exception
is still pending, execution aborts as if an exception was thrown. If no
exception is pending, execution resumes after the TCF.
throw
Statement;
-
The throw statement is used to raise an exception that can
be caught or passed up the hierarchy.
-
Since exceptions are objects, generally the throw statement
uses an anonymous class syntax to create the exception. e.g. throw
new Exception ( );
-
For checked exceptions, the compiler will enforce that the
method either handles the exception or declares it in its throws
clause.
-
??Unchecked exceptions ( exceptions descended from RuntimeException
) are not enforced by the compiler.
-
If a method throws a checked exception back up to its calling
method, that exception must be assignable ( of the same class or a subclass
) to an exception listed in the throws
clause of the method.
Interfaces
-
An interface may declare only methods and variables. Interfaces
cannot declare any constructors, initializers, or nested interfaces or
classes.
-
All interface members are implicitly public (Java lang spec
9.1.5)
-
If an Interface is declared public,
the file name must match the interface name, and it may be the only public
class or interface in the file.
-
If an interface is declared without the public modifier,
it can only be accessed from the package, but its members are still public.
This creates an unusual problem. Interface methods are implicitly
public, which is why the compiler gives
an error for this example code that says you must use a public method to
override the method of the interface.
interface A {
void TestMethod ();
}
public class B implements A {
void TestMethod () { }
}
-
By definition, the interface and all its methods are abstract,
and do not need to be declared as such.
-
Interface methods are declared using the method prototype
followed by a semicolon, i.e. no method body.
-
Interface methods cannot be static.
-
Interfaces may extend other interfaces using the extends
clause.
-
Unlike classes, and interface may extend multiple other interfaces
by separating the interface names with commas in the extends
clause.
Interface
variables
-
Interface variables are implicitly public,
static and final,
even if not declared as such.
-
Every variable declaration must have an initializer expression
that sets the value of the variable.
-
Variables cannot be declared transient
or volatile.
-
Interface variables may become shadowed by inheritance or
ambiguous by implementation. Since interface variables are final
and static, they may be resolved using
the interface name.
Interface
methods
-
Implementing an interface method is overriding an abstract
method, and so must follow the same rules.
-
Methods are implicitly public
and abstract.
-
Methods cannot be declared static,
final, native,
or synchronized.
-
If an interface inherits multiple methods with the same signature
and the same return type, there is no problem, i.e. it is the same prototype.
-
If an interface inherits multiple methods with the same signature
and different return types, it will cause a compile error. The same applies
when an interface overrides a method.
-
Methods declared in an interface must declare appropriate
checked exceptions that may be thrown by the methods that will implement
it. (Rules of Overriding ))
Threads
Creation
-
A Thread can be created by subclassing the Thread class and
overriding the method public void run ( ).
-
A Thread can also be created by implementing the Runnable
interface, which has one method, public void run
( ), and then pass that object to a Thread object at the thread's
construction.
-
A program will continue to run as long as there are non-daemon
threads executing.
-
A thread may be made into a daemon, which is a thread that
will automatically terminate when all non-daemon threads have terminated,
if a call to setDaemon ( boolean ) is made
before the thread is started.
-
Threads have a priority, initially inherited from the creating
thread. Threads with the highest priority will generally be run first.
Running
a Thread
-
Threads are started using the start
( ) method.
-
After start ( ) is called,
isAlive ( ) will return true, possibly
before start ( ) returns.
Thread
termination
A Thread dies under one of the following conditions
-
The run ( ) method of the
thread ends and returns.
-
An exception is thrown that causes run
( ) to exit.
-
The Thread's stop ( ) method
is called. This causes a ThreadDeath exception
to be thrown.
-
When any exception is thrown from the
run ( ) method, it is passed to the uncaughtException
( ) method of the ThreadGroup for
the Thread. The thread dies but all other
non daemon threads continue to run.
Thread
synchronization
-
Every class has a general monitor for the class, and one
for every instance of the class. These monitors can be used to synchronization
methods.
synchronized
methods
-
Declaring a method with the synchronized modifier will force
a thread to acquire the monitor before it enters the method body. Once
the monitor is acquired, no other thread may acquire the monitor until
it is released.
-
synchronized static
methods acquire the class monitor, while instance methods acquire the monitor
of a particular instance of an object.
-
The thread with the monitor may execute any other synchronized
methods for that monitor. Threads without the monitor may not execute any
synchronized methods for that monitor.
Unsynchronized methods may be executed at any time by any thread.
-
Subclasses that override synchronized
methods from the superclass, do not need to make them synchronized.
synchronized
blocks
-
Threads may also acquire an arbitrary monitor to execute
a block of code by using the syntax
synchronized ( <ObjectReference>
) { }. This syntax will acquire the object's monitor while the code
block executes. This strategy only works if the other threads check this
monitor as well.
Thread
states
Threads can be in one of four states
-
Ready-to-Run : Thread may run when the scheduler gets to
it.
-
Running : Thread is currently executing.
-
Non-Runnable : Thread is in one of three non-runnable states,
Waiting, Sleeping, or Blocked
-
Dead : Thread has terminated.
-
Threads in a non-runnable state must first transition to
the Ready-to-Run state before they can transition to Running.
-
Threads that have transitioned to the Dead state may not
be restarted.
-
The static method Thread.yield (
) will move a thread from Running to Ready-to-Run.
-
The static method Thread.sleep (
long milliseconds ) moves a thread to the Non-Runnable ( Sleeping
) state. The thread will be moved to Ready-to-Run when the specified time
has elapsed.
wait
and notify
-
wait, notify,
and notifyAll are Object
methods, and must be called from synchronized
blocks because they must have the object's lock.
-
wait, notify
and notifyAll cannot be used in static
contexts.
-
The wait ( ) method will
move a thread to Non-Runnable ( Waiting ) state. This will release all
the locks the object might have and the thread will be put on the wait
list of threads waiting on this object. The thread will remain in the waiting
state until it is put into the Ready-to-Run state by a notify
( ) from another thread. There is also a form of the wait
( ) method which uses a timeout, which does not require a notify.
-
The notify ( ) method selects
an arbitrary Thread from the list of threads on the object's wait list,
and puts it in the Ready-to-Run state. the notifyAll
( ) puts all waiting threads in the Ready-to-Run state.
-
Once moved back to the Ready-to-Run state, the thread must
acquire the object's lock before it can run. Once it has acquired the lock,
execution resumes with the statement following the call to
wait ( ).
join
( ) and isAlive
( )
-
The join ( ) method of a
thread will not return until the thread has finished execution and died.
-
isAlive ( ) returns true
after the start ( ) method of a thread
has been called ( but not necessarily returned ), and returns false after
the thread has died.
Summary
of Thread Methods
| Method |
Class |
Static or Instance |
throws InterruptedException |
Must be Executed in synchronized
block- |
| start
( ) |
Thread |
Instance |
|
|
| run
( ) |
Thread |
Instance |
|
|
| interrupt
( ) |
Thread |
Instance |
|
|
| join
( ) |
Thread |
Instance |
|
|
| yield
( ) |
Thread |
static |
|
|
| sleep
( long ) |
Thread |
static |
yes |
|
| wait
( ) |
Object |
Instance |
yes |
yes |
| notify
( ) |
Object |
Instance |
|
yes |
| notifyAll
( ) |
Object |
Instance |
|
yes |
Deprecated Methods:
suspend, resume,
and stop have been deprecated in Java 2.