Sunday, March 20, 2011

SCJP2 study notes


Language Fundamentals Certification Objectives
  • Identify correctly constructed source files, package declarations, import statements, class declarations (of all forms including inner classes), interface declarations and implementations (for java.lang.Runnable or other interfaces described in the test), method declarations (including the main method that is used to start execution of a class), variable declarations and identifiers.
  • State the correspondence between index values in the argument array passed to a main method and command line arguments. Identify all Java programming language keywords and correctly constructed identifiers.
  • State the effect of using a variable or array element of any kind when no explicit assignment has been made to it.
  • State the range of all primitive data types and declare literal values for String and all primitive types using all permitted formats, bases, and representations.
1.4 Exam Objectives
The objectives are basically the same; the first objective in 1.2 has been restated as:
  • Identify correctly constructed package declarations, import statments, class declarations (of all forms including inner classes) interface declarations, method declarations (including the main method that is used to start execution of a class), variable declarations and identifiers.
  • Identify classes that correctly implement an interface where that interface is either java.lang.Runnable or a fully specifiec interface in the question.
The second 1.2 objective has been split with an additional note on 'keywords'
  • State the correspondence between index values in the argument array passed to a main method and command line arguments.
  • Identify all Java programming language keywords. Note: There will not be any questions regarding esoteric distinction between keywords and manifest constants.
Operators and Assignments Certification Objectives
( 1.4 Objectives are identical )
  • Determine the result of applying any operator, including assignment operators and instanceof, to operands of any type, class, scope, or accessibility, or any combination of these.
  • Determine the result of applying the boolean equals(Object) method to objects of any combination of the classes java.lang.String, java.lang.Boolean, and java.lang.Object.
  • In an expression involving the operators &, |, &&, ||, and variables of known values state which operands are evaluated and the value of the expression.
  • Determine the effect upon objects and primitive values of passing variables into methods and performing assignments or other modifying operations in that method.
Flow Control and Exception Handling Certification Objectives
  • Write code using if and switch statements and identify legal argument types for these statements.
  • Write code using all forms of loops including labeled and unlabeled use of break and continue, and state the values taken by loop control variables during and after loop execution.
  • Write code that makes proper use of exceptions and exception handling clauses (try, catch, finally) and declares methods and overriding methods that throw exceptions.
1.4 Exam: Additional objectives
  • Recognize the effect of an exception arising at a sepcified point in a code fragment. Note: The exception may be a runtime exception, a checked exception, or an error (the code may include try, catch, or finally clauses in any legitimate combination).
  • Write code that makes proper use of assertions, and distinguish appropriate from inapporopriate uses of assertions.
  • Identify correct statements about the assertion mechanism.
For additional study materials try:
    Sun: Programming with Assertions
    Developerworks: Working with Assertions
    JavaWorld: Understand the mechanics of ... new assertion facility
Declarations and Access Control Certification Objectives
( 1.4 objectives are identical )
  • Write code that declares, constructs, and initializes arrays of any base type using any of the permitted forms both for declaration and initialization.
    (Covered under Language Fundamentals - Array Initialization)
  • Declare classes, inner classes, methods, instance variables, static variables, and automatic (method local) variables making appropriate use of all permitted modifiers (such as public, final, static, abstract, and so forth). State the significance of each of these modifiers both singly and in combination, and state the effect of package relationships on declared items qualified by these modifiers.
  • For a given class, determine if a default constructor will be created, and if so, state the prototype of that constructor.
    (Covered under Language Fundamentals - Constructors)
  • State the legal return types for any method given the declarations of all related methods in this or parent class.
    (Covered under Language Fundamentals - Method Declarations)
Garbage Collection Certification Objectives
  • State the behaviour that is guaranteed by the garbage collection system, and write code that explicitly makes objects eligible for collection.
1.4 Exam
The above objective has been expanded as:
  • State the behavior that is guaranteed by the garbage collection system.
  • Write code that explicitly makes objects eligible for garbage collection.
  • Recognize the point in a piece of source code at which an object becomes eligible for garbage collection.
