====== SCJP Infos ====== ===== Links ====== [[java]] ===== Language Fundamentals ====== [[javatut>java/nutsandbolts/datatypes.html|Table of Primitive Data Types]] | [[javatut>java/nutsandbolts/_keywords.html|Java Language Keywords]] ==== unsorted ===== * The default constructor initializes the base classes automatically * constructor has no return type * //transient// attributes are not serialized * //volatile// is like volatile in C: no compiler options are allowed. The value has to be read consistently from the memory. For values which are often read, but seldom written * //native// means a call of native code, e.g. compiled C-code * boolean can't be converted to int or vice versa * char can be converted to int (32 Bits) but not to short (16 Bits) ==== Arrays ===== * Multidimensinal arrays don't have to be rectangular! * Automatisch index-Ueberwacht int [] ia= new int[3]; String[] sa= {"a", "b"}; Object o0= ia; // ok Object o1= sa; // ok //Object[] oa0= ia; // ERROR: incompatible types Object[] oa1= sa; // ok ==== Initalization Values ===== * Instazvariablen werden automatisch mit 0 vorbelegt * Automatische Variablen (Stack) werden nicht initialisiert * Integerkonstanten haben den Typ int, floating pointkonstanten haben den Typ double! Fuer int & short gibt es keinen Modyfier, for long L, for float F (lower case also possible) * byte b=3 works (auto range check) but float f=3.3 will not compile! * float f=3 works (int is converted to float) * Float f=3.3 works (autoboxing, Foat has constructors accepting double (and float and String)) * long l=6 works, but Long l=6 not, because autoboxing calls Long constuctor which expects only long or String! ===== 1. Declarations and Access Control ====== ==== Declarations ===== * A static method can //not// call a nonstatic method, but the other way around is possible * Bei Konstanten Grossschreibung nur bei **primitiven Datentypen**, da bei final-Objekten nur dir Referenz, aber nicht der Inhalt des Objektes konstant ist. * Aufbau Sourcefile: Package-Deklaration | Imports | Klassendefinitionen * Nur **eine** public-Class per sourcefile is allowed. And Filename == PublicClassName.java * Not having a proper main-method results in an runtime error, not in an compiler error! * Native methods cannot have a body "natMet(){...}" only "natMet();" * Main method must be ''public static void main(String[] args)'' but this ''public static strictfp synchronized final void main(String[] args) throws Exception'' will also compile and run (tested) === Allowed modifiers for variables and methods: ==== | ^final ^public ^protected ^private ^static ^transient ^volatile ^abstract ^synchronized ^strictfp ^native ^ ^local variables |IYES |INO |INO |INO |INO |INO |INO |INO |INO |INO |INO | ^variables |IYES |IYES |IYES |IYES |IYES |IYES |IYES |INO |INO |INO |INO | ^methods |IYES |IYES* |IYES* |IYES |IYES |INO |INO |IYES |IYES |IYES |IYES | *)Only possible combinations with **abstract**: **public** and **protected**, nothing else! (tested) ==== Packages ===== * import blah.* schliesst nur alle Klassen des Packages blah, nicht jedoch Sub-Packages ein * Umgekehrte Domain-Namen fuer Packages sind nur eine Empfehlung / Konvention * Wird keine Package-Deklaration angegeben, gilt offensichtlich sowas wie das "Default"-Package * A Class can be public or not public. If public, it can be made visible in other packages (in addition to public it can als be abstract or final and strictfp (floating point)) ==== Interfaces ===== * Interface variables must be initialized when declarated (tested) * Interface variables are implicitly **public static final** and must not be anything else! (tested) * Interface methods are implicitly **public abstract** (not static, not final) and must not be anything else! (tested) * The runnable interface: public void run() * An Interface can only extend (not implement) 1 or more other interfaces (not classes) * A class can extend 1 other class and implement 1 or more interfaces * Because interface methods are public the implementing methods must also be public! ==== Abstract Classes ===== * An abstract class can claim to implement an interface but doesn't need to mention the methods of that interface at all! * An abstract method has no body-braces: {...} * A class that contains an abstract method must itself be declarated as abstract **but not vice versa** * An abstract class can't be instanciated * It's legal to extend an abstract class from a concrete class * concrete methods of superclass can be declared abstract by subclasses ===== 2. Object Orientation ====== ==== Benefits of Encapsulation == Maintainability, flexibility and extensibility: * Changes in implementation are possible without breaking the client code * Code is easier to reuse ==== Overridden and Overloaded Methods == ^ Method is ^ overloaded ^ overwritten ^ | argument list | must change | must stay same | | return type | can change | same or subtype :!: | | exceptions | can change | only fewer or narrower | | access modifier | can change | only less limited or same | | invocation detemined by | reference type | real type | It's not possible to have 2 or more methods in the same inheritance chain wich differ only in the return type :!: === Overriding Methods ===== This is polymorphism. Rules for overriding a method: * Argument list and return type must exactly match * The access level must not be more restrictive, but can be less restrictive * New or broader checked (not runtime) exceptions must not be thrown, but narrower or fewer exception can be thrown * Private and final methods cannot be overwritten === Overloading Methods ===== Overloading means different methods with same name (wich do the same) but with different argument list. Rules: * An overloading Method **must** change the argument list * An overloading Method can have a different return type (, but should be avoided) * An overloading Method can change the access modifier * An overloading Method can decleare different checked exceptions (tested 2006-02-13) * Overloading can happen in the same class or in a subclass === Overloading with Boxing and Varargs ===== class Tester { static void go(int i) {} // noConverison static void go(long l) {} // widening static void go(Integer io) {} // autoboxing static void go(int ...) {} // varargs public static void main() { int i=9; go(i); } } Which go() will be called? The rule is: **noConverison beats widening beats boxing beats varargs**. 1st Reason: Downward compatibility to java 1.4 an 2nd Reason: varags is mor "loose" than autoboxing, is more a fallback to default * Widen and than box is impossible: Eg an int cannot become a Long * box and than widen is possible: Eg an int can become an Object (via Integer) ==== Constructors and Instantiation == * The **first call** in a constructor of any class other than Object must //either// be this(...), i.e. calling another constructor, in the same class, //or// super(...), i.e. calling a constructor of the base class. If omitted, super() is inserted automatically. * After that first call, all instance variables (including static and base class ones) are accessible (tested 2006-02-13) * Before the super constuctor returns, only static members and functions are available, eg for passing as argument to this() or super() * The default (compiler generated and no arg) constructor is only generated automatically when no other constructor is present. * The default constructor has the same access modifier as the class (none or public) * Final attribute values can only be set in the constructor or at declaration * Every class //including abstract classes// has a constructor * A method with the same name as the class that has a return type (including void) is //not// a constructor! * Interfaces don't have constructors * Constructors can be called only from within another constructor ==== Reference Variable Casting == class Animal {} class Dog extends Animal { void doDogStuff(){} } class Tester { public static void main(String[] args) { Animal a= new Animal(); Animal d= new Dog(); //(Dog)d.doDogStuff(); // Compiler ERROR: Cast needs paratesis! ((Dog)d).doDogStuff(); // ok ((Dog)a).doDogStuff(); // compiles(!!) but throws ClassCastException } } ===== 3. Assignments and 4. Operators ====== ==== Converting and Casting ===== === Primitive Data Types ==== * all operations are on base of int, thus byte and short are automatically converted to int * no conversion or casting from or to boolean! * byte b; b+=7 compiles, but b=b+7 doesn't compile! * Interger literals are of type int, floating point literals are of type double * float f= 7.6f compiles, but float f= 7.6 not, whereas * byte b= 7 compiles * Possible assignments without cast: double <- float <- long <- int <- short <- byte (tested 2006-02-10) * characters (char, 16Bit) can be auto-cast into int (32Bit) ^ Integer ^^ Floating Point ^^ ^ expression ^ result ^ expression ^ result ^ | integer literal | int | fp literal | double | | byte operation | int | | | | short operation | int | | | | int operation | int | float operation | float | | long operation | long | double operation | double | === Reference Types ==== * cast to interface type is always possible, because any subclass of class could somewhen implement the interface; exception: class is final and does not implement the interface * An array in java is an object, that implements clonable and serializable === Shadowing and Stack Variables ==== class Tester { static int arsch=3; // A public static void main(String[] args) { System.out.print(arsch+ " "); // B int arsch=4; // C System.out.println(arsch); } // compiles and prints: 3 4 } If the class variable would not exist (A), the code would not compile at (B), because the automatic variable (C) doesn't exist until it's ceated in the code (tested) ==== Comparison Operators ===== * Array of primitives are objects too! * Things that can be compared: * Numbers with each other: byte short int long float double * char only with char * boolean only with boolean * Object reference variables only of the same type or if one is the base type (implements or extends) of the other (tested) ==== Arithmetic Operators ===== * (anyInteger / 0) or modulo causes runtime exception, not compiletime error * Division by 0.0 (floating p.) causes no exception, but infinity ==== Logical Operators ===== * op1&&op2 ; op1||op2 : only boolean operators possible (if (5 && 6) ... will NOT comile!), evaluates op2 only if necessary * op1&op2 ; op1|op2 : eighter only boolean operators (inefficient!) or only numbers (bitwise then); always evaluates op2 ==== instanceof ===== * instanceof kann bei einem Downcast zum vorherigen Test verwendet werden * Type of tested object (before instanceof-operator) and Class/Interface (after instanceof-operator) must lie in the same inheritance chain, otherwise it won't compile (tested 2006-02-10) ==== Bit Shift ==== INO not tested any more! * %%>>%% der Wert des MSB wird nachgezogen * %%>>>%% Es wird immer 0 nachgezogen * %%<<<%% doen't exist ===== 5. Flow Control, Exceptions and Assertions ====== ==== Loops ===== === Continue and Break ==== * ''continue'' must always be inside a loop(for, while, do while), otherwise compiler error * If ''continue'' terminates a loop cycle, the iteration expression (3rd expression) still runs! ' ''continue'' causes only the current cycle of the innermost loop to cease * ''break'' must be inside a loop or inside switch * Labeled continue and break ("continue myLabel" or "break myLabel") cease/terminate the labeled loop not the innermost loop * **Labeled ''continue'' and ''break'' statements must be somewhere inside the loop that has the same label name, otherwise the code will not compile** === Enhanced For Loop ==== * Block variable must always declared newly * Autoboxing possible === For Loop ==== * more than one command can be separated by ',' in 1st (initialization)? and 3rd (iteration) field * only 1 test expression allowed, no ","! Examples: int i= 6, m=8; for (i=0, m=0; i<3; i++) {} // ok to initialize more outer vars // for (int i=0; i<3; i++) {}; // Compiler Error! i alread exists for (int j=0, k=0; j<3 && k<2; j++, k++) {} // ok to declare more vars of the same type //for (int j=0, int k=0; j<3 ; j++, ) {} // Compiler Error! Wrong initialisaition //for (int j=0, k=0; j<3, k<2; j++, ) {} // Compiler Error! Wrong condition check ==== Branching Statements ===== === Switch ==== switch(expression) { case constant1: {} case constant2: {} default: {} } * expression must evalutate to char, byte, short, int, long, enum * expression //can// be a constant! * constantX //must// be a constant * constantX must evaluate to the same type as the expression * For enums: The type of the enum must be specified in the expression and needs not to be specified in constantX * 'default' works just like any other case for fall-through!! * 'default' is executed when no other 'case' is true!! class SwitchTester { public static void main(String[] args) { final int i=4; final long l=4; switch((byte)3) { // ok, constant is allowed case 127:{} // ok case -4:{} // ok //case 128:{} // Error! To big for byte case i: {} // ok //case l: {} // Error! long is not auto-converted to int or smaller } } } ==== Exceptions ===== === Important Classes ===== [[javaref>api/java/lang/Throwable.html]] Throwable |-- Error | |-- AssertionError | `-- LinkageError | `-- ExceptionInInitializerError (JVM) `-- Exception |-- ParseException |-- IOException `-- RuntimeException |-- ArithmeticException |-- ClassCastException (JVM) |-- IndexOutOfBoundsException | `-- ArrayIndexOutOfBoundsException |-- IllegalMonitorStateException |-- IllegalStateException (Developer) `-- IllegalArgumentException (Developer) `-- NumberFormatException (Developer) JVM: typically thrown by JVM Developer: typically thrown by a Devoloper of an application or API === Facts ===== * It's ok for an overriding method to throw the same exceptions, narrower exceptions, no exceptions or any runtime exceptions * Throwable and its descendants are real classes, not interfaces nor abstract * no runtime exception rule: //handle or declare// * runtime exception: are so generic that they shouldn't appear at all; RE's are errors in the code * Errors are severe exceptions which normally can't be handled => program termination * finally is always executed, no matter if an exception occured or not, even with assertions! * finally is executed **before** the exception is thrown upward, but **after** the catch clause! * no runtime exception = //application exception// * catch: order does matter! specialized types first, than more generic exception types * An overriding method can throw less, but not more exceptions than the overridden method in the parent class * A try-clause without catch-clause and without filally-claus is illegal * Only allowed order try{...}catch(XXXExcption e){...}finally{...}, and no code in-between! ==== Assertions ===== Principle: If an assertion expression evaluates to false, than an AssertionError is thrown if, and only if java is started with -ea flag Syntax example: assert a < b; // or: assert a < b : "a="+a+" is too big"; // or assert (a < b) : "a="+a+" is too big"; // but not: //assert (a < b : "a="+a+" is too big"); // Compiler Error! * Assertions apply only to java, not to javac * Are //disabled by default//, enable with "java -ea" :!: * Dont use assertions to check the parameters of a public method, * but use them to check the parameters of a private method * Never catch an AssertionError! * Ok to explicitly throw an AssertionError (to get ae, when assertions are disabled) * VM evaluates all assertion flags left2right === Compiler Issuses ==== int assert = 0;// warning with javac -source 1.3; error with -source 1.4 assert(false); // error with javac -source 1.3; ok with -source 1.4 ===== 6. Strings, IO, Formatting and Parsing ====== ==== Strings ===== === Class String ===== Important public methods: import java.lang.String; char charAt(int index); int indexOf(int ch); // Returns the index of the first occurrence of ch or -1 int indexOf(String s); // Returns the index of the first occurrence of s or -1 String concat(String str); // same as + boolean equalsIgnoreCase(String anotherString); int length(); String replace(char oldChar, char newChar); String substring(int beginIndex, [int endIndex]); String toLowerCase([Locale locale]); String toUpperCase([Locale locale]); String trim(); // Returns a copy of the string, with leading and trailing whitespace omitted. * Stings have a length()-method, not like arrays a length-attribute! * '+' is for Strings overloaded with concat() * ''s= s.concat("more")'', not only ''s.concat("more")''! Because ''String'' immutable, like concat, all methods of String can't operate on themselves but return a new String object! * "smiles".substring(1, 5) returns "mile" * String is final => it can't be overwritten === Classes StringBuffer and StringBuilder ===== Imporant public methods: import java.lang.StringBuffer; int length(); char charAt(int index); int indexOf(String str); // not char like in String! StringBuffer append(String str); // heavily overloaded with all types of arguments! StringBuffer delete(int start, int end); StringBuffer insert(int offset, String str); // heavily overloaded with other types than String! StringBuffer reverse(); String toString(); * public String concat(String s) <=> public synchronized StringBuffer append(String s) * StringBuilder supports the same operation as StringBuffer but is not synchronized * StringBuffer.equals is not overwritten and therefore useless! ==== File Navigation and IO ===== === Metods of File ===== [[javaref>api/java/io/File.html]] import java.io.File; File(String pathname); // overloaded with: File(String parent, String child); File(File parent, String child); static final String separator // eg. / for unix, \\ for windows boolean exists(); boolean isFile(); // true only for a normal file, not dir boolean createNewFile() throws IOException; boolean mkdir();// Creates the directory named by this abstract pathname /** Deletes file or directory . If this pathname denotes a directory, then the directory must be empty in order to be deleted. Returns: true if the file or directory is deleted; false otherwise */ boolean delete(); === Serialization ===== [[java#i_o_streams|IO stream overview]] Serializable is just a marker interface, i.e. no methods to implement. Class Object does //not// implement this interface! If a serialized object contains sub-objects, they also must implement the serializable interface or marked transient, otherwise an Exception is thrown! public final void writeObject(Object obj) throws IOException; public final Object readObject() throws IOException, ClassNotFoundException readObject(); Method writeObject of class ObjectOutputStream serializes any serializable object. For writing to a file, the constructor of ObjectOutputStream needs an instance of FileOutputStream. And Method readObject of ObjectInputStream works analogous. Here the returned object has to be casted! Static variables are //never// being serialized! == Manipulation of Serialization == If a class to be serialized provides exactly private void writeObject(ObjectOutputStream os) // and private void readObject(ObjectOutputStream os) those methods will be called while (de)serialization. These method throw the same exceptions as their namesakes of ObjectOutputStream & ObjectInputStream, namly IOException and IOException, ClassNotFoundException respectively. These exceptions can be declared to be thrown or handled within the methods. Extra variables can be (de)serialized with this methods, eg: os.writeInt(i) while os.defaultWriteObject and is.defaultReadObject has to be called to (de)serialize the rest of the object. The order of the method calls on os and is has to be the same in both methods! == Inheritance and Serialization == When objects are deserialized, no constructors are running. (It makes no sense because we want to resore the state before serializing, not the initial state) Serializable objects with non-serializable superclasses can be serialized, but the values inherited from the first non-serializable superclass and upward will //not// going to be restored. Instead the constructor of the first non-serializable superclass will be called and thus also every constructor ABOVE will run. == Serialized Arrays and Collections == For serializing an array or collection, every element must be serializable. Otherwise, an exception is thrown :?: The collection interfaces are not serializable, but the concrete collection classes in the Java API are. This means, that the type of the reference variable to the collection must be of the concrete (implementing) class type, not of the interface type, like usually :?: ==== Dates, Numbers and Currencies == Only instances of the classes Date and Locale can be created with a constructor. For Calendar, DateFormat and NumberFormat factory methods must be used :!: === Class Date == Most of Date is deprecated, but the followning uses and methods are useful: import java.util.Date; Date now = new Date(); public long getTime() // returns the number of milliseconds since January 1, 1970, 00:00:00 GMT public void setTime(long time) // set Date object to milliseconds after January 1, 1970 00:00:00 GMT === class Calendar == Useful methods and uses of class Calendar: import java.util.Calendar; // Calendar c = new Calendar(); // is illegal, because Calendar is abstract! Calendar c = Calendar.getInstance(); // use factory method instead of constructor public final void setTime(Date date); // getInstance doesn't set a Date! public final Date getTime(); public int getFirstDayOfWeek(); // Gets what the first day of the week is; e.g. MONDAY in France public static final int MONDAY; // Value of the DAY_OF_WEEK field indicating Monday public static final int DAY_OF_WEEK // For get and set indicating the day of the week. // Takes values from SUNDAY, MONDAY ... SATURDAY. public int get(int field); // Returns the actual value of the given calendar field, eg: c.get(Calendar.DAY_OF_WEEK); // only one version of get() exists! public abstract void add(int field, int amount) // Adds or subtracts the amount to the given field, eg: add(Calendar.DAY_OF_MONTH, -5) // only one version of get() exists! //c.toString(); is useless, use getTime().toString() instead! === Class DateFormat == Class DateFormat isn't aware of a certain date (=point in time)? DateFormat (and NumberFormat) can have their locales set only on time of instantiation :!: import java.text.DateFormat; // DateFormat df = new DateFormat(); // is illegal, is abstract! /** Get a default date/time formatter that uses the SHORT style for both the date and the time. */ public static final DateFormat getInstance(); /** Gets the date formatter with the given formatting style for the default locale Possible values: SHORT, MEDIUM, LONG, FULL Also available: getTimeInstance & getDateTimeInstance */ public static final DateFormat getDateInstance([int style[, Locale aLocale]]); /** Formats a Date into a date/time string. Overloaded methods available! */ public final String format(Date date); /** Parses text from the beginning of the given string to produce a date. Mind the ParseException, this is no RuntimeException, must be handled or declared!! */ public Date parse(String source) throws ParseException; === Class Locale == import java.util.Locale; public Locale(String language[, String country]); // eg: Locale locPT = new Locale("it"); // Italian Locale locBR = new Locale("it", "CH"); // Switzerland === Class NumberFormat == import java.text.NumberFormat; /** Returns a general-purpose number format for the current default locale. This is the same as calling getNumberInstance() */ public static final NumberFormat getInstance([Locale inLocale]) /** Returns a currency format for the specified locale. */ public static NumberFormat getCurrencyInstance([Locale inLocale]) public final String f public final String format(double number); public final String format(long number); /** Parses text from the beginning of the given string to produce a number. */ public Number parse(String source) throws ParseException; ==== Parsing, Tokenizing and Formatting == === Parsing == In general regex serch runs from left to right and once a source's character has been used in a match, it cannot be reused. import java.util.regex.Pattern; import java.util.regex.Matcher; Pattern p = Pattern.compile("\\d\\w"); // the expression Matcher m = p.matcher("ab4 56_7ab"); // the source while(m.find()) System.out.println(m.start() + " "+ m.group()); /* prints 4 56 7 7a */ - Generate a Pattern instance p by passing the needle-string to static Pattern.compile() factory method. Pattern has no public constuctor! - Generate a Matcher instance m by passing the haystack-string to p.matcher() - Repeatedly use boolean m.find() to check if there is (another) match - After each call to m.find() use m.start() to get the index of the previous match or m.group() to get the previous match itself as a string. Calling m.start() or m.group() without successful call to find() before leads to an IllegalStateException (runtime exception) :!: Important meta characters: ^ ^ matches... ^ | . | any character? | | * | previous char 0 or more times | | ? | previous char 0 or 1 time? | | + | previous char 1 or more times | | \d | same as [0-9] | | \s | any whitespace | | \w | letters, digits or _ | ''String pat= "\d";'' results in a compiler error, because d is not a valid escape character! How to search for the . (dot) char? ''String pattern= "\\."'' The dot is a metachar, therefore it must be escaped w th \ to get the literal meaning. But \ is also the escape char when defining strigs, so it must iself be escaped! = Any metachar in a search pattern that starts with \ has to be escaped in the string def, eg: pattern \w becomes ''String pattern="\\w"'' === Tokenizing == /** Splits this string around matches of the given regular expression. May also produce empty matches if 2 delimiters follow each other directly */ public String[] split(String regex); A more powerfull class Scanner is also available. === Formatting == Format string is composed by: ''%[ArgIndex$][flags][width][.precision]conversionChar'' * Which arg will be used by this format string; 0 not possible?; Ends with $ * Flags: * + prepend always + and - * - left justify (Not possible together with 0) * 0 pad with zeroes * , use locale specific grouping separators * ( enclose negative numbers with () * width: Minimum number of characters to print. ()+-,. are counted! * .precision: Only for floating point: number of digits to print after the decimal point * conversionChar: * b boolean accepts all objects and all primitves; null is expanded to false; 0 to true; some flags are forbidden eg 0 and + * d integer (no u!) accepts short, Short, int, Integer, long & Long, no fp :!: (tested) * s string accepts all objects and all primitves! * c character no Strings :!: * f floating point accepts float, double, Float & Double, no Integers :!: (tested) To provide more args than used in the format string is ok, eg: ''System.out.printf("running", t);'' Formatting is available for ''String.format()''; ''PrintStream.printf()'' = ''PrintStream.format()'' and '''' (and more?), [[javaref>api/java/util/Formatter.html#syntax|more]] --- 2007-05-03 ==== Math class ===== INO Not tested any more * represents a library -> only static methods, private constructor, is a final class * Belongs to //java.lang// package which is imported automatically * Methods: * absolute value: abs() is overloaded for int long float double * max() min() is overloaded for int long float double, needs 2 parameters * double ceil(double) always rounds up: Math.ceil(-9.4) -> -9.0 * double floor(double) always rounds down: Math.floor(-9.4) -> -10.0 * floor() and ceil() return double! (strange!) * double random() returns a value between %%0.0 <= x < 1.0%% * int round(float); long round(double): round(x) == floor(x+0.5) also for the negative range! * double sin(double); double cos(double); double tan(double) take a radian (not degree) angle as argument * double sqrt(double) * double toDegrees(double radian); double toRadians(double degree); * **Important:** abs(), max() & min() are overloaded for int long float double the rest gives and takes only double! * (Double.NaN == Double.NaN) is always false! ==== Wrapper Classes ===== * equals method is properly overridden * wrapped values cannot be modified, wrapper classes are immutable (like String) * parseByte ... parseDouble all throw a NumberFormatException which is a IllegalArgumentException which is a RuntimeException Essential method signatures: ^ method ^ purpose ^ static ^ ^ | ''wrapper.xxxValue()'' | wrapper -> primitive | INO | from all 6 number wrappers to all number primitives | | ''Wrapper.parseWrapper(String)'' | string -> primitive | IYES | only for number wrappers, not Boolean, not Character| | ''Wrapper.valueOf(String)'' | string → wrapper | IYES | all 6 number Wrappers + Boolean | ==== Using equals(Object) ===== * If equals() is overwritten, also hashcode() hast to be overwritten, because equal objects should have the same hash code * equals() for wrapper classes returns only true if - the primitive value and - the Class are the same * equals() of StringBuffer is **not** overwritten => 2 StringBuffer objects cannot be compared like strncmp() ===== 7. Generics and Collections == ==== Overriding hashCode() and equals() ===== public boolean equals(Object o) {return ((o instanceof ThisClass) && (...));} public int hashCode() {return 6; /* valid but bad! */} * **2 equal objects must return the same hash code** -> If you override equals(), override hashCode() as well! * equals() of Object (= not overwritten equals()) returns true only if the 2 references point to the same object * To use an object as a key in a map you must override equals() * overwriting equals(Object o): Do a type check with instanceof! * equals(), hashCode() and toString() all must have the ''publ ic'' modifier for overwriting! -> Check the signature! * Despite it's legal, don't use transient variables for determining an objects hashcode or equality * hashCode() and equals() in StringBuilder and StringBuffer are //not// overwritten -> they can not compared directly! Wrapper Classes like Integer also do a type check within their equals methods. Called with eg. a long leads to Long via autoboxing and thus the comparison always fails, regardless of the value. ==== Collections ===== See [[java#Collections]] ==== Generics ===== Autoboxing works where a primitive is supplied and an Object is expected, whereas unboxing doesn't work where an Object is supplied and a primitive is expected. -> The upcast to eg Integer must be done by hand: List test= new ArrayList(); // legacy code test.add(6); // Object expectet autoboxing works int x= (Integer)test.get(0) // Cast necessary for unboxing To parametrize a generic with the wildcard ''? extends ...'' prohibits to call methods which need the type in their paramter list: import java.util.*; class Tester { public static void main(String[] args) { List li0 = new ArrayList(); List li1 = li0; List li2 = li0; li0.add(new Integer(3)); li0.add(new Short((short)3)); //li1.add(new Integer(5)); // Error! li2.add(new Integer(7)); // works //li2.add(new Short((short)7)); // Error! Object t= li1.get(0); // works li1.remove(0); // works } } ==== Garbage Collection ===== * Handle eines Objekts kann auf null gesetzt werden, damit die GC sicher zuschlagen kann * GC can't be forced, GC runs asyncronuously * suggest garbage collecton to VM: ''Runtime rt = Runtime.getRuntime(); rt.gc();'' or: ''System.gc();'' * content of finalize() is never garanteed to run => in general don't override it! * For every object finalize() is called at most once ===== 8. Inner Classes ===== See [[java#inner_classes|overview]] first! ==== (Regular) Inner Class ===== * Instantiating an inner class requires an instance of the outer class. * Can use both class and instance variables of the outer class * Creating an IC from outside the outer class: ''Outer.Inner inner= outer.new Inner()'' * Access to outer this form IC: ''Outer.this'' * Allowed modifiers: final, abstract, public, private, protected, static, strictfp ==== Method-local inner Class ===== * Can be instanitated only within the method where it is defined * object of MLIC can only use //final// local variables of the method * Can use both class and instance variables of the outer class * Only possible modifiers are abstract //or// final * If declared in a static method it has only access to the static members of the enclosing class ==== Anonymous inner Class ===== * AIC's are created on the fly by implementing the mehtods of an interface or inheriting form another class (and overwirting methods) * Watch for missing semicolons after the AIC ends! * Only methods of the superclass or the implemented interface can be called from the AIC * Interfaces can't be instantiated, only their implementors! * AIC's can als be method local ==== Static nested Class ===== * More a concept of name-space scope * Is a class that's a static member of the enclosing class => it can be accessed without an instance of the outer class * No access to the instance variables , only to static variables of the outer class * Instantiation: ''Outer.Nested n= new Outer.Nested();'' * ICs that are declared static automatically become top level classes ===== 9 Threads ====== See [[java#Threads|java>Threads]] first ==== General ===== * ''Thread'' implements ''//Runnable//'' which defines the single method ''public void run()'' * Once a Thread is started, it can never be started again! (Leads to a runtime exception) * When a thread is running it will not have a lower priority than any thread in the runnable state. If a low-priority thread is running when a high-priority thread enters runnable, the JVM will usually preempt the running low-priority thread and put the high-priority thread in. * static's sleep() & join() (of Thread) & wait() of Object all throw InterruptedException, but not static yield() (of Thread) ==== Synchronized ===== * syncronized method or code block: Only one thread can access the code at one time * A thread owns the lock on the object, not vice versa. * Only one thread can own the lock on an object, but a thread can own the lock of more than on different objects * syncronized refers always to an object, not to code; the lock is acquired per object * Using the synchronized keyword with a constructor is a syntax error. * wait(), notify() and notifyAll() can only be called within a synchronized block and the methods can only be called on the object whose lock is owned by the current thread, otherwise an (unchecked) IllegalMonitorStateException ist thrown. * When wait() is invoced on an object, the thread executing that code gives up its lock on the object immediatily. However this is //not// the case when notify() is invoked (see scjp5Book p. 724) * Sleep does //not// relaese any locks from objects => A sleeping threads locks are not available for other treads! * Threads running static synchronized methods own the lock of the Class object of the class. Access: ''SomeClass.class'' or ''someObject.getClass()''. See [[javatut>reflect/class/getClass.html]]. ===== 10. Development ====== ==== javac ====== -d specifies the target dir for the generated class files. Specifying a nonexistent dir generates a compiler error. If ''-d targetdir'' is specified and source file starts with a package statement, javac will generate the appropiate directory structure above the targetdir. But targetdir must exist! If ''-d'' is //not// specified and source file starts with a package statement, the class files will be generated in the dir where the source file is located. This is usually the current dir, but not necessarily. ==== java ====== ''java -DmyProp=Willi SomeClass'' adds the key/value pair to the system properties. No space between -D and key is allowed. Get sysprops with: import java.util.Properties; class Tester { public static void main(String[] args) { Properties sp= System.getProperties(); System.out.println(sp.getProperty("myProp")); } } // prints: Willi The -D flag in not a compiler flag, it works only with java, not javac! ==== classpath ====== Search order: First system default classes than classpath content. cp can be an environment variable. But if -cp is specified, the environment variable will be ignored. Searching goes from left to right. It stops as soon, as a class is found. If -classpath (or -cp) is specified, than the current dir has to be added with :. otherwise classes in the local dir won't be found. If no classpath is specified, it seems, that the local dir is in the classpath automatically (tested) In order to compile A.java which needs B.java, both of package mp; javac has to be invoked with the parent dir of mp in the classpath! Reason: A.java uses class B without additional qualifier. This means that B is searched in the same package mp which must be a subdir of the dir's in classpath. ==== Jar Files ====== * have to be specified at the end of the classpath? * The can contain subdirs. * For import/package statments the system is the same as without jar files. * The name of the jar file alway has to be stated in the class path. * The dir tree inside the jar file usually resembles the package structure ie the import statements ==== Import static ====== * Statement is ''import static'' not vice versa! * Full name has to be specified, eg ''import static java.lang.System.out'' not only ''import static System.out'' Amibiguous imports: import static java.lang.Integer.MAX_VALUE; import static java.lang.Short.MAX_VALUE; // => Compiler error! *¹ import static java.lang.Integer.*; import static java.lang.Short.*; class Tester { public static void main(String[] args) {} } // => No Compiler error *² import static java.lang.Integer.*; import static java.lang.Short.*; class Tester { public static void main(String[] args) { System.out.println(MAX_VALUE); // => Compiler error! *³ } } - Single-type imports of 2 statics with the same name results immedtiatly in a compiler error - Wildcard import of 2 statics with the same name, but never using the name works but - Wildcard import of 2 statics with the same name, and trying to use the name results in a compiler error ===== Meta ====== ==== toDo ===== * Repeat failed tests (also old 1.4 ones) * Repeat IO, Threads, Generics * check http://www.sun.com/training/catalog/courses/CX-310-055.xml completely * learn by heart the keywords(?) see scjp-Book * Do Mock Test at java.com (see below) * Do Mock Test at http://www.javacamp.org ==== nimmit ===== * Wasser * Radiergummi * Bleistift * Papier, weiß, geheftet ==== Failed Tests ===== === scjp 1.4 Book ==== * chap1 * 2005-11-17: 5 9 20 * chap2 * 2005-12-19: 3 5 * chap3 * 2006-02-10: 2 3 8 9 * chap4 * 2005-11-03: 3 4 5 6 8 17 18 * chap5 Object Orientation * 2006-02-13: 17 * chap6 Math, Strings, Wrappers * 2006-03-09: 4 * chap7 Objects and Collections * 2006-04-04: 4 9 * chap8 Inner Classes * 2006-04-04: 4 * chap9 Threads === scjp 5 Book ==== * chap05 * 2006-09-26: 2 3 4 10 12 15 16 * chap06 * 2006-09-21: 4 6 7 8 9 13 15 * chap07 * 2006-09-25: 5 6 10 11 13 * chap09 * 2006-09-18: 2 6 9 12 13 15 16 17 * chap10 * 2006-09-24: 1 2 (Q10 is wrong in the book) ==== Links ===== * [[http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=next_topic&f=24&t=034229&go=newer|scjp5 book errata]] * Sun: [[https://www.suntrainingcatalogue.com/eduserv/client/loadCourse.do?coCourseCode=CX-310-055|Prüfungsbeschreibung]], [[http://www.sun.com/training/catalog/courses/CX-310-055.xml|test description]], [[http://www.register.prometric.com/Centers.asp?Page=4|Prometic]], [[http://www.sun.com/training/catalog/courses/WGS-PREX-10-QUEST.xml|free sample questions]] * Zertifizierungsmöglichkeiten in Nürnberg laut Prometric: [[http://www.tria.de/it_training/leistungsspektrum/it_zertifizierung/it_zertifizierung.html|Tria-It]] & [[http://www.netlogix.de/trainings/zertifizierungen.html|netlogix]] * 2 mock tests at www.javaprepare.com * is http://java.boot.by/scjp-tiger/ useful?