SCJP 5.0.

review
JAVA 5.0 KEYWORDS

RANGES FOR JAVA PRIMITIVES

INITIALIZATION

OVERLOADING EXMPLE

ASCII CODES

CORE A valid identifier must start with a letter a "$" or "_", and the rest of the characters can be letters, digits, "$", "_". No "-", "*", "?"....... are accepted. 32 is the ASCII code for space, 48 is the ASCII code for 0, 65 is the ASCII value of the character “A”, 96 represents the ASCII code for “a”. All comparisons (accept NaN != NaN) including NaN will result in false All operations including NaN (+, -,* ,/) will result in NaN You can return a short in a method that is supposed to return an int, but you cannot return a long without an explicit cast. 2.5 is implicitly a double, 2 is implicitly an int When a floating-point number is cast to an int, it simply loses the digits after the decimal. A long can be cast into a byte. If the long is over 127, it loses its most significant (leftmost) bits. x/y will have the type of the “larger” variable. Watch out for “possible loose of precision” error. (you may need an explicit cast). double vi(){ return 1/2; } returns 0.0 // int implicitly cast to double double vi(){ return 1/2.0; } returns 0.5 An array’s elements are initialized with the default value (‘\u0000’ for char, 0.0f for float ..) When you create an array by enumerating the elements you don't specify the size (it will be taken from the number of enumerated elements) If a dimension of an array has not been initialized, attempting to access an un-initialized object element raises a NullPointerException. You can create an array of size -1, without compilation errors, but you get a java.lang.NegativeArraySizeException. You can create an array of size 0, without compilation errors. argCopy, an array declared: String [][] argCopy = new String[2][2]; can be reassigned to argCopy = new String []{"1", "2", "3", "4"}; without compilation or runtime error Switch statements can evaluate only to enum, byte, short, int, and char data types (literals or final variables) => passing a long to a switch causes a compiler error. You cannot have duplicate values in a switch. Make sure you check the value for the final expressions used inside the switch Strictfp can be used in combination with classes, interfaces and methods, meaning all values used during floating-point calculations are made in the IEEE-standard float or double sizes. OPERATORS The ^ operator (called the "logical XOR"), returns true if exactly one operand is true. boolean x = false; if (x = true) { } // an assignment, so x will always be true! When you use modulo (%) operator, drop all the negative signs, compute the modulo and attach a "-" only if the left operand is negative (-5 % -2) = - (5 % 2) = -1 The & operator has a higher precedence than the | operator The conditional operators have higher precedence than assignment operators (s instanceof String) can be used only to test objects (or null) against class types that are in the same class hierarchy. => you get error if they are not in the same class hierarchy. (should be used only when overriding equals()) If equals() is well defined -> use of instanceof operator, will always return false when comparing Objects from different classes If you don't override equals(), your objects won't be useful hashing keys, and different object can’t be considered equal. When overriding equals(), use the instanceof operator to be sure you're evaluating an appropriate class. The instanceof operator returns false if the object on the left side is null. The object on the left side needs to be always explicit initialized. (even if used in a constructor) When you use = = you can get an incomparable types error, if the 2 objects you want to compare are different In static methods there is no need to initialize variables GOTCHAS Things to check first: - see if any local variable is used before initialization