Overloading, Overriding, Runtime Types and Object Orientation Certification Objectives
( 1.4 Objectives are identical )
  • State the benefit of encapsulation in object oriented design and write code that implements tightly encapsulated classes and the relationships "is a" and "has a".
  • Write code to invoke overridden or overloaded methods and parental or overloaded constructors; and describe the effect of invoking these methods.
  • Write code to construct instances of any concrete class including normal top level classes, inner classes, static inner classes, and anonymous inner classes.
Threads Certification Objectives
  • Write code to define, instantiate, and start new threads using both java.lang.Thread and java.lang.Runnable.
  • Recognize conditions that might prevent a thread from executing.
  • Write code using synchronized, wait, notify, or notifyAll, to protect against concurrent access problems and to communicate between threads. Define the interaction between threads and between threads and object locks when executing synchronized, wait, notify, or notifyAll
1.4 Exam
The third 1.2 objective has been re-worded as:
  • Write code using synchronized wait, notify and notifyAll to protect against concurrent access problems and to communicate between threads.
  • Define the interaction among threads and object locks when executing synchronized wait, notify or notifyAll
The java.lang Package Certification Objectives
  • Write code using the following methods of the java.lang.Math class: abs, ceil, floor, max, min, random, round, sin, cos, tan, sqrt.
  • Describe the significance of the immutability of String objects.
1.4 Exam : Additional objectives
  • Describe the significance of wrapper classes, including making appropriate selections in the wrapper classes to suit specified behavior requirements, stating the result of excecuting a fragment of code that includes an instance of one of the wrapper classes, and writing code using the following methods of the wrappers classees 9e.g, Integer, Double, etc):
    • doubleValue
    • floatValue
    • intValue
    • longValue
    • parseXxx
    • getXxx
    • toString
    • toHexString

The java.util Package Certification Objectives

  • Make appropriate selection of collection classes/interfaces to suit specified behavior requirements.

1.4 Exam

This objective has been renamed The Collection Framework and the following has been added:
  • Distinguish between correct and incorrect implementations of hashcode methods.

Also see

The java.awt Package Certification Objectives
NOT REQUIRED FOR 1.4 EXAM
  • Write code using component, container, and LayoutManager classes of the java.awt package to present a GUI with a specified appearance and resize behaviour, and distinguish the responsibilities of layout managers from those of containers.
  • Write code to implement listener classes and methods, and in listener methods, extract information from the event to determine the affected component, mouse position, nature and time of the event. State the classname for any specified event listener interface in the java.awt.event package.
Pay Attention to which Layout Managers implement LayoutManager2
  • one thing I discovered (after I wrote the exam!) that is of prime importance in the way containers handle components when they are resized is knowing which Layout Interface the active LayoutManager implements. Any Layout Manager that extends the LayoutManager2 Interface keeps track of their own components.
  • What this means in practice is that if the layout manager is set after components have been added to the container and the layout manager implements the LayoutManager2 interface, no components will be visible.
  • LayoutManager2 type managers do not query the container for a list of components, they maintain their own list.
  • FlowLayout and GridLayout, both implement LayoutManager. When the container is resized they will query the container for a list of the components and then layout them out according to their contract.
  • CardLayout, BorderLayout, GridBagLayout, BoxLayout, and OverlayLayout implement the LayoutManager2 interface. If the container is resized they rely on their own, internal list of components. Components added to a container before the LayoutManager was added will not be known and hence not included in the layout when the container is resized.
The java.io Package Certification Objectives
NOT REQUIRED FOR 1.4 EXAM
  • Write code that uses objects of the file class to navigate a file system.
  • Write code that uses objects of the classes InputStreamReader and OutputStreamWriter to translate between Unicode and either platform default or ISO 8859-1 character encoding and distinguish between conditions under which platform default encoding conversion should be used and conditions under which a specific conversion should be used.
  • Select valid constructor arguments for FilterInputStream and FilterOutputStream subclasses from a list of classes in the java.io package.
  • Write appropriate code to read, write, and update files using FileInputStream, FileOutputStream and RandomAccessFile objects.
  • Describe the permanent effects of the file system of constructing and using FileInputStream, FileOutputStream, and RandomAccessFile objects.

