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
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)^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)
Maintainability, flexibility and extensibility:
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
This is polymorphism.
Rules for overriding a method:
Overloading means different methods with same name (wich do the same) but with different argument list.
Rules:
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
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 } }
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 |
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)
INO not tested any more!
continue
must always be inside a loop(for, while, do while), otherwise compiler errorcontinue
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 switchcontinue
and break
statements must be somewhere inside the loop that has the same label name, otherwise the code will not compile
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
switch(expression) { case constant1: {} case constant2: {} default: {} }
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 } } }
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
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!
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
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.
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!
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();
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();
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!
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!
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.
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
Only instances of the classes Date and Locale can be created with a constructor. For Calendar, DateFormat and NumberFormat factory methods must be used
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
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 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;
import java.util.Locale; public Locale(String language[, String country]); // eg: Locale locPT = new Locale("it"); // Italian Locale locBR = new Locale("it", "CH"); // Switzerland
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;
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 */
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“
/** 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.
Format string is composed by: %[ArgIndex$][flags][width][.precision]conversionChar
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()
INO Not tested any more
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 |
public boolean equals(Object o) {return ((o instanceof ThisClass) && (...));} public int hashCode() {return 6; /* valid but bad! */}
publ
ic
modifier for overwriting! → Check the signature!
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.
See Collections
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<Number> li0 = new ArrayList<Number>(); List<? extends Object> li1 = li0; List<? super Integer> 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 } }
Runtime rt = Runtime.getRuntime(); rt.gc();
or: System.gc();
See overview first!
Outer.Inner inner= outer.new Inner()
Outer.this
Outer.Nested n= new Outer.Nested();
See java>Threads first
Thread
implements Runnable
which defines the single method public void run()
SomeClass.class
or someObject.getClass()
. See reflect/class/getClass.html.-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 -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!
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.
import static
not vice versa!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! *³ } }