- see if you have any block variable used outside the block - see if any non-static variable or method used inside static context - see if we don't have a possible loss of precision error (when we have a lot of numerical calculation) - see that all methods return what they are supposed to return (special attention to methods that include a switch) Regular classes can only be marked public (or default). If a method is taking a short as a parameter, an int needs to be cast before sending it as a parameter to that method. The final modifier assures that a reference variable cannot be referred to a different object, but final doesn’t keep the object’s state from changing. Watch out for assignments in if() clauses, can affect the rest of the if () clauses Static methods can’t use the reference this. You can get an error "illegal forward reference", if you're trying to use a variable that has not been initialized. This happens only in really obvious cases, when constructors and other methods are not involved in the process hashCode() is an native method clone() is declared protected in Object class, so you can't invoke it from other packages The Object equals() method returns true only it the 2 objects compared are = = THEORY Javac Class.java and then java Class (no .java required this time) => a NoClassDefFoundError will be thrown When you specify a class path in the command, you will overwrite the system class path (the first one from the left will be considered when you have more than one file with the same name) Coupling refers to the degree to which one class knows about or uses members of another class. When using interface types, not a class and the interface provides a small number of methods you are promoting low coupling. Cohesion refers to the degree in which a class has a single, well-defined role or responsibility. Has-a relationships always rely on instance variables, and has-a relationships are not necessary always tightly coupled. Static initialization blocks run once, when the class is first loaded. Instance initialization blocks run every time a new instance is created. They run after all super-constructors and before the constructor's code has run. INTERFACES: Interface’s methods are by default public and abstract — explicit declaration of these modifiers is optional. Interface’s variables are by default public, final and static — explicit declaration of these modifiers is optional. Watch out when trying to modify a variable declared in an interface in the body of an implementing class Interface methods can not be final or static. Interface variables cannot be protected or transient EXCEPTIONS IllegalArgumentException is the superclass for NumberFormatException A try-finally block doesn’t handle the Exception, so after the finally is executed the Exception will be propagated You can have a try inside a catch IllegalMonitorStateException is thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor. Error and RuntimeException are not checked so you can throw them in an overridden method. IllegalArgumentException, IllegalStateException and NumberFormatException, are not thrown by the JVM (are thrown by methods when some conditions are not appropriate) StackOverflowError is thrown when a stack overflow occurs because an application recourses too deeply. When casting, a ClassCastException will be thrown at runtime (It won’t be a compiler error) When throwing exception manually in a block of code, watch out for "unreachable statement" compiler error The assertion statement has two forms: assert Expression1 ; and assert Expression1 : Expression2 ; where Expression1 is a boolean expression and Expression2 is an expression that has a value. (It cannot be an invocation of a method that is declared void.) Do not use assertions to validate arguments to public methods.