Tip
  • focus on the classes mentioned in the objectives and their constructors

Sun Sites

Books

On-line

Hardcover

  • (JPL) The Java Programming Language Second Edition by Ken Arnold and James Gosling, The Java Series, Addison Wesley, 1998
  • (CPJ) Concurrent Programming in Java Second Edition: Design Principles and Patterns by Doug Lea, The Java Series, Addison Wesley, 2000
  • (JCL1) The Java Class Libraries Second Edition, Volume 1 by Patrick Chan and Rosanna Lee, The Java Series, Addison Wesley, 1998
  • (JCL2) The Java Class Libraries Second Edition, Volume 2 by Patrick Chan and Rosanna Lee, The Java Series, Addison Wesley, 1998
  • (JCLS) The Java Class Libraries Second Edition, Volume 1: Supplemental for the Java 2 Platform, Standard Edition, v1.2 by Patrick Chan, Rosanna Lee, and Douglas Kramer, The Java Series, Addison Wesley, 1999
  • (GJ) Graphic Java: Mastering the AWT by David M. Geary and Alan L. McClellan, SunSoft Press, 1997
  • (JJ) Java 2 Certification by Jamie Jaworski, New Riders, 1999
  • (BB) Java Certification Exam Guide for Programmers and Developers by Barry Boone, McGraw Hill, 1997
  • (VA) Programming with VisualAge for Java by Marc Carrel-Billiard and John Akerley, Prentice-Hall, 1998
Extracting Source code for the Java API classes
To extract source code for the Java Class files, check your JDK directory for a src.jar file. In the same directory, enter
    jar tf src.jar > srcList.txt
This will create a text file listing all the .java files in the src.jar file.
View the text file to locate the path name of the class you're interested in and then type:
    jar xf src.jar file pathname
   
    For example, to extract the Reader.java file
        jar xf src.jar src/java/io/Reader.java
Compiling with JDK 1.3 under Win98
If you're having problems compiling check the following:
  1. you do NOT have CLASSPATH set in your AUTOEXEC.BAT file (JDK 1.3 does not require the DOS environment variable).
    If the variable is set because of other programs, make sure it begins with a '.\' to ensure the current directory is always included.
  2. you are issuing the compile command from within the directory containing the .java source file
  3. if you are using the javac switch -classpath DO NOT include an ending '\'
JRE can't locate .jar files under Win98
If you've downloaded some .jar files and installed them, as instructed, to the jdk1.3\jre\lib\ext directory but you're still getting ClassDefNotFound errors when you try to run an application that references the jars; check your system for a Java JRE Plug-in. If one exists, copy the .jar files to that ...\jre\lib\ext directory and re-boot.

The Runtime should now be able to find the .jar files properly.
Tips
  • an empty source file will compile without error
  • if a .java file does not contain a public class or interface it can have any name
  • a single-type import will take precedence over an import-on-demand
  • import-on-demand types do not increase the size of the compiled code ie only the types actually used are added to the code
  • while import-on-demand adds no overhead to the compiled code, they can slow down the speed of the compile
  • a constructor body can include a return statement providing no value is returned
  • any method can throw a Runtime or Error exception without declaring it in the throws clause
  • methods having the same name and parameter types do not have the same signature unless the parameter types are listed in the same order
  • main() can be declared final
  • main() is inherited and can be overridden if not declared as final
  • args[0] references first command line argument after the application name ( arrays in Java are zero-based)
  • main() can be declared public static void ... or static public void ...
  • the variable name does not have to be args; can be anything as long as the type is String[]
  • variables can have the same name as a method or a class
  • only field variables are automatically initialized to their types default value; local variables must be explicitly initialized
  • arrays are initialized to the default value of their type when they are created, not declared, even if they are local variables
  • array index operator [] has highest level of precedence
  • integer variables can be used as array dimension values
  • postfix/prefix operators have the highest level of precedence
  • remember that when the postfix operator is used in an expression, the current value of the variable is used
  • a class may be assigned to an Interface type if the class implements the interface or one of it's sub-interfaces
  • you cannot cast a primitive type to an object reference, or vice versa
  • you cannot cast a boolean type to another primitive type
  • String operations whose result does not alter the original string (ie calling toUpperCase() on a String that is already in uppercase) return the original string reference; otherwise they return a reference to a new String
  • Strings are immutable; the original String value can never be changed
  • all the primitive type wrapper classes override the Object.equals() method to compare the value of the objects; the default Object.equals() method checks if the variables reference the same object
  • you do not have to have a default statement in a switch() block
  • the default statement in a switch() blcok can appear anywhere in the construct, does not have to be last
  • all sections of the for() loop are optional
  • finalize() can only be executed once on any object
