http://proglit.com/ the java language SA BY introduced in 1995 by Sun Microsystems • imperative, object-oriented • C-style syntax • statically-typed (mostly) • no pointers • JVM (Java Virtual Machine) • garbage collection • exceptions • SE (standard edition) • EE (enterprise edition) • ME (micro edition) Java 6 (2006) Java 7 (2010?) class (data type definition) • field (data member) • method (function member) object / instance (piece of data) class Moose { Rat r; Hamster h; void foo() {…} } encapsulation (methods act as “interface” to object’s fields) object.field object.method(args) apple.banana apple.banana.orange nadine.ed() nadine.ed().laura nadine.ed().laura.dale() object.field object.method(args) apple.banana (apple.banana).orange nadine.ed() (nadine.ed()).laura ((nadine.ed()).laura).dale () type name; new type(args) Moose m; // null m = new Moose(); Moose m = new Moose(); class Moose { Rat r; Hamster h; Moose() {…} constructor void foo() {…} } // Moose() { this.r = new Rat(); this.h = new Hamster(); } Moose(Hamster h, Rat r) { this.r = r; this.h = h; } new Moose(new Hamster(), new Rat()) inheritance Animal A B Mammal D E Cat F G C A D B E C A B C Ted Milton Kate illegal Object Jack Ted Kate Samantha Milton Brad Oliver Lisa class Terry {…} Object // extends class John extends Ben {…} Jack Ted Milton Kate illegal is-a vs. has-a Think before using inheritance. Object Jack (probably) Ted bad Lisa Kate Mike Hugh Olivia Uri Amber Hamster h = new Hamster(); Mammal m = h; h.runOnWheel(); m.runOnWheel(); illegal // OK // void bar(Mammal m) {…} x.bar(new Mammal()) x.bar(new Hamster()) Mammal foo() { if (…) { return new Mammal(); } else { return new Hamster(); } } (type) expression Mammal m = (Mammal) new Hamster(); // upcast (type) expression Mammal m = new Hamster(); // implicit upcast Hamster h = (Hamster) m; Hamster h = m; // downcast // illegal Lamp l = (Lamp) new Duck (); // illegal Object Jack overriding (redefining an inherited method) void foo() Ted t; … t.foo(); Ted Lisa Kate Mike void foo() Kate k; … k.foo(); ? x; if (…) { x = new Nick(); } else { x = new Diane(); } x.foo(); Object Nick void foo() Diane void foo() Object x; if (…) { x = new Nick(); } else { x = new Diane(); } x.foo(); // illegal Object Nick Diane void foo() void foo() interface Philip { void foo(); } class Diane implements Philip {…} class Nick implements Philip {…} Philip x; if (…) { x = new Nick(); } else { x = new Diane(); } x.foo(); // legal Object Nick Diane void foo() void foo() Philip x = new Ian(); Object Ian Nick Diane void foo() void foo() 1. Compiler checks compile time type. 2. Method invoked depends upon runtime type… 3. …except this always invokes version of own class. Mary Leo void foo() void bar() void foo() void bar() { this.foo(); } Leo l = new Leo(); l.bar(); 1. 2. 3. 4. Compiler checks compile time type. Method invoked depends upon runtime type… …except this always invokes own class’s version… …and super always invokes inherited version. Ryan Heather void foo() void foo() void ack() void ack() { super.foo(); } Heather h = new Heather(); h.ack(); Ryan Heather void foo() void foo() void ack() void foo() { super.foo(); … } void foo(Rat r) { r.bar(this); } void foo(Rat r) { r.bar(super); illegal } // primitive types byte short int long 1-byte signed integer 2-byte signed integer 4-byte signed integer 8-byte signed integer char 2-byte unsigned integer boolean float double floating-point true and false single-precision floating-point double-precision BigInteger BigDecimal (arbitrary-precision integer) (arbitrary-precision decimal) reference types: • variable holds a reference • == tests identity • cast appeases compiler primitive types: • variable holds a value • == tests equality • cast produces a new value int i = 60; float f = 5.4; i = (int)f; f = (float)i; int i = 5; byte b = 3; b = (byte)i; i = b; // implicit cast static member (a member which is not a member) class Ian { static Fran f; Ian.f static void foo() {…} Ian.foo() … // // class Ian { static Fran f; // Ian.f static void foo() {…} // Ian.foo() … Ian i = new Ian(); } i.foo(); i.f = new Fran(); 1. 2. 3. 4. 5. Compiler checks compile-time type. Method invoked depends upon runtime type… …except this always invokes own class’s version… …and super always invokes inherited version… …and static determined solely by compile-time type. package name; package shark; package pig.tiger; package pig.tiger; shark.Ant h = new shark.Ant(); package shark; Ant h = new Ant(); pig.tiger.Cow h = new pig.tiger.Cow(); package shark; import pig.tiger.Cow; import pig.tiger.Lemur; Lemur l = new Lemur(); Cow c = new Cow(); java.lang java.lang.Object java.lang.String String s = “hello”; int l = s.length(); s = s.toUpperCase(); “Hello, ” + “Ron” Ron” 5 + “ golden rings” // 5 // “HELLO” “Hello, “5 golden visibility public protected * subclasses) default private * (everywhere) (same package + (same package) (same class) * applicable only to members overloading (same name, different method) Sean void void byte void foo() foo(Mammal m, Lamp l) foo(int a) foo(Lamp l, Mammal m) Sean s = new Sean(); s.foo(new Lamp(), new Mammal()); s.foo(35); overloading (same name, different method) Sean void foo() void foo(Mammal m, Lamp byte foo(int a) // void foo(Lamp l, Mammal float foo(int b) // l) conflict m) conflict Sean s = new Sean(); s.foo(35); // ambiguous overloading (same name, different method) Sean void void byte void char foo() foo(Mammal m, Lamp l) foo(int a) foo(Lamp l, Mammal m) foo(Lamp l, Animal m) Sean s = new Sean(); s.foo(new Lamp(), new Hamster()); overloading (same name, different method) Sean void void byte void char foo() foo(Mammal m, Lamp l) foo(int a) foo(Lamp l, Mammal m) foo(Lamp l, Animal m) Sean s = new Sean(); s.foo(new Lamp(), (Animal) new Hamster()); 1. 2. 3. 4. 5. Compiler checks compile-time type and picks overload. Method invoked depends upon runtime type… …except this always invokes own class’s version… …and super always invokes inherited version… …and static determined solely by compile-time type. Jill Donald void foo() void foo(int a) (overload) void foo() (override) Jill Donald void foo() void foo(int a) (overload) char foo() (illegal) Moose(Hamster h, Rat r) { this.r = r; this.h = h; } Moose() { this.r = new Rat(); this.h = new Hamster(); } new Moose(new Hamster(), new Rat()) Moose(Hamster h, Rat r) { this.r = r; this.h = h; } Moose() { this(new Hamster(), new Rat()); } Moose(Hamster h, Rat r) { this.r = r; this.h = h; } Moose() { // not what we want new Moose(new Hamster(), new Rat()); } Moose(Hamster h, Rat r) { this.r = r; this.h = h; } Moose() { // sensical, but not legal Java Moose(new Hamster(), new Rat()); } Moose(Hamster h, Rat r) { this.r = r; this.h = h; } Moose() { this(new Hamster(), new Rat()); } Moose(Hamster h, Rat r) { super(); // invoke constructor of Moose’s parent this.r = r; this.h = h; } Moose() { this(new Hamster(), new Rat()); } Object Jack Ted Kate new Kate() constructor rules 1. Constructors invoked only via new, this(), or super(). 2. Calls to this() and super() only can be first line. 3. The first line is always this() or super(). 4. Default first line is super() with no arguments. // infinite recursion Moose(Hamster h, Rat r) { this(); } Moose() { this(new Hamster(), new Rat()); } constructor rules 1. Constructors invoked only via new, this(), or super(). 2. The first line is always this() or super(). 3. Calls to this() and super() only go in first line. 4. Default first line is super() with no arguments. 5. A this() call cannot be recursive. 6. To return, always just use return; Object exceptions Throwable Exception RuntimeException Error Cat c; … c.meow(); // exception if c is null Cat c; … try { c.meow(); // exception if c is null } catch (NullPointerException e) { … } Object Throwable Exception RuntimeException* Error* *unchecked // illegal void bar() { if (…) { throw new Leo(); exception } } // checked // OK void bar() throws Leo { if (…) { throw new Leo(); // checked exception } } // OK void bar() { try { if (…) { throw new Leo(); // checked exception } } catch (Leo e) { … } } void bar() throws FooException, AckException {…} void bar() throws Exception {…} arrays (fixed-sized, homogenous collection) Apple[] Apple ref Apple object Apple ref Apple ref Apple object Apple ref Fuji object Mammal[] m; m = new Mammal[3]; m[2] = new Mammal(); m[0] = new Cat(); int i = m.length; // 3 Object Object[] Lisa Lisa[] Jerry Wyatt Jerry[] Natalie Natalie[] Wyatt[] Cat[] c = new Cat[3]; Mammal[] m = c; Object[] o1 = c; Object o2 = c; Cat[] c = new Cat[3]; Mammal[] m = (Mammal []) c; Object[] o1 = (Object []) c; Object o2 = (Object) c; c = (Cat[]) o2; Mammal[] m = new Cat[4]; m[0] = new Mammal(); // exception Mammal[] m = new Cat[4]; m[0] = new Cat(); Cat mittens = m[0]; // compile error Mammal[] m = new Cat[4]; m[0] = new Cat(); Cat mittens = (Cat) m[0]; OK // Object Object[][] Lisa Lisa[][] Jerry Wyatt Jerry[][] Natalie Natalie[][] Wyatt[][] Apple[][] Apple[] ref Apple[] object Apple[] ref Apple[] ref Apple[] ref Fuji[] object Cat[][] c = new Cat[3][]; c[1] = new Cat[5]; c[1][0] = new Cat(); Cat[][] c = new Cat[3][]; c[1] = new Cat[5]; (c[1])[0] = new Cat(); Object Object[][][] Lisa Lisa[][][] Jerry Wyatt Jerry[][][] Natalie Natalie[][][] Wyatt[][][] Apple[][][] Apple[][] ref Apple[][] object Apple[][] ref Apple[][] ref Apple[][] ref Fuji[][] object Object Object[] Object[][] Object[][][] Object[][][][] int[] int int int int int[][] int[] ref int[] object int[] ref int[] ref int[] ref int[] object Object int[] byte[][] char[][][] float[] Hello, world! public class HelloWorld { public static void main(String[] args) { System.out.println(“Hello, world!”); } } • • • • • • • • inner classes generics abstract classes wrapper classes enumerations annotations assert final http://proglit.com/