JAVA-HOWTO PREPARE FOR SUN CERTIFIED JAVA PROGRAMMER EXAM
Java Study Note: Jan 4 - Mar 4, 2002
These are the study notes I made while preparing for my SCJP2 Exam.
When I find the time, I will convert it to an HTML doc with links and diagrams,
hopefully my note 'as-is' can be of service to others preparing for the
SCJP2 Exam. To give these notes some perspective, they are written from someone
with a professional development background in C++ as such it may have some
omissions!
Best of luck!! :^D
- Rajinder Yadav
In following with the Linux/OpenSource/OpenDoc philosophy, I am making my java
notes available for free to the public under the GNU FDL (GNU Free
Documentation License).
JAVA-HOWTO PREPARE FOR SUN CERTIFIED JAVA PROGRAMMER EXAM
Copyright (c) 2002 Rajinder Yadav
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with no Invariant Sections, with the no Front-Cover Texts, and with
no Back-Cover Texts being LIST. A copy of the license is included in
the section entitled "GNU Free Documentation License".
A copy of the GNU FDL can be obtained at, http://www.gnu.org/licenses/fdl.html
If you have signed the SUN CERTIFIED JAVA PROGRAMMER EXAM
Non-disclosure form, please do not make changes or modifications
to this document other than for personal use. You are still
granted to make copies and redistribute the document. This
restriction has been added to assure that this document is
allowed to be freely available without any legal restriction
to others.
If you have not signed the SUN CERTIFIED JAVA PROGRAMMER EXAM
Non-disclosure form and would like to contribute to the growth
of this document by adding, correcting, or modifying this document,
you are free to do so.
To get the latest copy of this document please visit:
http://www.rajindery.com/javacert/jnotes.txt
If you have come across this document from another source,
please send me an email stating where you obtained your copy,
thank you.
You may send your comments, suggestions and corrections to:
Rajinder Yadav
email: rajindery@yahoo.com
+--------------------------------------------------------+
| Table of Content |
+--------------------------------------------------------+
1) How to use my notes
2) How to help out and give back
Part I
3) fundamentals
4) classes
5) exception handling
6) string immutability & garbage collection
Part II
7) AWT components
8) AWT events
9) AWT layout event listeners
Part III
10) java.lang
11) threading
12) Collections
13) java.oi
+--------------------------------------------------------+
| How to use my notes |
+--------------------------------------------------------+
I would suggest that you print out a copy of my notes and use them along with
other reading material. I have done my best to give each topic it's own section
so you can use my notes as a quick refresher.
Once you are able to read my notes in it's entirety, I would suggest that you
take a look at my java questions, they are designed to test you on what you
already know from my notes and your reading. My review question can be picked
up at:
http://www.rajindery.com/javacert/jtest.txt
I suggest that you save my review questions for the last week before taking
your exam, you can then use my answer sheet which also contains the questions,
together they will provide you a way to refresh your memory and keep you sharp!
I've taken my free time to make this available for you, now please take some
time to give back.... in the immortal words of Jerry Maguire,
"Help me help you!"
+--------------------------------------------------------+
| How to help out and give back |
+--------------------------------------------------------+
First please read the FDL agreement contained in this document.
If you found these notes to be helpful, please share them with others so they
may also benefit in their preparation for the SCJP2 Exam, better yet direct
them to this site so they can pick up the latest copy.
To give back, I would encourage you strongly to come up with a few 'tough'
questions of your own, and send them to me for inclusion in my review questions
document. Please do not send me copies of someone else's original work!
Other ways to help,
* help translate these documents and test questions to another languages
* proof read for typos, errors, clarification
* review information for technical accuracy
* help maintain all information current, advise on deprecated APIs, etc.
btw, when you make your first million, please don't forget about me :^D
+--------------------------------------------------------+
| fundamentals |
+--------------------------------------------------------+
With references to Java Language Specification (2nd ed)
http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html
foo.java --->(javac) --->foo.class ---> JVM
sourcecode java bytecode
* a valid source code filename contains the .java suffix
* the name of the source file must be the same name used by the public top-level class
* only one top-level class within a source file can be public
* a source file may contain many non public top-level classes
* a valid empty source file will compile without an error
* a valid java source file has three optional parts, in the following order
> single package declaration
> one or more import statement
> one or more class declaration
NOTE: one or more comment may appear before the package name
// file: MyClass.java
package com.mydomain.myutils;
import java.awt.*;
import java.util.*;
public class MyClass {...}
class MyHTTPClient {...}
* all the packages under java.lang are imported implicitly by javac
* all classes which reside in the same file belong to the same package and are
placed in the same directory
> classes with the 'default' access modifier are only visible within the
same package
* java primitives data-type and their wrapper classes
wrapper
data-type classes bits value range
--------- ------- ---- -----------
byte Byte 8 -2^7 to (2^7)-1
short Short 16 -2^15 to (2^15)-1
int Integer 32 -2^31 to (2^31)-1
long Long 64 -2^63 to (2^63)-1
float Float 32
double Double 64
char Character 16 '\u0000' to '\uffff'
boolean Boolean na false, true
* java 'implicit' up-casting rule is
byte -> short
\
+--> int -> long -> float -> double
/
char
* integer types: byte, short, int, long are signed values
* negative numbers in java are stored in two's compliment --> ~a = -a-1
* valid java comments
// this is a single line comment
/* this comment line can span many lines */
/** this is a javadoc comment line */
* all java keywords are in lowercase
* a valid java identifier has the following rules:
> can begin with $, an underscore '_' or a letter [a-z, A-Z]
> identifiers are not length limited
> cannot begin with a number
> must start with a valid unicode char
> cannot contain the special java control char like, ':', ';', '#', '%'
> cannot be a java keyword
ref:
http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625
* valid java keywords
ref:
http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#229308
abstract default if private this
boolean do implements protected throw
break double import public throws
byte else instanceof return transient
case extends int short try
catch final interface static void
char finally long strictfp volatile
class float native super while
(*)const for new switch
continue (*)goto package synchronized
NOTE: const and goto are reserved java keywords
NOTE: null, true, false are java literal values (not java keywords)
From the JLS
3.10.3 Boolean Literals: The boolean type has two values, represented by the
literals true and false, formed from ASCII letters.
3.10.7 The Null Literal: The null type has one value, the null reference,
represented by the literal null, which is formed from ASCII characters.
A null literal is always of the null type.
ref:
http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#229308
* java operators:
the bitwise shift operators '>>' is a signed right shift operator, the sign of
the value is not changed
the bitwise operator '>>>' is a unsigned right shift operator, it fills the
MSB(most significant bit) with a zero
int i = 1; i = i<<31; i = i>>31; ---> i == -1
int j = 1; j = j<<31; j = j>>>31; ---> j == 1
int x = -1; y = x>>1; // sign remain negative
z = x>>>1; // sing become positive, value is some large number
all arithmetic operations are promoted to at least an int value
byte b1 = 10;
byte b2 = 5;
byte sum = b1 + b2; // will not compile without casting!
dividing a value by zero, or taking a modulus '%' with a zero will cause a
"java.lang.ArithmeticException" exception to be thrown
* with the operators '>>' and '<<' if the r-value is greater then the bit depth
of the value, java will use the following rules to interpret the result
1<<35 == 1<<(35%32) == 1<<3 == 8 (since interger literals are 32-bit)
* short-circuit operators '&&' and '||' work with boolean values only
> operator '&&' will not need to evaluate the r-value if the l-value is false
> operator '||' will not need to evaluate the r-value if the l-value is true
> given that X can has either a true or false value
false && X is always false
true || X is always true
* dividing a floating point value by zero will not result is an exception
import java.util.*;
public class Test {
public static void main(String[] args) {
double f = 1.0/0;
double g = -1.0/0;
double h = Math.sqrt(-1.0);
System.out.println(f);
System.out.println(g);
System.out.println(h);
}
}
output displays special identifiers for floating point arithmetic errors
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
Infinity
-Infinity
NaN
* the comparison operator '==' works with java primitives values, and does a
superficial comparison of references with objects
* a literal value of '10' is interpreted as a integer
* a literal value of '10.2' is interpreted as a double
* all hexadecimal value begin with a 0x or 0X
* all octal values begin with a zero
int i = 10; // decimal value 10
int j = 0x0a; // hex value of 10
int k = 012; // octal value of 10
* valid char literal values must be in the range of 0 to (2^16)-1, or
'\u0000' to '\uffff'
// valid char literals
char a = 'a';
char b = 10;
char c = 0xaa;
char d = '\u0001';
NOTE: a char literal must appear inside a single quote, not a double quote
ref:
http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#48272
* valid ways to declare an array reference
int[] a;
int b[];
int b[][];
int []c[];
int[] a, b; // declares two array references
int a, b[]; // only b is an array reference
* you don't declare the array size inside the square brackets as in C\C++
int a[5]; // compile time error
* an array object has a length field (property) not a length() method
* valid ways to declare and initialize an array reference
int []j = {1,2,3};
int q[][] = {{1,1},{2,3,4},{5,5,5,5}};
int k[] = new int[]{1,2,3,4};
Object[] o = { new Object(), new Object(),new Object() };
* arrays values are always initialized to default values
* an array's size is determined using it's length field
public class Test {
public static void main(String[] args) {
boolean[] b = new boolean[5];
for(int i=0; i < b.length; ++i) {
System.out.println(b[i]);
}
}
}
output shows how to get the array's size and proves arrays are
initialized to a default value
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
false
false
false
false
false
ref:
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html#27805
+--------------------------------------------------------+
| classes |
+--------------------------------------------------------+
* top-level class declaration has the following format:
| class name { }
where: <...> indicates optional
| indicated an or binding
indicates an xor binding
NOTE: abstract and final cannot be used together
* by default a class in not visible outside of it's package
* no restriction on the ordering of public, abstract or final
* class field declaration has the following format:
|
||| type name;
* class method declaration has the following format:
|
||||
* class fields can be assigned a default value when they are declared
* the access modifiers are public, protected, private and "default" if not specified
* the volatile modifier is used to tell the JVM not to cache the value for
optimization purpose, but rather to use a single reference to access it's
"real-time" value
* the protected access modifier is less restrictive then the 'default' access
modifier since it also adds the provision for subclasses in other packages to
be able to access member fields and methods of thier parent class
* all classes implicitly derive from java.lang.Object
* to subclass use the 'extends' keyword
* java only allows single inheritance (only one class can be extended)
class A {}
class B extends A {}
* the 'super' keyword is used to reference superclass members
* super(); is used to call the superclass ctor
* a default constructor (ctor) will be included in the class if no other ctor
is defined within the class
* a ctor is required to allow a class object to be created
class A {
A(int n) {}
}
class B extends a {
}
B b = new B(); // will not compile!
the following error message is reported by javac 1.3.1 on linux
yadav@sandbox: javac Test.java
Test.java:15: cannot resolve symbol
symbol : constructor A ()
location: class A
class B extends A {
^
1 error
there are two ways to correct the code
i) declare a default no argument ctor within class A
class A {
A() {} // no argument ctor
A(int n) {}
}
ii) declare a default ctor within class B to make a call to a "defined" ctor in
the superclass A
class B extends a {
B() {
super(10); // make call to superclass ctor
}
}
* ctor's don't have a return value
* ctor's have the same name as the class
* it's valid to have a method with the same name as the class with a return
value
// example of a method name looking like a ctor
class A {
void A() {} // watch out this is not a ctor, has a return type of void
}
* a call to another ctor using the 'this' or 'super' operator must be the first
statement inside a ctor, otherwise a compiler error will result
01 public class Test {
02 public static void main(String[] args)
03 {
04 B b = new B();
05 }
06 }
07
08 class A {
09 A(int n) {}
10 }
11
12 class B extends A {
13 B() {
14 int i=10;
15 super(10);
16 }
17 }
javac 1.3.1 on linux report the following error message when this file is
compiled
yadav@sandbox: javac Test.java
Test.java:13: cannot resolve symbol
symbol : constructor A ()
location: class A
B() {
^
Test.java:15: call to super must be first statement in constructor
super(10);
^
2 errors
* all superclass are created before their subclasses
public class Test {
public static void main(String[] args)
{
C c = new C();
}
}
class A {
A() { System.out.println("Class A created"); }
}
class B extends A {
B() { System.out.println("Class B created"); }
}
class C extends B {
C() { System.out.println("Class C created"); }
}
output for this code is
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
Class A created
Class B created
Class C created
* a ctor with no access modifier has the same access privilege as the class
* class static members can be accessed without creating an object
public class Test {
public static void main(String[] args) {
StaticCls.who();
}
}
class StaticCls {
static String name = "me that's who!";
static void who() {
System.out.println(name);
}
}
output:
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
me that's who!
* all class member (instance) fields are initialized with their default values
type default value
---- -------------
byte (byte)0
short (short)0
int 0
long 0L
float 0.0F
double 0.0D
char '\u0000'
boolean false
* all instance fields are initialized when an object is created
* all static fields are initialized once when the class is loaded by the JVM
* static fields belong to the class, instance fields below to each object
* a look at static and instance initializers
public class Test {
public static void main(String[] args) {
StaticCls.who();
}
}
class StaticCls {
static String name;
StaticCls() {
System.out.println("inside the ctor");
}
static {
System.out.println("inside the static initializer");
name = init();
}
static String init() {
System.out.println("inside the static init() method");
return "me that''s who!!!";
}
static void who() {
System.out.println("inside the static method who()");
System.out.println(name);
}
}
when the following code is compiled and run, here is the output you get
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
inside the static initializer
inside the static init() method
inside the static method who()
me that''s who!!!
NOTE: 1) static initializer is executed when the class is loaded
2) static field is set using a method call to a static method
3) static methods are called using a reference to the class name
* non-static methods and fields cannot be accessed from inside a static method
public class Test {
String s = "Hello!";
public static void main(String[] args) {
System.out.println(s);
}
}
javac 1.3.1 on linux reports the following error message with a
static/non-static access
yadav@sandbox: javac Test.java
Test.java:4: non-static variable s cannot be referenced from a static context
System.out.println(s);
^
1 error
* an interface is declared using the 'interface' keyword
* a class can support one or more interface using the 'implements' keyword
* all interfaces are abstract by default
* all fields in an interface are 'public static final' by default
* all methods in an interface are 'public abstract' by default
* an interface can subclass one or more interface using the 'extends' keyword
* the following will not compile since class A implements MyInterface
but declares method myMethod1() as default which has a narrower access scope
then public
public class Test {
public static void main(String[] args) {
A a = new A();
}
}
interface MyInterface {
int j=10;
void myMethod1(); // this is public, not default
}
class A implements MyInterface {
void myMethod1() {} // declared as default
}
javac 1.3.1 on linux report the follow compiler error
yadav@sandbox: javac Test.java
Test.java:1: myMethod1() in Test cannot implement myMethod1() in MyInterface;
attempting to assign yadav@sandbox: javac Test.java
Test.java:12: myMethod1() in A cannot implement myMethod1() in MyInterface;
attempting to assign weaker access privileges; was public
class A implements MyInterface {
^
1 error
NOTE: to fix this declare myMethod1() as public within class A
class A implements MyInterface {
public void myMethod1() {}
}
* a class declared with a private ctor cannot be created
* ctor's are not inherited
* sub-classing is known as a 'is-a' relationship, key words to look for are
'extends' and 'implements'
* in the diagram below we can say the following about class Test
> class Test 'is-a' subclass of class Object
> class Test 'is-a' implementation of interface Runnable
+---------------+ +--------+
| <> | | Object |
| Runnable | +--------+
+---------------+ ^
^ |
| |
| |
| +------+ |
+-| Test |-----+
+------+
public class Test extends Object implements Runnable {
public void run() {}
public static void main(String[] args) {
Test t = new Test();
Object o = new Object();
System.out.println("t instanceof Object : " + (t instanceof Object));
System.out.println("t instanceof Runnable: "+ (t instanceof Runnable));
System.out.println("o instanceof Test : " + (o instanceof Test));
}
}
output shows t is-a subclass of Object and t is-a subclass Runnable, but o is
not a subclass of Test
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
t instanceof Object : true
t instanceof Runnable: true
o instanceof Test : false
* containment is known as a 'has-a' relationship
class A {}
class B {
A a; // class B contains a ref of type class A
}
* all classes directly or indirectly derive from class Object
* the following class members are inherited from class Object
protected Object clone() throws CloneNotSupportedException
public boolean equals(Object obj)
public int hashCode()
public String toString()
protected void finalize() throws Throwable
public final Class getClass()
public final void notify() throws IllegalMonitorStateException
public final void notifyAll() throws IllegalMonitorStateException
void wait() throws IllegalArgumentException,
IllegalMonitorStateException,
InterruptedException
void wait(long millisec) throws IllegalArgumentException,
IllegalMonitorStateException,
InterruptedException
void wait(long millisec, int nanosec) throws IllegalArgumentException,
IllegalMonitorStateException,
InterruptedException
* a cloneable class must implement the the Cloneable interface
* a shallow clone operation copies java primitives values and only makes a copy
of reference values
* a deep clone creates new objects from the references in the class being
copied
* inner class declaration has the following format:
|
|| class name {}
class Outer {
class Inner {}
}
// two step process for inner class creation
Outer o = new Outer();
Outer.Inner i = o.new Inner();
// one step creation of an inner class
Outer.Inner c = new Outer().new Inner();
* An inner class is a nested class that is not explicitly or implicitly declared static.
* Inner classes may not declare static initializers or member interfaces.
* Inner classes may not declare static members, unless they are compile-time constant fields
* Member interfaces are always implicitly static so they are never considered to be inner classes.
* an non-static inner class requires that the outer class exist before it can
be created
* an inner class has full access to 'all' fields of it's outer class
* a static inner class doesn't require an instance of the outer class for it's
creation
// how to create a static-inner class object
class Test {
public static void main(String[] args) {
A.B b = new A.B();
}
}
class A {
static class B {
B() { System.out.println("Hello from static inner class!"); }
}
}
output
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
Hello from static inner class!
* an abstract class may contain non-abstract methods
* a class with an abstract method must be declared as abstract
* method overloading requires the following conditions:
1) the method name is the same
2) the argument list is different
3) method is declared in the same class (class level scope)
* overloaded methods can have different return types
* overloaded methods have no restrictions on the exceptions they may throw
* overloaded methods can have any access modifier
* method overriding requires the following conditions:
1) the method name is the same
2) the return type is the same
3) the argument list is the same
4) the method is declared in the subclass
* overridden method have these restrictions:
1) may not throw any new 'checked' exception
2) may not throw a broader 'checked' exception than the superclass
3) may throw a narrower 'checked' exception than the superclass
4) the access modified can be less restrictive
class A {
void init() {}
}
class B extends A {
protected void init() {}
}
NOTE: protected is less restrictive then the default access modified
* restriction level of access modifiers (most restrictive to least):
private--->(default)-->protected--->public
Modifier Method Variable class
======== ====== ======== =====
public yes yes yes
private yes yes nested
protected yes yes nested
abstract yes no yes
final yes yes yes
transient no yes no
native yes no no
volatile no yes no
* static initialization code block is executed once when the class is loaded
* instance initialization code blocks are executed each time an object is created
public class test {
static public void main(String[] agr) {
System.out.println("Inside class static method: main()");
foo f1 = new foo();
foo f2 = new foo();
}
static {
System.out.println("Static initializer executed in class test");
}
}
class foo {
int i;
foo() {
System.out.println("Object getting created");
}
static {
System.out.println("Static initializer executed in class foo");
}
// instance initializer block
{
System.out.println("instance initializer executed when object foo is created");
i=10;
}
}
Output
C:\temp>java test
Static initializer executed in class test
Inside class static method: main()
Static initializer executed in class foo
instance initializer executed when object foo is created
Object getting created
instance initializer executed when object foo is created
Object getting created
+--------------------------------------------------------+
| exception handling |
+--------------------------------------------------------+
* java provides built in exception handing support (unlike C++)
* there are two type of exceptions, 1) checked exception and 2) unchecked
exceptions
* checked exception are checked by the compiler, a sourcefile will not compile
if the checked exception is not handled correctly
* unchecked exception are subclasses of 'RuntimeException' or 'Error'
* an exception causes the thread to stop executing and do a search for an
exceptional handler
* all uncaught exception are passed up the call stack until a handler is found,
otherwise the thread is terminated
* an exception can be caught in a try/catch block
* there are three causes of an exception
1) an abnormal condition occurred (i.e divide by zero)
2) a throw statement was executed
3) an internal error occurred in the JVM
* java provides a try/catch/finally block, where the either catch or finally
block is optional, but not both
* the finally block is always executed, even if there is a return statement
in the try / catch block
* a try block cannot appear alone
public class Test {
public static void main(String[] args) {
try {
int i=0;
System.out.println(i);
}
}
}
the following error is reported by javac 1.3.1 on Linux
yadav@sandbox: javac Test.java
Test.java:3: 'try' without 'catch' or 'finally'
try {
^
1 error
* the root class of exception is 'java.lang.Throwable'
java.lang.Throwable
|
+-Error {unchecked exception}
|
+-Exception {checked exception}
|
+-RuntimeException {unchecked exception}
|
+-ArithmeticException
+-IllegalMonitorStateException
+-IndexOutOfBoundsException
+-NullPointerException,
* if an exception is caught, execution continues after the handler block
try {
int i = 10/0;
}
catch(ArithmeticException e) {
}
finally {
// always executes!
}
* the order exception handlers are listed is important, all specific/narrower
exceptions must be listed before the general/broader exception, otherwise an
error will result
public class Test {
public static void main(String[] args) {
try {
int i=10/0;
}
catch(Exception e) { // general handler
}
catch(ArithmeticException e) { // specific handler
}
}
}
javac 1.3.1 on linux reports the following error message since a more general
exception handler is listed before a more specific handler
(see exception class hierarchy above)
yadav@sandbox: javac Test.java
Test.java:8: exception java.lang.ArithmeticException has already been caught
catch(ArithmeticException e) {
^
1 error
+--------------------------------------------------------+
| string immutability & garbage collection |
+--------------------------------------------------------+
* java String is immutable, what this means is that it cannot be modified
String s = "Hello";
s.concat(" World!");
System.out.println(s);
output will be "Hello" not "Hello World!"
* String.concat() creates a new string object on the heap while leaving the
original string un-altered
public class Test {
public static void main(String[] args) {
String s = "Hello";
String s1 = s.concat(" World!");
String s2 = s.concat(" World!");
System.out.println(s1 == s2);
}
}
when compiled and run the output indicated s1 and s2 are difference objects!
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
false
* all string literals are converted into java String object and placed in the
'java runtime constant string pool'
public class Test {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println("s1 == s2 :" + (s1 == s2));
System.out.println("s1 == s3 :" + (s1 == s3));
System.out.println("s3 == s4 :" + (s3 == s4));
System.out.println("s1.equals(s3) :" + s1.equals(s3));
System.out.println("s3.equals(s4) :" + s3.equals(s4));
}
}
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
s1 == s2 :true
s1 == s3 :false
s3 == s4 :false
s1.equals(s3) :true
s3.equals(s4) :true
+------------------+ +---------------+
| runtime constant | | heap |
| string pool | | |
| | |"Hello" "Hello"|
| "Hello" | | | | |
+-------|----------+ +---|-------|---+
| | |
+---+---+ | |
| | | |
(s1 == s2) != (s3 != s4) {references}
the output shows s1 and s2 reference the same object from the 'constant string
pool', but objects created on the heap will be unique objects, and thus s3 and
s4 will reference different objects
* the String.equals() method overrides class Object.equals() to compare each
character, the default base class implementation does a superficial
comparison of object references
boolean equals(Object obj) {
return this == obj;
}
* the StringBuffer class does not override the Object.equals() method
public class Test {
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("Hello");
System.out.println("s1.equals(s2) :" + s1.equals(s2));
}
}
output:
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
s1.equals(s2) :false
* only objects created on the heap can be garbage collected
* garbage collection (gc) 'cannot be forced'
* garbage collection may or may not occur
* calling System.gc() will not force gc to occur
* an object becomes 'eligible' for gc when all reference to it are removed
String s1 = new String("xxx");
String s2;
s2 = s1;
s1 = null; // not yet eligible for gc, s2 still has a
// reference to String "xxx" created on the help
s2 = null; // String "xxx" is now eligible for gc
* an object's finalize() method is only called when the object is 'actually'
garbage collected
* an object's finalize() method will be called at most one time, it is possible
to save a reference inside the finalize() method, doing this will prevent the
object from being GCed, so the next time the object is GCed the finalize()
method will not be called
NOTE: don't ever use the finalize() method since there is no guarantee if an
object will be GCed or when that will happen
* there is no guarantee that a java application will not run out of memory
+--------------------------------------------------------+
| AWT components |
+--------------------------------------------------------+
* class Component is the base class for all visible GUI widgets
* the Component class provides general methods for things like:
> setting the background colour
> setting the foreground colour
> setting the font
> to specify size and min/max constraints
> setting visibility
> to enable/disable the component
* all components have a graphic's context that can be obtained with
Component.getGraphics();
* with the graphic's context you can
> set the clip region
> get/set current colour attributes
> get/set the font
> get/set drawing mode (i.e XOR is one drawing mode)
> render graphics primitives like line, circle,...
> render text
* Applets have 4 'lifetime' methods you can override
init() // called once
start() // called each time applet is started
stop() // called each time applet is stopped
destroy() // called when applet is unloaded
* the basic GUI components are derive from the Component class
Component
|
+-Button
+-TextComponent
| |
| +-TextField
| +-TextArea
|
+-Label
+-Canvas
+-Checkbox
+-List
+-Choice
+-ScrollBar
+-ScrollPane
* GUI components are added to containers with Container.add()
* class Container is a subclass of Component
* Containers may contain other containers
Component
|
+-Container {abstract}
|
+-Panel
| |
| +-Applet
|
+-Window
|
+-Frame
+-Dialog
|
+FileDialog
* Menus et. al belong to the MenuComponent class
MenuComponent
|
+-MenuBar
+-MenuItem
|
+-CheckboxMenuItem
+-Menu
|
+-PopupMenu
* menu components cannot be added to a container
* a menu component is added to the Frame window using Frame.setMenuBar()
* CheckboxGroup is not a container, it is a logical group
* Panel, Applet and Window have no title bars, menu bar or close/min/max boxes
* Applet container designed to appear within a web-browser
* a Frame compoment has a title bar, menu bar, close/min/max boxes
* the following code shows how to create a Frame application with a menubar
import java.awt.*;
public class Test {
public static void main(String[] args) {
Frame f = new Frame("Test");
MenuBar bar = new MenuBar();
Menu menu = new Menu("File");
menu.add(new MenuItem("Open..."));
menu.add(new MenuItem("Close"));
bar.add(menu);
f.setMenuBar(bar);
f.setSize(400,200);
f.setVisible(true);
}
}
* to draw inside a component override the paint method()
public void paint(Graphics g);
* to perform tasks before a paint operation, override the update() method
public void update(Graphics g);
* call Component.repaint() to cause an update to occur, which in turn calls the
paint method
* the Button component is a simple push button
Button b1 = new Button();
Button b2 = new Button("Click");
* the TextField component is a single line input field
TextField t1 = new TextField();
TextField t2 = new TextField(30); // 30 char field limit
TextField t3 = new TextField("Default Text"); // default text in field
TextField t4 = new TextField("Text", 30);
* the TextArea component is a multi-line input field, vertical and horizontal
scrollbars can be added
> defined constants are:
TextArea.SCROLLBARS_VERTICAL_ONLY
TextArea.SCROLLBARS_HORIZONTAL_ONLY
TextArea.SCROLLBARS_BOTH
TextArea t1 = new TextArea();
TextArea t2 = new TextArea(row, col);
TextArea t3 = new TextArea("default text");
TextArea t4 = new TextArea("text", row, col);
TextArea t5 = new TextArea("text", row, col, TextArea.SCROLLBARS_BOTH);
* the Label component is a read-only text field
Label l1 = new Label();
Label l2 = new Label("Name:");
* the Canvas component provides a surface to draw on as well as track mouse
clicks and movements
Canvas c = new Canvas();
* the Checkbox component can be used for single boolean selection:
Checkbox c1 = new Checkbox("label", true, null);
* the Checkbox component can be used in a group to provide exclusive boolean
selection options:
CheckboxGroup sex = new CheckboxGroup();
Checkbox c1 = new Checkbox("male", true, sex);
Checkbox c2 = new Checkbox("female", false, sex);
* the List component show a list of items that can be selected
> multiple selection can be enabled
> the number of visible items is set via the ctor
> a scrollbar is provide if there are many items
List l = new (5); // make 5 items visible
List m = new (3, true); // allow multiple selections
l.add("one");
l.add("two");
* the Choice component provides a single drop-down list where the selected item
is visible by default
Choice c = new Choice();
c.add("Toronto");
c.add("New Delhi");
c.add("Seoul");
* the ScrollBar component provides both vertical and horizontal
oriented range selection
> defined constants are: ScrollBar.HORIZONTAL and ScrollBar.VERTICAL
ScrollBar sb = new ScrollBar(ScrollBar.HORIZONTAL,
position,
slider_size,
min_val,
max_val)
* the ScrollPane provides a scrollable surface and handles the
scrolling for you
> can be used as a container for other components
> defined constants are:
ScrollPane.SCROLLBARS_ALWAYS
ScrollPane.SCROLLBARS_NEVER
ScrollPane.SCROLLBARS_AS_NEEDED
ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
* the layout manager for components are:
FlowLayout
GridLayout
BorderLayout
GridBagLayout
CardLayout
* the default layout manager for Panel derived classes is FlowLayout
* the default layout manager for Window derived classes is BorderLayout
* the FlowLayout manager tries to maintain the component's preferred size
* FlowLayout adds components left to right and top to bottom
* GridLayout manager honors the row setting and adds new columns when more
components are added beyond the initial size
* BorderLayout manager has five regions a component can be placed in,
they are:
BorderLayout.CENTER
BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.WEST
BorderLayout.EAST
+-----------------+
| N | <-- N/S regions runs the entire width
+-----------------+
| | | |
| W | C | E |
| | | |
+-----------------+
| S |
+-----------------+
* components added to BorderLayout without specifying a region are placed in
the center, one on top of the other, the component also ends up taking the
entire area
* the layout manager can be changed with Container.setLayout()
+--------------------------------------------------------+
| AWT events |
+--------------------------------------------------------+
* AWTEvent objects contains information about the source of the event
* java.util.EventObject is the super class of all event objects
java.util.EventObject
|
+-AWTEvent
|
+-ActionEvent
+-AdjustmentEvent
+-InputMethodEvent
+-ItemEvent
+-TextEvent
+-ComponentEvent
|
+-ContainerEvent
+-InputEvent
| |
| +-KeyEvent
| +-MouseEvent
|
+-FocusEvent
+-PaintEvent
+-WindowEvent
Event Type Mask
---------- -----
ActionEvent ACTION_EVENT_MASK
AdjustmentEvent ADJUSTMENT_EVENT_MASK
InputMethodEvent INPUT_METHOD_EVENT_MASK
ItemEvent ITEM_EVENT_MASK
TextEvent TEXT_EVENT_MASK
ContainerEvent CONTAINER_EVENT_MASK
KeyEvent KEY_EVENT_MASK
MouseEvent MOUSE_EVENT_MASK
FocusEvent FOCUS_EVENT_MASK
PaintEvent PAINT_EVENT_MASK
WindowEvent WINDOW_EVENT_MASK
* events are enabled with Component.enableEvents(eventmask)
* to process the event, the appropriate event handler methods
need to be overridden
> the method signature will the form:
public void ProcessXEvent(XEvent e)
where X is one of the event types listed above
// example for processing events using event handlers
// class MyButton enables ActionEvent and provides
// the overridden event handler for it
import java.awt.*;
import java.awt.event.*;
class MyButton extends Button {
MyButton(String s) {
super(s);
enableEvents(AWTEvent.ACTION_EVENT_MASK);
}
public void processActionEvent(ActionEvent e) {
System.exit(0);
}
}
public class Test {
public static void main(String[] args) {
Frame f = new Frame("Event Enabled App");
MyButton b = new MyButton("Close");
f.add(b);
f.setSize(300,300);
f.setVisible(true);
}
}
* ActionEvent is generated by the following components
Button - button is clicked
List - item is double clicked
MenuItem - menu item is selected
TextField - return key is hit
* ItemEvent is generated by the following components
CheckBox - state of check is changed
CheckBoxMenuItem - state changed
Choice - selection is changed
List - item selection changed
* AdjustmentEvent is generated by the following components
ScrollBar - when position is changed
* TextEvent is generated by the following components
TextArea - when text is updated
TextField - when text is updated
* FocusEvent is generated by the following components
Component - gains/looses focus
* KeyEvent is generated when
key is pressed and release
* MouseEvent is generate when
mouse button is pressed and released
mouse pointer is moved
* WindowEvent is generate when
Window - open/close, activate/deactivate window
* PaintEvent is generate when
Component - on repaint notification
* ComponentEvent is generated by the following components
Component - when it's hidden,shown,moved,resized
* ContainerEvent is generated by the following components
Container - when components are added/removed
+--------------------------------------------------------+
| AWT layout event listeners |
+--------------------------------------------------------+
* java has a second way of handling events using event listeners
* event listeners allow event notification to be delegate to other objects
* event listeners are classes that implement one more listener interface
* java.util.EventListener is the superclass for the listener interfaces
java.util.EventListener
|
+-ActionListener
+-AdjustmentListener
+-ComponentListener
+-ContainerListener
+-FocusListener
+-InputMethodListener
+-ItemListener
+-KeyListener
+-MouseListener
+-MouseMotionListener
+-TextListener
+-WindowListener
* interface ActionListener {
public void actionPerformed(ActionEvent e);
}
* interface AdjustmentListener {
public void adjustmentValueChanged(AdjustmenEvent e);
}
* interface ComponetListener {
public void componentHidden(ComponentEvent e);
public void componentMoved(ComponentEvent e);
public void componentResized(ComponentEvent e);
public void componentShown(ComponentEvent e);
}
* interface ContainerListener {
public void componenAdded(ContainerEvent e);
public void componenRemoved(ContainerEvent e);
}
* interface FocusListener {
public void focusGained(FocusEvent e);
public void focusLost(FocusEvent e);
}
* interface InputMethodListener {
public void caretPositionChanged(InputMethodEvent e);
public void inputMethodTextChanged(InputMethodEvent e);
}
* interface ItemListener {
public void itemStateChanged(ItemEvent e);
}
* interface MouseListener {
public void mouseClicked(MouseEvent e);
public void mouseEntered(MouseEvent e);
public void mouseExited(MouseEvent e);
public void mousePressed(MouseEvent e);
public void mouseReleased(MouseEvent e);
}
* interface MouseMotionListener {
public void mouseDragged(MouseMotionEvent e);
public void mouseMoved(MouseMotionEvent e);
}
* interface TextListener {
public void textValueChanged(TextEvent e);
}
* interface WindowListener {
public void windowActivated(WindowEvent e);
public void windowClosed(WindowEvent e);
public void windowClosing(WindowEvent e);
public void windowDeactivated(WindowEvent e);
public void windowDeiconified(WindowEvent e);
public void windowIconified(WindowEvent e);
public void windowOpened(WindowEvent e);
}
* steps required to add a listener interface
1) create component object
2) create listener object
3) add listener object to component
* a listener is added to the component with addXListners();
where X is one of the event listener above
// example of event delegation using an event listener
// a event listener is added to the button object
import java.awt.*;
import java.awt.event.*;
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public class Test {
public static void main(String[] args) {
Frame f = new Frame("Event Listener");
Button b = new Button("Close");
MyActionListener h = new MyActionListener();
b.addActionListener(h);
f.add(b, BorderLayout.SOUTH);
f.setSize(300,400);
f.setVisible(true);
}
}
+--------------------------------------------------------+
| java.lang |
+--------------------------------------------------------+
* from JDK 1.3.1 - Provides classes that are fundamental to the design of the
Java programming language.
* the java.lang package is imported implicitly by javac
* the java.lang.Math package contains many useful function
* the Math class define two constants: Math.E and Math.PI
* the Math class define the following public static methods:
* the abs() function
double abs(double n);
float abs(float n);
int abs(int n);
long abs(long n);
From JDK 1.3.1
If the argument is negative, the negation of the argument is returned.
Special cases:
> If the argument is positive zero or negative zero,
the result is positive zero.
> If the argument is infinite, the result is positive infinity.
> If the argument is NaN, the result is NaN.
* the round() function
long round(double n);
int round(float n);
From JDK 1.3.1
Returns the closest long to the argument. The result is rounded to an
integer by adding 1/2, taking the floor of the result, and casting the
result to type long. In other words, the result is equal to the value of
the expression:
Special cases:
> If the argument is NaN, the result is 0.
> If the argument is negative infinity or any value less than or equal to
the value of Long.MIN_VALUE, the result is equal to the value of
Long.MIN_VALUE.
> If the argument is positive infinity or any value greater than or equal
to the value of Long.MAX_VALUE, the result is equal to the value of
Long.MAX_VALUE
* double floor(double n);
From JDK 1.3.1
Returns the largest (closest to positive infinity) double value that is not
greater than the argument and is equal to a mathematical integer.
Special cases:
> If the argument value is already equal to a mathematical integer,
then the result is the same as the argument.
> If the argument is NaN or an infinity or positive zero or negative
zero, then the result is the same as the argument.
* double ceil(double a)
From JDK 1.3.1
Returns the smallest (closest to negative infinity) double value that is
not less than the argument and is equal to a mathematical integer.
Special cases:
> If the argument value is already equal to a mathematical integer,
then the result is the same as the argument.
> If the argument is NaN or an infinity or positive zero or negative
zero, then the result is the same as the argument.
> If the argument value is less than zero but greater than -1.0, then
the result is negative zero.
Note that the value of Math.ceil(x) is exactly the value of -Math.floor(-x).
* double sqrt(double a)
From JDK 1.3.1
Returns the correctly rounded positive square root of a double value.
Special cases:
> If the argument is NaN or less than zero, then the result is NaN.
> If the argument is positive infinity, then the result is
positive infinity.
> If the argument is positive zero or negative zero, then the result
is the same as the argument.
Otherwise, the result is the double value closest to the true mathematical
square root of the argument value.
* the max functions
int max(int a, int b);
long max(long a, long b);
float max(float a, float b);
double max(double a, double b);
From JDK 1.3.1
If either value is NaN, then the result is NaN. Unlike the the numerical
comparison operators, this method considers negative zero to be strictly
smaller than positive zero. If one argument is positive zero and the other
negative zero, the result is positive zero
* the min functions
int min(int a, int b);
long min(long a, long b);
float min(float a, float b);
double min(double a, double b);
From JDK 1.3.1
If either value is NaN, then the result is NaN. Unlike the the numerical
comparison operators, this method considers negative zero to be strictly
smaller than positive zero. If one argument is positive zero and the other
is negative zero, the result is negative zero.
* double random()
From JDK 1.3.1
Returns a double value with a positive sign, greater than or equal to 0.0
and less than 1.0. Returned values are chosen pseudorandomly with
(approximately) uniform distribution from that range.
This method is properly synchronized to allow correct use by
more than one thread.
* java.lang.System provides three useful stream classes
> System.err - standard error output stream (usually console)
> System.in - standard input stream (usually keyboard)
> System.out - standard output stream (usually console)
* to get system properties use System.getProperties();
* to end the process call System.exit(int status);
* to run the garbage collector use System.gc();
public class Test {
public static void main(String[] args) {
System.out.println("abs(-0.0) " + Math.abs(-0.0));
System.out.println("abs(NaN) " + Math.abs(Double.NaN));
System.out.println("floor(-0.0) " + Math.floor(-0.0));
System.out.println("floor(-1.2) " + Math.floor(-1.2));
System.out.println("ceil(-0.0) " + Math.ceil(-0.0));
System.out.println("ceil(-1.2) " + Math.ceil(-1.2));
System.out.println("round(-1.3) " + Math.round(-1.3));
System.out.println("round(1.5) " + Math.round(1.5));
System.out.println("round(NaN) " + Math.round(Double.NaN));
}
}
output
yadav@sandbox: javac Test.java
yadav@sandbox: java Test
abs(-0.0) 0.0
abs(NaN) NaN
floor(-0.0) -0.0
floor(-1.2) -2.0
ceil(-0.0) -0.0
ceil(-1.2) -1.0
round(-1.3) -1
round(1.5) 2
round(NaN) 0
NOTE: NaN cannot be represented as a integer so a zero is return
from the round function
-3 -2 -1 0 1 2 3
+---+---+---+---+---+---+
ceil---> <---floor
+--------------------------------------------------------+
| threading |
+--------------------------------------------------------+
* a thread is an independent path of execution within a given process
* a process may have many threads working independently
* all threads in a process share process global data
* each thread will have it's own call stack and copy of local variables
* there are two ways to make a class multi-threaded:
1) subclass the java.lang.Thread class
2) implement the java.lang.Runnable interface
* a thread may be in one of the following state:
> newly created
> ready to run
> running
> waiting
> blocked
> sleeping
> dead
+-------+ +---------+
|created|-->(start)-->| ready |<-----<-----<-----+<--------+
+-------+ +---------+ | |
(thread) | ^ | |
v | ^ |
+---------+ | ^
|scheduler| | |
+---------+ ^ |
CPU time| ^ CPU time | |
granted | | spent +--------+ ^
| | +-->|sleeping| |
v | | +--------+ |
+----+ +-------+ | |
|dead|<----(exit)---|running|-->(sleep)-+ +-->(notify)-->+
+----+ thread +-------+ | |
finishes ||| +-------+ |
||+-->(wait)->|waiting| |
|| +-------+ |
+-------+ |+--->(yield)--->----->---->------+
| |<--(operation call)-+ ^
|blocked| |
| |-->(call returns)----->-------->-------->-------------+
+-------+
NOTE: with a blocked thread, if control returns to the thread before the
CPU time is used up the thread will return to the running state,
otherwise the scheduler will have swapped it out meaning the thread
will be put into the ready state when control return from the blocked
call (the blocked call may be running in a separate thread or process)
* a thread is started by calling the Thread.start() method
* a threaded class must override method, public void run();
* a process dies when the last non-daemon thread exists or terminates
// threading support by sub-classing Thread
public class Test {
public static void main(String[] args) {
MyThread t1 = new MyThread("One");
MyThread t2 = new MyThread("Two");
t1.start();
t2.start();
}
}
class MyThread extends Thread {
String m_msg;
MyThread(String s) {
m_msg = s;
}
public void run() {
while(true) {
System.out.print(m_msg);
}
}
}
// threading support using interface Runnable
public class Test {
public static void main(String[] args) {
MyRunner r1 = new MyRunner("One");
MyRunner r2 = new MyRunner("One");
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
class MyRunner implements Runnable {
String m_msg;
MyRunner(String s) {
m_msg = s;
}
public void run() {
while(true) {
System.out.print(m_msg);
}
}
}
* if your class needs to extend another class, then using the Runnable
interface is your only choice for thread support
* the synchronized keyword is used to sync access to shared resources and
gain the object's monitor lock
* a synchronized object can only be accessed by a single thread at a time
* the synchronized keyword can be added to a method
> synchronized void foo() {...}
* the synchronized keyword can be used within a block
> synchronized(this) {...}
* method wait(), notify() and notifyAll() must be called on an object that
we have a monitor lock
* the following example shows how to sync the output of two threads
// two threads are created, one prints "Ping" and the other prints "Pong"
// shows how to get the two threads to co-operate to print "PingPong"
// both threads are synchronized on the PingPongTest object 't'
//
class PingPongTest
{
public static void main(String[] argv) {
PingPongTest t = new PingPongTest();
t.play();
}
public void play() {
Thread m_ping = new Thread(new Ping(this));
Thread m_pong = new Thread(new Pong(this));
m_ping.start();
m_pong.start();
}
}
// class Ping
class Ping implements Runnable
{
PingPongTest m_ppt;
Ping(PingPongTest ref) {
m_ppt = ref;
}
public void run() {
synchronized(m_ppt) {
for(int i=0; i<100; ++i) {
try {
System.out.print("Ping");
m_ppt.notify();
m_ppt.wait();
}
catch(InterruptedException e) {
}
} // for()
m_ppt.notify();
} // sync
}
}
// class Pong
class Pong implements Runnable
{
PingPongTest m_ppt;
Pong(PingPongTest ref) {
m_ppt = ref;
}
public void run() {
synchronized(m_ppt) {
for(int i=0; i<100; ++i) {
try {
System.out.println("Pong");
m_ppt.notify();
m_ppt.wait();
}
catch(InterruptedException e) {
}
} // for()
m_ppt.notify();
} //sync
}
}
output:
yadav@sandbox: javac PingPongTest.java
yadav@sandbox: java PingPongTest
PingPong
PingPong
PingPong
PingPong
...
* non-atomic treatment of long and double
From JLS 2ed (17.4 Nonatomic Treatment of double and long)
>If a double or long variable is not declared volatile, then for the
purposes of load, store, read, and write actions they are treated as if
they were two variables of 32 bits each: wherever the rules require one of
these actions, two such actions are performed, one for each 32-bit half.
* the volatile keyword assure that the master value of a variable is processed
on and not a local cached value
+--------------------------------------------------------+
| Collections |
+--------------------------------------------------------+
* a Collection can be viewed as a container for object grouping
* a Collection work by grouping objects such that they can be operated on
independent of their data structure
* a Collection has the following intefaces
<< interface >>
Collection
|
+-List
+-Set
|
+-SortedSet
<< interface >>
Map
|
+-SortedMap
* the Set collection is used for storing 'unique' elements within the group
* the List collection stores elements is a sequentian order allowing
dupilcated of elements
* the SortSet collection is an ordered Set
* a Map collection associates 'key' references with a data 'value'
* there is a 1-to-1 mapping of key to value, this implies that key's must
be unique, but values can be non-unique
* the java.util.*; package provided the following concrete classes
collection
data structure class interface
-------------- ----- ----------
Dynamic Array ArrayList List
Dynamic Array Vector List
Balanced Tree TreeSet SortedSet
Balanced Tree TreeMap SortedMap
Linked List LinkedList List
<< class >> ---> << interface >>
java.util.AbstractCollection ---> Collection
|
+-java.util.AbstractSet ---> Set
| |
| +-java.util.HashSet ---> Set
| |
| +-java.util.TreeSet ---> Set
|
+-java.util.AbstractList
|
+-java.util.AbstractSequentialList ---> List
| |
| +-java.util.LinkedList ---> List
|
+-java.util.Vector
|
+-java.util.ArrayList --> List
java.util.AbstractMap
|
+-java.util.HashMap ---> Map
+-java.util.TreeMap ---> SortedMap
+-java.util.WeakHashMap
+--------------------------------------------------------+
| java.oi |
+--------------------------------------------------------+