INHERITANCE Object type (not the reference variable's type), determines which overridden method is used at runtime. Reference type determines which overloaded method will be used at compile time When you try to "override" a private method you can't invoke it using polymorphism even if you have the same signature in parent and child. The compiler will use the parent reference and decide that the method is for internal use only.

Each super class in an object's inheritance tree will have a constructor called. The first statement of every constructor must be a call to either this(), (an overloaded constructor), or super(). The compiler will add a call to super() if you do not, unless you have already put in a call to this(). A default constructor will not be generated when you code at least one constructor; the call to super() provided by the compiler can fail in this case Calls to super.method() can apply only to overridden methods (Static methods are not overridden) Instance members are accessible only after the super constructor runs. (super class’s members are available for use in the constructor) A constructor can throw an Exception, but the subclasses will have to handle or re-throw this Exception if the said constructor will be invoked. A static method cannot override a regular method and vice versa. (you will get a compiler error) Abstract classes have constructors that are called when a concrete subclass is instantiated. Interfaces do not have constructors. Abstract methods have no body.

The inherited variables exist and can be used in the constructor’s subclass. Initialization of class members occurs before the constructor runs, final reference variables must be initialized before the constructor completes You get a compiler error if you try assigning an object reference to a sibling reference, even with casting With respect to the method it overrides, the overriding method must have the same return type, except that as of Java 5, the return type can be a subclass—this is known as a covariant return. The overriding method must not have a more restrictive access modifier. It’s okay for an overriding method to throw the same exceptions, narrower exceptions, or no exceptions. It is okay for the overriding method to throw any runtime exceptions or even Errors b/c this ones are not checked Protected = package plus kids (kids meaning subclasses). Protected is less restrictive than default

VISIBILITY:

VARARGS: If you have a overloaded method that takes a String[], and a String ... var-arg, invoking the method with a instance of a String array will cause a compiler error A var-arg method can have only one var-arg parameter, and this one must come last A var-arg can take 0 elements It will be the last one considered (comes after widening and auto-boxing) GARBAGE COLLECTION Stack variables are not dealt with by the GC, but objects created locally are. Watch out in GC problems for references that are set to null and then used (will cause a NullPointerException to be thrown) Islands of objects can be GCed, even though they refer to each other. When Garbage collecting, watch out when you work with immutable Strings (+ will result in another instance for Strings) The finalize is a protected method of Object object and can be used to resurrect an object. If you assign null to a reference, the object doesn’t change (It may be collected by the GC if there isn’t any other reference to that object) AUTOBOXING: All the wrappers are located in java.lang package new Boolean("aString") will wrap a false boolean Number is not the super class for Boolean and Character Using == with wrappers is tricky; wrappers with the same small values (typically lower than 127), will be = =, larger values will not be = =. The equals() method for the integer wrappers will only return true if the two primitive types and the two values are equal Trying to un-box a null value will cause a NullPointerException. You can't auto-box a primitive just by trying to invoke a method with it. Primitive widening uses the "smallest" method argument possible. A wrapper can’t be used in a switch even if it’s final (auto boxing won’t work in this case)

You CANNOT widen and then box in one step. (An int can't become a Long.) You can box and then widen. (An int can become a Number, via an Integer.) long newLong = Long.parseLong(String s); returns the named primitive Long newLong = Long.valueOf(String s); returns a newly created wrapped object of the type that invoked the method. long newLong = aLong.longValue(); takes no arguments, returns a primitive When you use Integer == int, the Integer object will be unboxed, not the other way ENUMS: java.lang.Enum is the common base class of all Java language enumeration types An enum can be declared outside or inside a class, but NOT in a method. An enum is static by default, so it can be imported like: import static com.xyz.Enum; java.util.EnumSet is a specialized Set implementation for use with enum types. Methods: range (E from, E to), of (E, E, E ..) etc Correct enums: enum A { A } enum A { A; } The valueOf("aString") for enums returns the enum constant whose value correspond to the string argument passed (if there is no enum constant corresponding to the given string a IllegalArgumentException will be thrown) For enums you can use == or equals() with same results You can use a enhanced loop to iterate over all the values of an enum => for (MyEnum myEnum: MyEnum.values()){} You can NEVER invoke an enum constructor directly. The enum constructor is invoked automatically, with the arguments you define after the constant value. BIG(8) invokes the constructor that takes the int 8 to the constructor. SERIALIZATION: You can supplement a class's automatic serialization process by implementing the writeObject() and readObject() methods. If you do this, embedding calls to defaultWriteObject() and defaultReadObject(), respectively, will handle the part of serialization that happens normally. If an instance of a serializable object contains an instance of a non-serializable object, any attempt to serialize an instance of the first object will cause an exception to be thrown. An object that needs to be serialized needs to contain only primitive variables or Serializable objects, unless the fields are marked transient or static. (NotSerializable Exception will be thrown) If you deserialize an object, the transient variables will take the default value. When you deserialize an object, the constructor doesn’t run, the variables will have the values they had before serialization accept for the transient and static variables which will take the default values. If a super class of a serialized object doesn't implement Serializable, then when a subclass object is deserialized, the super class constructor will run. To be properly deserialized the first class in inheritance that does not implement Serializable must have a no argument constructor, else the readObject() method will throw a InvalidClassException. Transient applies only to variable declarations, not to method declarations. Use Externalizable interface for a complete control over the format and contents of the stream for an object and its super types. Externalizable extends java.io.Serializable and defines readExternal(ObjectInput in), and writeExternal(ObjectOutput out) STRING STUFF Located in java.lang.* String methods use zero-based indexes, except for the second argument of substring(). String x = new String("xyz"); actually creates 2 String objects, one referred to by x and the lost String "xyz". If you use the same String literal without the keyword new to create multiple strings, Java will create only one String object that will be referenced by all the String references The String class is final—its methods can't be overridden. Strings have a method: length(), arrays have an attribute named length. StringBuffer equals() is not overridden; it doesn't compare values. A String class doesn’t have the methods: append(), delete(), reverse(), and insert() (StringBuffer and StringBuilder do have them) StringBuffer strB =new StringBuffer(“aaaaaa”); strB.insert(4, “123”); => “aaaa123a” Natural order for Strings: space, digits, uppercase, lowercase Strings work different: String s1 = “a”; String s2 = s1; s1 = “b”; => s1 will be “b”, s2 will stay “a” Concatenation runs from left to right, and if either operand is a String, the operands are concatenated. If both operands are numbers they are added together. Parsing methods for String:  boolean matches(String regex) == Pattern.matches(regex, str)  String[] split(String regex, int limit) -> String[] will contain only the String if the search fails, limit tells how many times the pattern will be applied (negative number = as many time possible, 0 = trailing empty spaces will be discarded) WRITERS: BufferedWriters can be constructed only by wrapping a Writer (a File won’t work) A FileWriter has a constructor FileWriter(String filename, boolean append) which can be used when you want to append some data to a file that already contains information. All readers have a read() method, all writers have a write() method The Formatter’s format, String’s format and the PrintWriter’s printf and format methods work exactly the same Printf String = %[arg_index$][flags][width][.precision]conversion char: fmt.format("%2$- 10.3f %1$d", 9, (double)123456); will switch the 2 numbers, first one will have a 10 characters width including the 3 decimals; for the flag you can use:  "-" Left justify this argument

 "+" Include a sign (+ or -) with this argument  "0" Pad this argument with zeroes  "," Use locale-specific grouping separators (i.e., the comma in 123,456)  "(" Enclose negative numbers in parentheses The %S in format() method prints the given String in uppercase The %s can receive a wrapper The %b (boolean) conversion character returns true for any non-null or non-boolean argument.-> for Boolean returns valueOf() The %f (floating-point) conversion character won't automatically promote an integer type. The %d (integral not double) conversion character won't take a floating point number. The %t (date and time) conversion character won't take a floating point number. When using printf with decimals, the number is rounded to the closest value INNER CLASSES An inner class can access all of the outer class's members, including those marked private. An inner class can have any access modifier An inner class cannot have static declarations. An inner class can be declared abstract Instantiating an inner class from code within the enclosing class: MyInner mi = new MyInner(); Instantiating an inner class from code outside the enclosing class: MyOuter mo = new MyOuter(); MyOuter.MyInner inner = mo.new MyInner(); Instantiating a static nested class requires: BigOuter.Nested n = new BigOuter.Nested(); A method-local inner class cannot use variables declared within the method (including parameters) unless those variables are marked final. A static nested class can access only static members of the outer class You cannot mark any local inner class (or any other variable) as static. Boo f = new Boo(24) { }; will be a correct anonymous inner class if Boo has a constructor that takes an int Don’t forget about “;” after anonymous classes From an inner class you can use MyOuter.this; to get the enclosing object THREADS.

A Thread's constructors can take: a ThreadGroup(not by itself), a Runnable, a String = name in this order if 2 or 3of these are used in the same time If a thread is executing a low-level interruptible blocking method like sleep(), join(), or wait(), it can throw an InterruptedException when is interrupted by some other thread through a call to Thread.interrupt(). => must be enclosed in a try/catch block You can call start() on a Thread object only once. If start() is called more than once on a Thread object, it will throw a RuntimeException Sleeping is used to delay execution for a period of time, and no locks are released when a thread goes to sleep. When one thread calls the join() method of another thread, the currently running thread will wait until the thread it joins with has completed. Static methods can be synchronized, they will use the lock from the java.lang.Class instance representing that class. If a thread invokes wait() or notify() on a particular object, then the thread must currently hold the lock on that object, else a IllegalMonitorStateException will be thrown. (method or block must be synchronized upon that specific object) If you have more than one instance of an object, make sure you lock on TheClass.class, in order to synchronize (otherwise you will have a lock on different instances => the same code may be handled in the same time by different threads) A waiting thread will not return to runnable when the lock is released, unless a notification occurs. If the thread has not been notified by the time the wait(5000) duration has elapsed, then the thread will move back to runnable even without having been notified. You can mark an overridden method with synchronized even if the superclass’s method is not synchronized. Thread names don't need to be unique. Abstract methods cannot be synchronized When synchronizing over a literal String, Java will use the same object instance even if for any other type of Object it would use different instances When synchronizing over a static object the lock will be on the class instance Synchronize can not be applied to constructors, but you can have a synchronized block inside the constructor. Static methods cannot call directly an instance method like notifyAll() or wait, even if the method is synchronized over the right object, because a static method cannot access an instance method From synchronized context if you assign another object to the variable that was pointing to the object used for synchronization, a call to wait(), notify() or notifyAll() will throw a RuntimeException b/c the synchronization is still made over the first object. join(), wait() and sleep() accept an int parameter that will represent a duration

run() can’t be overridden with a static run() => it is not an override anymore start() just schedules a Thread for running, is not actually starting it

GENERICS: The compiler will generate warnings if it sees that there's a chance your type safe collection could be harmed by older, non-typesafe code. Generics is strictly a compile-time protection You can't use a primitive type as a type parameter List<Parent> myList = new ArrayList<Child>(); will not work because the type of the variable declaration must match the type you pass to the actual object type When using a wildcard, List<? extends Dog>, the collection can be accessed but not modified. When using a wildcard, List<?>, any generic type can be assigned to the reference, but for access only, no modifications. The generics type identifier can be used in class, method, and variable declarations:  class Foo<T> { } // a class  T anInstance; // an instance variable  Foo(T aRef) {} // a constructor argument  void bar(T aRef) {} // a method argument  T baz() {} // a return type => the compiler will substitute the actual type. You can declare a generic method using a type not defined in the class: public <T> void makeList(T t) { } No static member can use a typed parameter declared by the enclosing class Super could be used in conjunction with a wildcard but not a type variable like E. Generic methods can be parameterized by one or more parameters. => public static <X, Y extends X> boolean (X x, Y y) is correct The type parameters must be declared before the return types, but after the modifiers. <?> can be used only in declaration (not in instantiation). You cannot add anything in Collection when you use this.

COLLECTIONS Located in java.util.*

When iterating a Collection using an enhanced for make sure you assign the elements of the Collection to Objects not to primitives At runtime, the TreeSet will try to sort the elements as they're added, and when it tries to compare an Integer with a String it will throw a ClassCastException. The add() method of a TreeSet throws ClassCastException if the Object added doesn't implement Comparable LinkedHashMap has a special constructor to create a map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) To work correctly, a Map's keys must override equals() and hashCode(). HashMap and LinkedHashMap allow one null key, many null values. A Hashtable cannot have null keys or values If you try to add in a HashSet an object that doesn’t have a method of comparison, you will get a ClassCastException If you put() in a Map an entry with a key already existing in the Map, the old value will be replaced with the new one and returned A Map has a method called keySet() that returns a Set of containing all the keys in the Map and a method entrySet() that returns a Set of Map.Entry, a method values() that returns a Collection of all values. For a Queue the remove() and poll() methods act in the same way accept that, remove() throws an Exception when the queue is empty while poll() returns null Collections and Arrays classes have a sort() method (using a Comparator or sort using natural order), and a binarySearch(array or list, searchedValue) method (searches a pre-sorted array or List) Collections.sort(List list) will be used when the objects in the List implement Comparable and overrides the method int compareTo(SpecificObject) Arrays.sort(array) will be used to sort the elements in the array using the natural order Arrays.asList(existingArray) returns a fixed list backed by the specified array (any change to the array will be reflected in the list and backwards) Collections.sort(List list, Comparator comp), or int Arrays.sort(existingArray, Comparator comp) will be used when you have an object that implements Comparator => overrides the method int compare(SpecificObject1, SpecificObject2) Whenever you want to sort an array or a collection, the elements inside must all be mutually comparable. Collections.reverseOrder() and Arrays.reverseOrder() returns a Comparator Int Arrays.binarySearch() or int Collections.binarySearch() will work only if the List or array have already been sorted (If the collection/array you want to search was sorted in natural order, it must be searched in natural order =>This is accomplished by NOT sending a Comparator as an argument to the binarySearch() method) Successful searches with binarySearch() return the int index of the element being searched. Unsuccessful searches with binarySearch() return an int index that represents the insertion point. The actual insertion point is represented as (-(insertion point) -1). List.toArray(AnyObject[]) returns all the elements into the given array toArray method in List returns an array of Objects, so a cast will be required in order to use the object Collection.add() returns boolean, for a Set an element can be added or not API STUFF A java.util.Locale can take as parameter when instantiated a language, a country, and a variant (browser specific) Ex: "de_DE_WIN". A Locale has 3 constructors and a Factory method (getDefault()). The key methods are: getAvailableLocales() -> returns an array of installed Locales, and get methods for each parameter.

A java.util.Date can take as parameter when instantiated a long or a String. The key methods are: after(), compareTo(), getTime(). Most of the methods are deprecated so Calendar must be used instead. A java.util.Calendar has only factory methods that can take as parameter when instantiated a Locale or a TimeZone. It has constants defined for all month days, all week day etc. The key methods are: getAvailableLocales(), getTime(), roll(), works like add() but doesn't increment a date's bigger pieces. (For example: adding 10 months to an October date changes the month to August, but doesn't increment the Calendar's year value.) A java.util.Formatter can take as parameter when instantiated a destination (Appendable, OutputStream, PrintStream, File (or Filename as String)-> will be created or truncated to zero size), Locale (if not specified the defaultLocale will be used), or charset (same as for Locale). Key methods: format(), locale() java.text.Format is an abstract base class for formatting locale-sensitive information such as dates, messages, and numbers. It is the superclass for DateFormat, NumberFormat and MessageFormat.  NumberFormat: uses a factory method to get an instance; getInstance(), getCurrencyInstance(), getPercentInstance(), getNumberInstance()…, can take a Locale as a parameter. The key methods are: format (returns String or StringBuffer …. From an int, long), parse (a String into a Number)  DateFormat: uses a factory method to get an instance; getInstance(), getDateInstance(), getDateTimeInstance(), getNumberInstance()…, can take a Locale as a parameter, an int dateStyle (SHORT, MEDIUM, LONG, FULL), an int timeStyle. The key methods are: format (returns String or StringBuffer … from a Date), parse (a String into a Date), getAvailableLocales() A java.io.PrintWriter extends from Writer and can take as parameter when instantiated a File, String, OutputStream or Writer. The key methods are: printf, println, format, close, flush, write A java.io.File can take as paramater when instantiated a File or String. The key methods are: createNewFile(add entries to the file system), mkdir (add entries to the file system), delete, renameTo, canRead, exists(works for either files or directories), isDirectory(tests only for directories), isFile(tests only for files), list(returns an array of Strings), listFiles => returns an array of Files (can accept filter, instance of FilenameFilter which has an accept() method for filtering by name what files to be returned) A java.util.Scanner can parse primitive types and Strings using regular expressions.  can take as parameter when instantiated a String, a File, an InputStream, a Readable etc  white space is the default delimiter for Scanner; change this using useDelimiter() method.  the resulting tokens can be converted into values of different types using the various next methods, which uses the delimiters.  You can check if the Scanner has another token in its input using the various hasNext() methods  hasNext() and next() can receive a Pattern or a String regex as parameter (success only if the next token matches)  is capable of scanning numbers in the standard formats by using: useLocale(Locale locale)  findInLine(String regEx), findWithinHorizon(String regex, int i) -> attempts to find the next occurrence of a pattern, skipping delimiters;  after using one of the previous methods you can use MatcherResult result = scanner.match() to return the match result of the last scanning operation performed by this scanner; after this use result.groupCount() and result.group() methods. A java.util.regex.Pattern is a compiled representation of a regular expression. All of the state involved in performing a match resides in the java.util.regex.Matcher. The input will always be a CharSequence. Usage: Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); or boolean b = Pattern.matches("a*b", "aaaaab"); -> cannot be reused The key methods for Pattern class: compile(), matches(), matcher(), split() The key methods for Matcher class: matches() -> attempts to match all the input, find() ->can be used in a while to get all the matches, group(), start(), end(), reset(), appendReplacement(stringUsed, replacementSubString) => usually is used with find() in a while, apendTail(string) => used after appendReplacement to copy the remainder in the input sequence, replaceAll(), lookingAt() -> just like matches() but it needs only a part from the input to return true

Sign up to vote on this title
UsefulNot useful