Traps
  • code with package or import declarations given in wrong order
  • more than one package declaration
  • file with more than one public class or interface declaration
  • filename.java does not match name of public class declared in the file
  • single-type imports for two classes in different packages but with the same simple name
  • single-type import with the same simple name as a class defined in the source file
  • attempting to import a package vs a type ie import java.util vs import java.util.*
  • class attempting to extend more than one other class
  • class declared both final and abstract
  • an interface method declared as native or synchronized
  • an interface method declared as static
  • subclass with default constructor when the superclass does not have a no-args constructor or it's no-arg constructor has a throws clause
  • constructor declared with a return type
  • an abstract method also declared private, native, final, synchronized, or strictfp
  • an abstract method declared in a non-abstract class
  • a native or abstract method with a method body
  • method returning a type which is not convertible to the declared return type
  • a void method returning a value
  • a static method referencing this or super
  • main() declared other than according to the standard convention
  • local (automatic) variables declared with a modifier other than final
  • identifiers names beginning with a number or # sign
  • main listed as a possible keyword
  • capitalized words listed as possible keywords; particularly wrapper classes Integer, Boolean, etc
  • C/C++ keywords listed as possible Java keywords
  • an empty string vs null as the default value for a String object
  • incorrect array declaration statements, particularly:
       arrayType [#] varName;
  • incorrect array initialization statements, particularly:
      arrayType[] varName = new arrayType[2];
      varName = { value, value, value };
  • negative values for array index
  • long value for array index
  • array declaration used as an array creation statement
  • variables of primitive type handled as Objects
  • using the char literals \u000A or \u000D in comments or Strings
  • String literal "c" assigned to char type
  • using == operator to compare values of two different string reference variables
  • variables requiring narrowing conversion being passed to methods without using a cast
  • assigning a typed byte or short variable to a char variable
  • floating point operation throwing an ArithmeticException
  • Bitwise operator precdence is: & ^ |
  • assigning subclasses with the same parent to each other
  • assigning a parent class to a subclass without a cast
  • result of an integer operation on byte or short types being assigned to a byte or short without an explicit cast
  • a non-boolean value used for operand1 in a ternary expression
  • using == to compare the contents of two different String objects
  • using a new value based on a short-circuit operation that was never evaluated
  • code that results in a primitive value being changed in a method (can't happen)
  • code that results in an unchanged object value when it was changed in a method
  • failing to cast a value to match a method parameter type ie assuming narrowing conversion on a method call
  • a non-boolean value used in a loop or if( ) statement
  • using the assignment operator '=' vs '==' in an loop or if() statement
  • using an expression vs a value promotable to int in a switch() block
  • switch() blocks with duplicate case values
  • switch() blocks with incorrectly 'typed' case statements
  • switch() blocks with missing break statements (unintentionally causing code to fall through to next case)
  • attempting to access a variable declared in the initialization outside of the for-loop
  • for()loop with incorrect initialization expression
  • for()loop with a non-boolean expression
  • a question that targets a specific object for garbage collection (can't be done)
  • a question that presumes to force the gc to run (can only suggest it run)

Mock Exams

A Java SCJP Mock Exam by Ashok Gupta The site also contains study notes.

Java Conversions


Conversions
Implicit conversions 
  • conversions which happen automatically
  • any primitive type value can be converted to a type which supports a larger value (widening primitive conversion)
  • implicit conversion occurs from integer to floating point values but not vice versa
  • you can use an object of one type wherever a reference to one of it's supertypes is required ie you can reference up the class hierarchy but not down
  • you can assign a null object reference to any object reference
Explicit conversion 
  • when one type cannot be assigned to another type through implicit conversion you can use the cast operator
Identity Conversion
  • any type can be converted to it's own type
  • only conversion allowed for boolean primitive type
Widening Primitive Conversion 
byte -> short -> int -> long -> float -> double
char -> int -> long -> float -> double
  • widening conversions of integer types preserve the exact original value of the number
  • runtime errors never occur as a result of widening conversion
  • which is why widening conversion does not allow byte and short values to be converted to char as the char type is unsigned while byte and short are signed; the byte and short would lose information
·                    byte  b =  126;
·                    short s = 1000;
·                    char  c;
·                    
·                    c = b;  // compile error: possible loss of precision
·                    c = s;  // compile error: possible loss of precision   
  • widening conversion of an int or long to a float may result in loss of precision however the new float value will be the correctly rounded equivalent of the original number
  • the same applies when a long is widened to a double
Narrowing Primitive Converson (JLS §5.1.3)
double -> float -> long -> int > char -> short > byte
  • narrowing primitive conversion may lose information about the overall magnitude of the number and may also lose precision
  • runtime errors never occur as a result of narrowing conversion because compile time errors occur if you try it; need to use cast operator
  • narrowing conversion loses all but the lowest bits (see Working with Binary, Octal and Hex numbers)
  • narrowing from floating-point numbers to integer numbers occurs within the following minimum and maximum values (values are rounded-toward-zero)
long:  -9223372036854775808..9223372036854775807
int:   -2147483648..2147483647
short: 0..-1
char:  0..65535
byte:  0..-1
  • if the floating-point value is NaN the result is an int or long value of zero
Widening Reference Conversion 
  • convert from any class, interface or array reference to an Object reference
  • convert from any class to any interface that it implements
  • convert from any class, interface or array type to a null reference
  • convert from any subinterface to any interface it extends
  • from any array to type Cloneable or type java.io.Serializable
  • from any array of references to an array of compatible reference types
  • the above conversions never produce a runtime error or require special action
You can't instantiate an interface reference as interfaces are always abstract
    SuperInterface si = new SuperInterface();   // compile-error
Narrowing Reference Conversion 
  • from Object to any other class, interface or array type
  • from any superclass to a subclass
  • from any non-final class to any interface as long as the class does not implement the interface
  • from any interface to any non-final class
  • from any interface to any final class providing the final class implements the interface
  • from any interface to any other non-superinterface and providing neither interface contains methods with the same signature
  • from any array of reference types to any other array of reference types as long as the types of each array are compatible under the Narrowing Reference rules
The above will be allowed at compile time but may throw a runtime ClassCastException if the types are not compatible
Summary
  • widening conversions do not require casts and will not produce compile or runtime errors
  • narrowing conversions require explicit casts. Will compile ok but may result in runtime ClassCastException errors
String Conversions
  • every other type, including null, can be converted to String
Method Conversion
  • each argument is converted to the type of the method parameters
  • widening conversion is implicit
  • narrowing conversion is not implicit (values must be cast)
Forbidden Conversions
  • reference to primitive
  • primitive to reference (excepting String)
  • null to primitive
  • reference or primitive to boolean
  • boolean to reference (excepting String) or primitive
  • one class to another unless they have a superclass/subclass relationship (excepting String)
  • final class to interface unless the final class implements the interface
  • class to array unless the class is Object
  • array to any class other than Object or String
  • array to any interface other than java.io.Serializable or Cloneable
  • interface to interface if they contain methods with the same signature
Example Code
class TestConversions {
    public static void main(String[] args) {   
    /** Widening **********************************************/   
    double d = 2.12345D;
    float f = 150.50F;
    long  l = 15000L;
    int   i = 55;
    char  c = 20;
    short s = 1000;         
    byte  b = 126;          
      
    // following compile ok
    System.out.println();
    System.out.println("Implicit Widening conversions:");
    System.out.println("------------------------------");
    System.out.println("  byte to short: \t -> " + (s=b) );
    System.out.println("   short to int: \t -> " + (i=s) );
    System.out.println("    int to long: \t -> " + (l=i) );
    System.out.println("  long to float: \t -> " + (f=l) );
    System.out.println("float to double: \t -> " + (d=f) );
   
    // following produce compile error: possible loss of precision
//    System.out.println("byte to char: \t -> " + (c=b) );
//    System.out.println("short to char: \t -> " + (c=s) );   
 
    // following compile ok with cast 
    System.out.println();
    System.out.println("Explicit Widening conversions:");
    System.out.println("------------------------------");   
    System.out.println("cast byte to char: \t -> " + (char)b );
    System.out.println("cast short to char: \t -> " + (char)s );
   

    /** Narrowing **********************************************/
   
    // following produce compile errors
    d = 150.234256421235489645;
   
    System.out.println();
    System.out.println("Implicit Narrowing conversions:");
    System.out.println("------------------------------");
//    System.out.println("double to float:  -> " + (f = d) );
//    System.out.println("  float to long:  -> " + (l = f) );
//    System.out.println("    long to int:  -> " + (i = l) );
//    System.out.println("   int to short:  -> " + (s = i) );
//    System.out.println("  short to byte:  -> " + (b = s) );   
    System.out.println("All require explicit cast");   

    // following compile ok with cast
            
    System.out.println();
    System.out.println("Explicit Narrowing conversions:");
    System.out.println("------------------------------");
    System.out.println("double to float:  -> " + (f = (float)d) );
    System.out.println("  float to long:  -> " + (l = (long)f) );
    System.out.println("    long to int:  -> " + (i = (int)l) );
    System.out.println("   int to short:  -> " + (s = (short)i) );
    System.out.println("  short to byte:  -> " + (b = (byte)s) );   
       
       
    /** Widening Reference ***************************************/
   
    SuperClass sc = new SuperClass();
    SubClass   sb = new SubClass();
    SubClassWithInterface sbi = new SubClassWithInterface();
    SuperInterface si;
    SubInterface subi;
    AlternateInterface ai;
    Object o;
    Cloneable cl;
   
    int[] arr = { 1,2,3 };
    SuperClass[] scArray = { new SuperClass(), new SuperClass() };
    SubClass[] subArray = { new SubClass(), new SubClass() };
   
    // following compile ok
    // note: cannot instantiate an interface
    System.out.println();
    System.out.println("Widening Reference conversions:");
    System.out.println("-------------------------------");
    System.out.println("          class to Object: \t -> " + (o=sc) );
    System.out.println("          array to Object: \t -> " + (o=arr) );
    System.out.println("       class to interface: \t -> " + (subi=sbi) );
    System.out.println("subinterface to interface: \t -> " + (si=subi) );
    System.out.println("       array to Cloneable: \t -> " + (cl=arr) );  
    System.out.println("   ref array to ref array: \t -> " + (scArray = subArray));
           
    // following do compile ok but throw runtime errors
   
    o = new Object();    
    sc = (SuperClass) o;
    si = (SuperInterface) o;
    arr = (int[]) o;
    sb = (SubClass) sc;
    si = (SuperInterface) sc;   
    ai = (AlternateInterface)sc;    // compiles ok, runtime error
    si = (SuperInterface)sc;        // compiles ok, runtime error
    
    }

}

class SuperClass {
    public String toString(){
        return "SuperClass";
    }
}

class SubClass extends SuperClass {
    public String toString(){
        return "SubClass";
    }
}

class SubClassWithInterface extends SuperClass
                            implements SubInterface {
                           
    public void method(){}                           
    public String toString(){
        return "SubClassWithInterface";
    }                           
}

final class FinalClass implements SuperInterface {
    public void method() {}
}

interface SuperInterface {
    public void method();
}

interface SubInterface extends SuperInterface {
    public void method();
}

interface AlternateInterface {
}
Traps
  • variables requiring narrowing conversion being passed to methods without using a cast
  • assigning a typed byte or short variable to a char variable