Upload
others
View
33
Download
0
Embed Size (px)
Citation preview
pg. 1
SKILLCERTPRO
OCA Java SE 8 Programmer I Master
Cheat Sheet
1. Java Class Structure
Code style in the exam
Don't expect best practices
Really bad code there
The International Obfuscated C Code Contest: http://www.ioccc.org/
o http://www.ioccc.org/2015/dogon/prog.c
#define So long #define R rand() #include <math.h> #include <X11/Xlib.h> #define T(i,F) ((So long)(i)<<F) #define O(c,L,i) c*sin(i)+L*cos(i) #define y(n,L) for(n=0; n<L 3; n++) #define P(v,L) d=0; y(l,)d+=T(L*l[v],l*20); #define X(q) q>>10&63|q>>24&4032|q>>38&258048 char J[1<<18]; int G[W*p],_,k,I=W/4+1,w=p/4+1; float C,B,e; unsigned So long A,n,d, t,h,x, f,o,r,a,l,L,F,i,s,H=1<<18,b=250,D[1<<14],z[W*p],q =0x820008202625a0;main(){Display *j=XOpenDisplay(0);Window u=XCreateSimpleWindow (j,RootWindow(j,0),0,0,W,p,1,0,0);XImage *Y=XCreateImage(j,DefaultVisual(j,0),24 ,2,0,(char*)G,W,p,32,0); XEvent M; for(XMapWindow(j,u); XSelectInput( j,u,1)&&a- 65307; ){ if(!H){ if(XCheckWindowEvent(j,u,1,&M)){ a=XLookupKeysym(&M.xkey,0);*( a&1?&C:& B)-=(.05 -a/2% 2* .1)*!(a- 1& 4092^ 3920);a+ 2&0xfe0^ 0xfc0||( s=a+2&31 ); }else { y(k,p+ ){ F=k%w* 4|k/w; float a[6],S=(F-p /2.) /p; y(_,W+){ i=_%I*4|_/I; if( F<p&i<W){ o=1; L= i+F*W;if (l=i&3); else{ l=F&3; o=W ; } h=z[L-o*l]; f =z[L+(4- l)*o]; t =F-p/2||i-W/2; r =h^f; if(!l| !t|( int)r|(! (h- 3&3) &&258063&r>>38)) { float V=(i-W/2. )/p,U=O( S,1,B),m =32768,Q=m; a[4] =O(-1,S,B); a[3]= O(U,V,C) ; a[5]=O (-V,U,C); P((a+3 ),s*42); t||(A=d) ;f=0;y(n ,){float N=a[n+3], E=1024 /fabs(N); b= N<0; float K= (((q>>20 *n)^~-b)+!b&1023 )/1024.; y(d,)a[d ]=a[d+3]
pg. 2
SKILLCERTPRO
*E; a[n] =round(a[n]); P( a,K); i=q+d; P(a, 1); e=E* K; for(; e<m; i+=d){ l=X(i); t=r=l^(l^l-( 1<<6*n)) &63<<6*n ; if(b){ r=l; l=t; } if(J[r])l=r ; if(t=J [l]){x=( n-1)?(i|i>>40)&1023|i>>8&4190208 |4194304 :i&1023| i>>28&4190208|(b^l==r)<<23; if(h =D[(x>>6 &0xf|x>> 14&0x3f0)+t*768]){ o=h; f=n|l*4| x<<32; m =e; } if (t==8&e<Q)Q=e; } e+=E; } }b=(255 -((f&3)+ 2)%3*51) *(1-m/32768); o=o*b>>8; G[L]=o>> 32<<8|o& 16711935 ; z[L]=3*(Q<=m)|f|b<<56; } else{ d=l*(f<< 8>>40)+( 4-l)*(h<<8>>40)>>2&16774143; o=D [(d>> 6& 15|d>>14 &1008)+J[(int)h/4]*768]*(b=h>>56 )>>8; G[ L]=o>>32 <<8 | o& 16711935 ; z[L]=( int) h|d <<32|b<< 56; } }} } q +=A; XPutImage (j, u+0, DefaultGC (j,J[X(q )]=0),Y, 0,0,0,0, W,p); }} else{ L= --H/768; J[H] =R% 16*(R%4< abs((H>> 6&63)-32 )+abs((H >>12&63) -32)-3); i=H &15; F=H %768 >>4; if( L<16){if (L-1|!(R %3))b=R% 96^255; l=i*i*3+i*81/4&3; a=L>3?L-8?L-5?9858122:12365733-488848*((i+F/4*4)%8&&F% 4):R%2*5298487:3352537*L*L-14202379*L+19205553; if(L==4)if(F<l+18)a=6990400;else if(l>F-19)b*=0.7; if(L==3){ if((i-1&15)<14&(F-1&15)<14&!(F&16)){ a=12359778; _=7 -i; k=7-F%16; _^=_>>31; k^=k>>31; b=196-R%32+(k>_?k:_)%3*42;} else{ b*=1+R%2*(.5 -(i&1)); } } D[H]=(a&16711935|(a&65280)<<24)*(b>>(F>>5))>>8&0xff00ff00ff; } } }}
Classes vs. Objects
Class: building blocks. Template to create objects
Objects: runtime instances of classes
State: all objects of all our classes
Class members
Fields: class-level variables
Methods: functions, procedures
Method signature:
access modifier return type methodName(parameter type parameter name, ...)
pg. 3
SKILLCERTPRO
Valid class
public class Person { } ... class House { Person owner; int rooms; void cleanRoom(int roomNumber) {} }
Java building blocks
Classes
Interfaces
Enums (OCP)
😱 Spot errors
public class Main { public static void main(String[] args) { new House().rooms(); } } class House { String ownerName; int rooms; void cleanRoom(int roomNumber) { roomNumber = rooms; } int Rooms; int rooms() {} }
😱 Missing return statement
Easier with an IDE & compiler, right? :-D
pg. 4
SKILLCERTPRO
Comments
// one line Comments /* Multiline comment */ /* * Fancy Multiline comment * */ /** * * Java Doc comment (NOT IN THE EXAM) */
😱 Spot errors
// hello // world /* // hello world */ /* /* // Hello // World */ */
Rules .java source files
one public class in every file, at most
if there's one public class -> file name same as class
as much non-public classes as we want
😱 Spot errors
// Wolf.java
pg. 5
SKILLCERTPRO
class Wolf { } class wolf { }
😱 Spot errors
// House.java public class House { } class Person { } class Monkey { }
Main method
Entry point to our program
Java Runtime injects parameters
public static void main(String[] args) { }
Main method II
All valid
public static void main(String[] main) { // write your code here } public static void main(String... main) { // write your code here }
pg. 6
SKILLCERTPRO
public static void main(String m[]) { // write your code here }
😈 Watch out
public void main(String m[]) { // write your code here System.out.println("Hello"); }
Error: el método principal no es static en la clase Main, defina el método principal del siguiente modo: public static void main(String[] args)
😱 Spot errors
public class Main { public static void main(String args) { new House().rooms(); } } class House { String ownerName; int rooms; void cleanRoom(int roomNumber) { roomNumber = rooms; } int Rooms; int rooms() { return rooms; } }
😱 Spot errors
public class Main { public static void main(String args) { // array of Strings! new House().rooms(); } } class House { String ownerName; int rooms; void cleanRoom(int roomNumber) {
pg. 7
SKILLCERTPRO
roomNumber = rooms; } int Rooms; int rooms() { return rooms; } }
Exercise: print all parameters from command line
if its a number?
JRE vs JDK
JRE: to run Java programs
JDK: to compile Java programs
JDK contains a JRE in order to run (test) programs
o inside the JDK folder there's a JRE with java command
o javac & other tools, only in JDK
Compiling from command line
$ javac -version $ java Main
Compile & run classes by hand. Read page 14
Imports
PIC: Package, Imports, Classes
import java.lang.*; by default
import one class or all classes in that package (wildcard)
non recursive
package name: lowercase legal identifiers separated by .
pg. 8
SKILLCERTPRO
😈 Watch out
Redundant
import java.lang.Exception; import java.lang.*;
Error
import java.lang..;
Packages as namespaces
avoid conflicts with two classes, same name
FQCN: Fully Qualified Class Name
default package == no package
😈 Watch out
Error!
import java.sql.Date; // try with * import java.util.Date; public class Main { public static void main(String m[]) { Date d; } }
Exercise
create our own packages, compile from command line
launch from command line java package.ClassWithMainMethod
Constructors
pg. 9
SKILLCERTPRO
methods to initialize objects after creation
creation in three phases
Stack (references), Heap (Objects, References)
😈 Watch out
public class A { String a = "Wow"; public A() { a = "much A's"; } public void A() { } public static void main(String m[]) { A a = new A(); } }
Using object fields (get & set values)
public class A { String a = "Wow"; String s = a + " much String!"; // reading field public static void main(String m[]) { A a = new A(); a.a = "Hello"; // setting field System.out.println(a.a); // reading field } }
Instance initializer blocks
public class Doge { String meme = "Wow!"; { meme += "Much instance initializer blocks ";
pg. 10
SKILLCERTPRO
} public Doge() { meme += " so exciting"; } public static void main(String[] args) { Doge d = new Doge(); System.out.println(d.meme); } { meme += " very confusing!"; } }
Instance initializer blocks
[fit] WAT
Instance initializer blocks
pg. 11
SKILLCERTPRO
only for people who doesn't know to chain constructors
to make code confusing
to build objects without using constructors
Java Reserved words
abstract boolean break byte case catch char class const continue default do double else extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile while assert enum
Misterios
Transient: no se serializa esa propiedad (y así no se graba a disco / envia por
la red)
Volatile: puede ser accedida por múltiples hilos: está sincronizada
Strictfp: compatibilidad operaciones floating point ^1
Goto: reservado ^2
Tipos primitivos vs. Clases Wrapper
boolean Boolean byte Byte char Character double Double float Float int Integer long
Long short Short
Identificadores
Legales: los que compilan
Convenciones de código de Sun
Estándares de nombrado de JavaBeans
pg. 12
SKILLCERTPRO
Convenciones de nombres Sun
Clases: 1ª mayúscula + CamelCase
Interfaces: 1ª mayúscula + CamelCase
atributos: 1ª minúscula + CamelCase
métodos: 1ª minúscula + CamelCase
constantes: CONST_NAME
JavaBeans naming standars
JavaBean:
o constructor público sin argumentos
o propiedades privadas
o get / set / is (boolean)
o public void setProp(PropTipo val)
o public PropTipo getProp();
o Listeners:
add / remove Listener
Identificadores: reglas
empiezan por letra [A-Za-z], $, _
NO empiezan por número
desp. del 1er. carácter, cualquier combinac de letras, números y $,_
case sensitive
no se pueden usar las palabras clave de Java
Identificadores (test)
int $$; int $___10; int 1niesta;
pg. 13
SKILLCERTPRO
int :hola; int hola:; int otro_identificador$; int e$te_e$ta_mal; int pero-Este-Bien;
Reference types
reference: pointer
references: variables en la pila, apuntan a objetos en el heap
Stack:
o variables locales
o parámetros
Heap:
o variables de instancia (iVars)
o objetos
String name = null;
Declarando variables
declarar variables tipos simples
o no podemos usar null con tipos simples
declarar variables referencias
Declarando variables
int i = null; String s1, s2, s3; s1 = new String("Hello"); s2 = "World!";
MiClase c = new MiClase();
pg. 14
SKILLCERTPRO
instancia un nuevo objeto en el montón
lo inicializa
lo liga a la referencia c (que es una var. local, luego está en la pila)
Variable initialization (rules)
local vars
fields
o iVars: se establecen a un valor por defecto
o primitivos
o referencias a objetos
o arrays
class variables
Blocks of code & variable scope
class
method
if, while, switch, ...
int i = 10; { int i = 11; // error: redefining var int j = 10; // only visible inside block }
alcance de variables
static
iVars
local / automatic
block
pg. 15
SKILLCERTPRO
Order of elements
PIC: Package, Imports, Classes
methods, fields: everywhere
Destroying objects
Garbage collector finalize()
o not guaranteed to be called jconsole
Benefits of Java
OO
Encapsulation
Platform independent
Robust
Simple
Secure
Operators and statements
Numeric promotion
int + long == long
int+ float == float
byte, short, char --> promote to int always
pg. 16
SKILLCERTPRO
Byte woes
byte b1 = 1; byte b2 = 1 + b1; // error --- byte b1 = 1; byte b2 = (byte)(1 + b1);
Byte woes
byte b3 = b1++; // OK b1 = b1 += 1; // OK b1 = b1 + 1; // error
System.out.println(b1 + 1); // OK ¯\_(ツ)_/¯
Assignment
= no es ==
int i = 10; long l = 10; double d = 10.9; float f = 10.0;
Binary arithmetic operators
Unary operators
+, -, ++, --
postfix & prefix ++
instanceof no entra en el examen
pg. 17
SKILLCERTPRO
Logical operators
|, &, !: int / boolean
||, &&: short-circuit operators
Ternary operator ?
if-then-else
curly braces not mandatory
int x = 0; if (x == 10) { x = 11; } else { x == 10; } // value of x?
if-then-else
int x = 0; if (x == 10) x = 11; x--; else x = 10;
switch
int x = 0; switch (x) { case 10: case 7: case 4: break;
pg. 18
SKILLCERTPRO
default: }
switch
String name = "spongebob"; switch (name) { case "spongebob": case "7": case "PatrickStar": break; default: }
Dates and Times in Java 8
Current Date
LocalDate now = LocalDate.now(); System.out.println(now); // 2015-11-08
LocalDate: only date (not time)
can't do new LocalDate(); import java.time.LocalDate;
Date with year, month, day
LocalDate firstOfJanuary2015 = LocalDate.of(2015, Month.JANUARY, 1); System.out.println(firstOfJanuary2015);
LocalDate inmutable!
LocalDate _12Oct1492_ = LocalDate.of(1492, Month.OCTOBER, 12);
pg. 19
SKILLCERTPRO
_12Oct1492_.plusDays(800); System.out.println(_12Oct1492_); // 1492-10-12 LocalDate other = _12Oct1492_.plusDays(800); System.out.println(other); // 1494-12-21
LocalTime
LocalTime timeNow = LocalTime.now(); System.out.println(timeNow); // 13:51:53.382
LocalTime: sólo tiempo
LocalDateTime: fecha y hora
LocalTime inmutable!
LocalTime timeNow = LocalTime.now(); System.out.println(timeNow); timeNow.plusHours(1); System.out.println(timeNow); // 19:57:24.995 // 19:57:24.995
plusMinutes / minusMinutes
plusSeconds / minus
Recorrer intervalos
LocalDate start = LocalDate.of(2015, Month.APRIL, 10); LocalDate end = LocalDate.of(2015, Month.APRIL, 20); while (start.isBefore(end)) { System.out.println(start); start = start.plusDays(1); } 2015-04-10 2015-04-11 2015-04-12 2015-04-13 2015-04-14
pg. 20
SKILLCERTPRO
2015-04-15 2015-04-16 2015-04-17 2015-04-18 2015-04-19
TimeZones [^1]
System.out.println(LocalTime.now()); System.out.println(LocalTime.now(ZoneId.of("US/Pacific"))); System.out.println(LocalTime.now(ZoneId.of("Zulu"))); // console output 20:05:25.170 11:05:25.172 19:05:25.173
[^1]: no entra en el examen https://garygregory.wordpress.com/2013/06/18/what-
are-the-java-timezone-ids/
Period
// Create task every week Period everyWeek = Period.ofWeeks(1); start = LocalDate.now(); end = LocalDate.of(2016, Month.APRIL, 10); while (start.isBefore(end)) { System.out.println(start); start = start.plus(everyWeek); }
Parse dates
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); LocalDate date = LocalDate.parse("2010/10/40", formatter); System.out.println(date);
can throw java.time.format.DateTimeParseException (Runtime)
pg. 21
SKILLCERTPRO
Core Java APIs
String concatenation
1. both operands numeric, + means addition
2. either operand a STring, + means concatenation
i. operands gets promoted into String
3. expression evaluated from left --> right
String concatenation
String s1 = 1 + 3 + "j"; // "4j" String s2 = "1" + 3.0; // 13.0 String s3 = 1 + 2.5 + "€"; // 3.5€ String s4 = 1 + "" + 1; // ? String s5 = 1 + 2 + 3; // ? String s6 = null + 1; // ?
Strings are inmutable
inmutable: can't change once created
final: can't be made mutable by inheritance
String s = "Hello"; s = "goodbye"; // original "Hello" object released
Creating my own inmutable classes
final class Person { private String name; Person(String name) { this.name = name; } public String getName() {
pg. 22
SKILLCERTPRO
return name; } } // after that code... Person diego = new Person("Diego"); diego.getName(); // setName() doesn't exists
Creating my own inmutable classes
// v2, with "setter" final class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } public Person setName(String name) { return new Person(name); } }
Inmutable for what?
Parsing JSON / XML objects just read from the net
Using global settings in my app I don't want to change
In general, avoiding mutable state Is A Good Thing
Watch out!
String s = "hello"; String s1 = s.concat(" Mary Lou"); s.concat(" goodbye heart"); System.out.println(s1); System.out.println(s);
pg. 23
SKILLCERTPRO
Strings & the String pool
String s = "Hello"; String s1 = new("Hello");
Memory test
System.out.println("start"); try { Thread.sleep(3000); // 3 sec delay } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("lets go!"); List<String> list = new ArrayList<>(100000); for (int i = 0; i< 1000000; i++) { String s = "number"; // change for String s = new String("number"); list.add(s); } try { Thread.sleep(10000); // 10 sec delay } catch (InterruptedException e) { e.printStackTrace(); }
jvisualvm
Comes for free with JDK
in your $JAVA_HOME
http://visualvm.java.net/download.html
pg. 24
SKILLCERTPRO
String methods
length
charAt
indexOf
substring
toLowerCase / toUpperCase
equals / equalsIgnoreCase
startsWith / endsWith
contains
replace
trim
StringBuilder
mutable String
good for concat Strings
good for the GC / memory fragmentation
pg. 25
SKILLCERTPRO
StringBuilder s = new StringBuilder("Apple Google Microsoft"); System.out.println(s); System.out.println(s.charAt(3)); s.append(" Yahoo!"); System.out.println(s);
Typical SQL statement
String query = "Select ( " + id + ", " + name + " ) from " + table + " where " + id + " = " + theId;
at least 10 String objects...
now 1000 customers connect to this page...
10000 objects in memory...
StringBuilder vs StringBuffer
StringBuffer: old, Thread safe
StringBuilder: shiny, shiny, new, not Thread safe, use this
Equality (== vs equals)
Sirve para ver la igualdad logica entre dos objetos
Object.equals compara referencias (es identico a ==)
Podemos sobreescribirlo
Sin equals no podemos usar estos objetos como Key en HashTable
@Override public boolean equals(Object obj) { // OJO: se recibe un Object if (obj instanceof Person2 && ((Person2)obj).getName().equals(getName()) ) { return true; } return false; }
pg. 26
SKILLCERTPRO
Equals contract
reflexivo: x.equals(x) debe devolver true
simetrico: x.equals(y) <---> y.equals(x)
transitivo: x.equals(y) --> true, y.equals(z) --> true ==> x.equals(z) --> true
consistente: si x.equals(y) devuelve true y no cambiamos nada, multiples
invocaciones devuelven siempre lo mismo
x.equals(null) --> false (con x no null)
equals - hashcode contract
Si dos objectos se consideran iguales mediante equals, deben devolver el
mismo hash code value
Invocaciones sucesivas sobre un mismo objeto que no cambiamos deben
devolver el mismo valor
NO es obligatorio que si dos objetos no son iguales (equals) deban devolver
hash codes distintos: pueden devolver siempre el mismo
Arrays
definition / instantiation
// good int[] a1 = new int[10]; int a2[] = new int[10]; Integer ai[] = new Integer[10]; // bad int a3[10] = new int[10]; int a4[] = new int[]; int a5[10] = new int[]; int a6[] = new int[](); int a6[] = new int(10);
memory (when using reference types)
pg. 27
SKILLCERTPRO
Arrays: sorting / searching
Sorting
Integer ai[] = {4, 1, 3}; Arrays.sort(ai); for (int i: ai) { System.out.println(i); }
Arrays: sorting watch out
String ai[] = {"4", "11", "03", "1", "100"}; Arrays.sort(ai); for (String i: ai) { System.out.println(i); } // output: 03 1 100 11 4
Arrays: search
can only search a sorted array
int ai[] = {1, 7, 24, 32}; Arrays.sort(ai); System.out.println(" * " + Arrays.binarySearch(ai, 11)); System.out.println(" * " + Arrays.binarySearch(ai, 24));
Varargs java
(seen in chap 4)
pg. 28
SKILLCERTPRO
Multidimensional arrays
ArrayList
import java.util.*
creating an ArrayLIst
add()
remove()
set()
isEmpty(), size()
clear()
contains()
equals(): same elements in the same order
Wrapper classes
to convert values between types
to have collections of simple values
Methods / encapsulation
Method signature
public final void sayHello (String message) throws RuntimeException access | final | return | method name | parameter list | throws Exception list modifier | (optional) | type name |
pg. 29
SKILLCERTPRO
return type: check type
method name: valid identifier
Return type
Void m1(String s) { return null; } void m1(String s) { // no return } String m1() { return "hello"; }
Varargs
vargars must be lastargument
there can be only one
1. Exercise: create a method calcMedian that returns the median value of
n int numbers. At least you must pass one value
2. Exercise: create a method hodor that given some Strings returns a single string
with s1 + " Hodor! " + s2 + " Hodor! "
Access modifiers for members
3 keywords, 4 levels: private, protected, (package), public
Access modifiers: explain why are all wrong
public void public m1() {} public void m1 {
pg. 30
SKILLCERTPRO
} package void m1(String s) { } protected int m1(String s) { } protected void final m1(String s) {} protected void m1(String s);
Method modifiers
static: class method
abstract: method has no body, child class should override it
final: can't override this method
synchronized: thread safe
strictfp (not in OCA/OCP): floating point calculations IEEE 754 [^1]
native (not in OCA/OCP): to interact with native libraries (C, C++)
[^1]: Strictfp ensures that you get exactly the same results from your floating point
calculations on every platform. If you don't use strictfp, the JVM implementation is
free to use extra precision where available.
http://docs.oracle.com/javase/specs/
Static
variables
methods
static imports
Passing by value
passing by value vs. passing by ref
o in Java there's only pass by value
pg. 31
SKILLCERTPRO
o we pass a copy of the reference
simple types
object types
Overloading methods
Lambdas
use IntelliJ to learn how to write them :-D
A Lambda is just a piece of code we can pass around. Think of it as a function
pointer.
Lambda that takes a string as param and doesn't return anything
(String s) -> { ...statements; };
Without lambdas...
Runnable task1 = new Runnable() { @Override public void run() { System.out.println("Something!"); } }; task1.run();
With Lambdas...
Runnable task2 = () -> { System.out.println("Yeah!"); }; task2.run();
We can omit {} if there's only one statement
Runnable task2 = () -> System.out.println("Yeah!"); task2.run();
pg. 32
SKILLCERTPRO
Functional interface
a functional interface has exactly one abstract method
default methods in an interface have an implementation, they are not abstract
public class Main { public static void main(String[] args) { Downloadable d; d = uri -> { return uri + " Downloaded"; }; } } interface Downloadable { String download(String uri); }
Pass something to the lambda, return something
interface Eater { public String eat(int i); } Eater e = (int i) -> { return "Eaten i==" + i; }; System.out.println(e.eat(11));
Functional programming
focus on what, not in who
"I want to convert all elements in this array to String", instead of "loop
through..."
Lambda expression
o block of code
o you can store it in a variable
o you can pass it around
o methods without a name
pg. 33
SKILLCERTPRO
Lambda expressions
Stream<Person> f = people.stream().filter((Person p) -> {return p.isHappy() == true;}); f.forEach(p -> System.out.println(p.getName()));
Classic First class functions: map
Not in OCA, but useful
List<String> names = Arrays.asList("Grouch", "Chicc", "Harp"); // forEach to print names.stream().forEach(e -> System.out.println(e )); names.stream().map((e) -> e + "o").forEach(e -> System.out.printf(e + "\n")); names.stream().map((e) -> e.toUpperCase()).forEach(e -> System.out.printf(e + "\n"));
Predicates
functional interface Predicate
has a test method
boolean test(T t);
Predicate<String> p = s -> s.startsWith("G"); System.out.println(p.test("Manolo")); // --> false System.out.println(p.test("Groucho")); // --> true
Predicates can be composed!
Predicate<String> startsWithG = s -> s.startsWith("G"); Predicate<String> correctSize = s -> s.length() == 7; Predicate<String> correctName = startsWithG.and(correctSize); System.out.println(correctName.test("Manolo")); System.out.println(correctName.test("Groucho")); // --> true
pg. 34
SKILLCERTPRO
Predicates for filtering streams
List<String> names = Arrays.asList("Grouch", "Chicc", "Harp"); Predicate<String> p = s -> s.startsWith("G"); names.stream().filter(p).forEach(System.out::println);
Optionals
Optional<String> s = names.stream().reduce((s1, s2) -> { return s1+s2; }); if (s.isPresent()) { System.out.println(s.get()); }
Fun with functions
Interface Function<T,R> - T: the type of the input to the function - R: the type of the result of the function
// m1() takes a String and returns a String, hence the <String, String> static Function<String, String> m1() { return new Function<String, String>() { @Override public String apply(String s) { return s.concat(" and two boiled eggs!"); } }; }
Fun with functions
static Function<String, String> m2() { return new Function<String, String>() { @Override public String apply(String s) { return s.concat(" yeah!"); } }; } // ....
pg. 35
SKILLCERTPRO
Function<String, String> f; f = m1(); System.out.println(f.apply("Hola")); f = m2(); System.out.println(f.apply("Hola"));
Class Design
Inheritance
IS_A vs HAS_A
single inheritance
extends vs implements
a class can´t extend an Interface
can't implement a Class
against inheritance: http://www.yegor256.com/2016/09/13/inheritance-is-
procedural.html
Access modifiers for top-level classes
public, (default)
not private nor protected!
o we can have inner or nested classes with those modifiers (not in OCA)
// not in the same file: each class in a differente .java file // also: name the files public class A { }
yay or nay?
private class B { }
pg. 36
SKILLCERTPRO
yay or nay?
public default class B { }
yay or nay?
Calling super members
only public & protected
Constructors
default constructor: added by the compiler
calling always super() or this()
constructor chaining
watch out! private constructors
Constructors: private constructors!
class A { private A() { } } class B extends A { // comp error: There's no default constructor available in A // we can't call super()! }
Constructors: private constructors!
// problem solved class A { private A() { } public A(String s) {
pg. 37
SKILLCERTPRO
} } class B extends A { public B() { super(null); } }
Init order
public class Main { public static void main(String[] args) { System.out.println("In main"); Test t1 = new Test(); Test t2 = new Test(); } } class Test { static int staticNumber = 1; static { System.out.println("static block 1 " + staticNumber); staticNumber = 10; } { System.out.println("instance block 1"); } public Test() { System.out.println("Inside constructor"); } { System.out.println("instance block 2"); } static { System.out.println("static block 2 " + staticNumber); } }
In main static block 1 1 static block 2 10 instance block 1 instance block 2
pg. 38
SKILLCERTPRO
Inside constructor instance block 1 instance block 2 Inside constructor
super() vs super
class A { private int i1; int i2; } class B extends A { public B() { System.out.println(i2); i2 = 10; // OK, can see it System.out.println(i2); super.i2 = 11; // it's the same System.out.println(i2); this.i2 = 12; // same again System.out.println(i2); } }
Overloading vs. Overriding
override a method: same method in child class
overload a method: same method name, different parameters
Overriding checks
same signature
method in child class at least as accessible as method in parent class
can't throw new / broader checked exceptions
if returns a value, same type or sibclass of the method in parent class
(covariant returns) [^1]
[^1]: preserves the ordering of types
pg. 39
SKILLCERTPRO
final methods
can't be overridden
Redeclaring private methods
private methods can't be overridden
Static method hiding
no such thing as static method overridding exists
class A { public static void m1() { System.out.println("In A"); } } class B extends A { public static void m1() { // not "overridding", just same name System.out.println("In B"); } } A.m1(); // In A B.m1(); // In B A a = new B(); ((B)a).m1(); // In B
Hiding instance variables
that's why getters/setters are nice!
class A { private int i1; int i2; } class B extends A {
pg. 40
SKILLCERTPRO
int i1; // no problem, doesn't exist here String i2; // hiding instance vars! public B() { System.out.println(i2); i2 = "b"; // OK, String var System.out.println(i2); super.i2 = 11; // OK, int var System.out.println(super.i2); this.i2 = "b2"; // sOK, String var System.out.println(i2); } }
Abstract classes
a class that is marked as abstract
can't instantiate objects from this class
can have concrete & abstract methods
exercise: create an abstract class
excersise: extend an abstract class
Interfaces
method signature inside interfaces: public abstract always
marker interface: empty interface
variables inside interfaces: public static final always (static constants)
Interface inheritance
can inherit from multiple interfaces
interface I { void m1(); } interface II extends I {
pg. 41
SKILLCERTPRO
void m1(); public abstract void m2(); } class A implements II { @Override public void m1() { } @Override public void m2() { } }
Default methods in interfaces
public interface Test { public default int getInt() { return 1; } }
can't be abstract, final, static
problems with multiple inheritance?
Static methods in interfaces
interface I { void m1(); static void sm1() { System.out.println("sm1"); } }
Polymorphism
we can "see" only the part of the object we're interested in
at runtime, if we call a method, the true one is the method from the instance
clas, not the reference one
pg. 42
SKILLCERTPRO
Exceptions
An "Exceptional" 😩 family
Object | class Throwable | |-- class Error |-- class Exception | |- class RuntimeException
Types of exceptions
all Exceptions are created & injected by the Runtime
checked == "Compile-time" exceptions
o handle-or-declare rule
non-checked == runtime exceptions
Should I "catch" Errors? �
never, ever
never
really
don't do it
ever
I'm serious
don't
Try-catch-finally
try { // do something that can throw
pg. 43
SKILLCERTPRO
} catch (Exception e) { // do something if this exception is injected } finally { // do this always }
Try-catch gotchas
Error! Needs a block
try int i = 0; catch (Exception e) ;
This is fine
try { int i = 0; } catch (Exception e) { }
Try-catch gotchas
Just one try, please
try { } try { } catch (Exception e) {}
Try-catch gotchas
// we can have a try-catch with Throwable try { int i = 0; } catch (Throwable t) { // Pokémon catch: Gotta catch'em all! } try { int i = 0; } catch (Exception t) { // i++; Error: i - local to try block
pg. 44
SKILLCERTPRO
}
Try-catch gotchas
// can have more than one catch try { int i = 0; } catch (Exception e) { } catch (Throwable t) { } try { int i = 0; } catch (Throwable t) { } catch (Exception e) { // error: Exception has already been caught }
Creating your own exceptions
// Runtime, non-checked Exception class NonCheckedException extends RuntimeException { } // Compile-time, checked exception, handle or declare rule class CheckedException extends Exception { }
Catch-Or-Declare rule (Checked exceptions)
public class Main { public static void main(String[] args) { throwsNonChecked(); // no problem with non-checked try { throwsChecked(); } catch (CheckedException e) { e.printStackTrace(); } } static void throwsNonChecked() {
pg. 45
SKILLCERTPRO
throw new NonCheckedException(); } static void throwsChecked() throws CheckedException { throw new CheckedException(); } }
What does this prints? 😈
import java.io.IOException; public class Main { public static void main(String[] args) { try { System.out.println("DogeBegin"); new Main().saveToDisk(); } catch (IOException e) { System.out.println(e.getMessage()); } finally { System.out.println("DogeFinally"); } } void saveToDisk() throws IOException{ throw new IOException("Such litte space. Much files. Wow"); } }
What does this prints?
DogeBegin Such litte space. Much files. Wow DogeFinally
What does this prints? 😈
import java.io.IOException; public class Main { public static void main(String[] args) { try { System.out.println("DogeBegin"); new Main().saveToDisk(); } catch (IOException e) { System.out.println("IODoge" + e.getMessage());
pg. 46
SKILLCERTPRO
} catch (Exception e) { System.out.println("ExceptionDoge"+ e.getMessage()); } finally { System.out.println("DogeFinally"); } } void saveToDisk() throws IOException{ throw new IOException("Such litte space. Much files. Wow"); } }
What does this prints?
DogeBegin IODogeSuch litte space. Much files. Wow DogeFinally
What does this prints? 😈
import java.io.IOException; public class Main { public static void main(String[] args) { new Main().run(); } void run() { try { System.out.println("DogeBegin"); saveToDisk(); } catch (IOException e) { System.out.println("IODoge" + e.getMessage()); return; } finally { System.out.println("DogeFinally"); } System.out.println("DogeReturn"); } void saveToDisk() throws IOException{ throw new IOException("Such litte space. Much files. Wow"); } }
pg. 47
SKILLCERTPRO
What does this prints?
DogeBegin IODogeSuch litte space. Much files. Wow DogeFinally
What does this prints? 😈
import java.io.IOException; public class Main { public static void main(String[] args) { new Main().run(); } void run() { try { System.out.println("DogeBegin"); saveToDisk(); } catch (IOException e) { System.out.println("IODoge" + e.getMessage()); return; } finally { System.out.println("DogeFinally"); } System.out.println("DogeReturn"); } void saveToDisk() throws IOException{ throw new RuntimeException("Such litte space. Much files. Wow"); } }
Exception in thread "main" java.lang.RuntimeException: Such litte space. Much files. Wow DogeBegin at Main.saveToDisk(Main.java:22) DogeFinally at Main.run(Main.java:11) at Main.main(Main.java:5) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
pg. 48
SKILLCERTPRO
OCA IZ0-808 Revision Notes
Exam Revision notes for OCA Java SE 8 Programmer I (1Z0-808)
Module 1: Before You Begin
Lesson 1: Why would I take the Oracle Certified Associate Java
Programmer Exam
1.1 Why would I take the Oracle Certified Associate Java Programmer Exam
Skipped
Lesson 2: The path to certification
2.1 The path to certification
Skipped
Lesson 3: Preparation strategies
3.1 Preparation strategies
Skipped
Lesson 4: Test Taking Strategies
4.1 How to take exam questions
Skipped
4.2 Prepare for exam questions, confidence, and other resources
Skipped
Module 2: Java Basics
pg. 49
SKILLCERTPRO
Lesson 1: Define the scope of variables
1.1 The meaning of scope, blocks and curly braces
The scope of a variable is where about in the program source you can use this
variable used by it's simple name (e.g. if you have a variable, egg in
class Food, Food.egg would not be classed as a simple name, whereas being able to
use jusrt egg would)
Initially, the scope of the variable is defined within the curly braces where it's declared
until those curly braces close.
1.2 Special cases of scope
These occur under simple for loops, and in the formal parameters of a method
Lesson 2: Define the scope of a Java class
2.1 Java class files:Contents and naming rules
Structure is: Package, then Import, then Class (package and imports are optional)
package mypackage; import myother.package.Here; import ohlook.here.are.morepackages.*; public class MyClass {...} class MyOtherClass {...} interface MyInterface {...}
Having more than one class/interface in a source file is unusual, but can be used.
It's only possible to have at most one public class or interface in one source file
2.2 Java classes: The class, member variables, methods and constructors
Within a class, we're allowed: (in any order, all elements in a class, unlike a method,
are collected together, so order does not matter)
o Method(s), static or non-static
o Constructor(s) (initialize objects of that class before they are made available
for regular use)
o Class(es), yes, you can declare a class inside another class :o
We can label as public so it's available from anywhere in our program, if we leave
this off then we can only use this class from within the package it was declared in
We can mark it as abstract which makes it impossible to create an instance of the
class
pg. 50
SKILLCERTPRO
o It can still contain variables or methods to be referenced elsewhere
o We usually use abstract classes as a base class for others to be derived
Lesson 3: Create executable Java applications with a main
method; run a Java program from the command line; including
console output
3.1 Creating executable Java applications with a main method
When the JVM starts, it looks for a method: main as an entrypoint
public static void main(String[] args) // alternatively, the following will function: public static void main(String $woo[]) public static void main(String _Name[]) public static void main(String... args)
public - accessible anywhere
static - no instance needed
void - nothing returned
main - name of method, must be called this
String[] - an array of string
args - purely convention, this can be anything
There are cases where we do not need to create a main method ourselves, e.g.
when bootstrapping with a framework, this framework will often encompass a
main method, we just provide plugin material
Java does not send a status code from the main method
o We can use System.exit(status) if we want to send a status code
We can overload the main method (same name but different types of
arguments), but there is no compelling reason and the JVM will not complain
(but won't get treated as the entrypoint)
3.2 Running Java from the command line
3.3 Managing the classpath
Directory structure must match package names
If we build from command line with javac, we must use -d flag
Supposing we have several classes (.class files, library classes are stored
in javalib from root, application code is stored in respective package structure from
pg. 51
SKILLCERTPRO
root, we need to specify a classpath comprising of our libraries and the location of
system libraries
java -cp /javalib:/home/example/things.Application would find code both
in /javalib and /home/example/things.Application (-classpath can also be used,
or set as an environment variable $CLASSPATH), we can also use /* notation to include
all files in directory
On Mac/UNIX/Linux, we use colons and foward slashes, whereas on Windows, it uses
backslashes and semi-colons
3.4 Working with console output
We can initialise a reference to the console by using:
Console c = System.console(); /* * System.console method might return null. * It usually does this if the program's I/O has been redirected */ if(c != null { c.printf(); c.format(); }
We can use this console object to instantiate a PrintWriter object:
Printwriter pw = c.writer(); pw.printf(); pw.format(); pw.append(); pw.print(); pw.println();
The Java.lang.system class has a static member called out, that can be used to write
to the system's standard output channel, this is sometimes the same destination as
the Console object (If I/O redirection occurs, this redirection will be followed)
System.out is actually a PrintStream (PrintWriter is from Console)
println() is unique as there is an overload which doesn't take a parameter, and just
prints a new line
println methods will flush the output, that is, force the characters on the screen
when they complete. The print methods probably won't do this until something
more explicit causes them to do so (flush() can be called directly)
printf and format work the same, taking template strings to concatenate text:
System.out.printf("The count is %d\n", x); // `\n` is a newline, we can also use `%n`
All placeholders start with percent sign (%d = integer, %f = float, %s = string, %b =
boolean, %% = percent sign (%))
pg. 52
SKILLCERTPRO
append methods take char or CharSequence (e.g. String, String Buffer or String
Builder)
Append returns the same object you started with
Lesson 4: Import other Java packages and make them accessible
in your code
4.1 About packages and their purpose
A package is a group of related classes
We can either use the fully qualified name for the classes we wish to use, e.g.
package mypkg; Date d = new java.util.Date();
Alternatively we can import as the following
package mypkg; import java.util.ArrayList; Arraylist al = new ArrayList();
JAR Classfiles always use fully qualified class names, so the import statement is just
syntactic sugar
4.2 Statement order, wildcard imports, importing sub-packages, and handling duplicate class
names
Heirachies in package names are purely for organisational purposes, and have no
special meaning when importing
We cannot use partial wildcard imports, we can only use an * in place of Classnames
We should not have ambiguous imports, e.g:
import java.util.*; import java.sql.*; Date d = new Date() // this is ambiguous as both packages contain Date class
We could mark one as explicit, e.g. java.util.Date d = new java.util.Date()
we could explicitly import one using fully qualified name to take precidence
import java.util.Date; import java.sql.*; Date d = new Date() // this is unambiguous as it inherits from java.util.Date class
pg. 53
SKILLCERTPRO
Lesson 5: Compare and contrast the features and components
of Java such as: platform independence, object orientation,
encapsulation, etc
5.1 Understanding Java's execution model
The Java code is compiled to platform independent Java Bytecode to run on the JVM
(Java Virtual Machine) which acts as a simulator
Runtime optimisations can be made, e.g. identifying most frequent code regions
(hotspots)
o These hotspots can be converted from platform independent byte code into
native machine code for the host CPU, this area of code will run at full speed
of a compiled program
5.2 Understanding the value of threading and garbage collection
The garbage collector takes the responsibility for releasing memory
Before Java, if two parts of a program share the same part of memory, where one
part of the program uses the memory and passes the reference to another part of the
program, seemingly uncoupled, then each sees the data written by the other as an
inexplicable corruption of the data that should have been there (these bugs tend to
be completely non-deterministic and incredibly difficult to debug)
Each part of the program is only able to indicate whether it has any ongoing interest
in using an area of memory. It does that by keeping a reference to the memory. The
garbage collector will look around at intervals, and determine which areas of memory
are still of interest to any part of the program. All the areas that are found to be of no
interest to any part of the program, are reclaimed and added back to the free
memory in the heap. This model completely prevents the accidental reuse of
memory. If a part of a program can access memory, then that will not be reclaimed.
Java does not protect us if we say we're finished with the memory when we're not,
and in that case we'll get a NullPointerException
5.3 Understanding the value of object orientation and encapsulation
Classes are are intended to represent well-understood ideas in the problem domain
that the program addresses
Objects are things we build from the templates we call classes, they tightly associate
the state that represents something with the behaviour that interacts with that state
Encapsulation allows the state of the object, its variables, to be visible outside the
class only indirectly through methods. And those methods can control whether
changes are made or rejected
o All variables must be private
o Some methods accessible from outside
o Methods protect internal state integrity
pg. 54
SKILLCERTPRO
Inheritance is a mechanism that lets us create a class from a template, and add extra
features, with other changes
o We cannot take away features, but we can change behaviour
o We can allow different objects to share definitions of common behaviour
o We can use association to share behaviours between classes
Module 3: Working with Java Data Types
Lesson 1: Declare and initialize variables (including casting of
primitive data types)
1.1 Using the general form of simple declarations
Variables can be declared as members declares as part of an object, or local variables
in a method
o Class variables can be called member variables, members, instance variables
or attributes
o Local variables are called method locals, stacked variables or automatic
variables
Everything applied to local variables is true of member declarations too, there are
additional modifiers that may be applied to member declarations
An identifier must start with a letter, an underscore or a dollar symbol, after the first
character we can have any number of letters, numbers, underscores or dollar signs
Member variables may also have an accessibility
o Public
o Private
o Protected
o No accessibility specified means default accessibility
We can declare multiple variables of the same type on the same line
int x, y, a, b;
1.2 Using the general form of initialized declerations
Local variables in methods do not have values until we explicitly give them ones,
member variables have default values
numeric types -> 0; boolean -> false; reference types -> null
We can assign multiple variables on one line
int x = 100, y = 99, z = x + y;
pg. 55
SKILLCERTPRO
1.3 Understanding integer primitive types, literal forms
Java has 4 data types that are intended as integer types, to hold whole numbers
o byte - 8 bits -128 - +127
o short - 16 bits -32,768 - +32,767
o int - 32 bits +/- 2,147,000,000 ish
o long - 64 bits +/- 9,223,000,000,000,000,000 ish
o char - 16 bits 65535 (stores no negative values) - (intended to represent
characters, but can perform arithmetic on it in calculations)
The Java system allows an implementation to use more storage if desired, this is all
hidden in the JVM though
Integer numbers have other literal forms that can be used in code
o decimal - regular numbers
o octal - start with 0 (digits from 0-7 as octal)
o hexadecimal - start with 0x
o binary literals - start with 0b (only 1s and 0s)
o long - append L to end (lowercase is permitted also)
We can assign e.g. short s = 1234;, but not in a method call, or anything computed
at runtime
We can use seperators between digits, an underscore can be used, as long as it's
between two digits, not next to a decimal point and not next to an x or b in hex and
binary numbers
1.4 Understanding floating point primitive types, literal forms
Java provides float (32 bits) and double (64 bits), stored in a special way allowing a
greater range than int but with less precision (e.g. large numbers or fractions) - floats
are not always exact, and we can see rounding errors
A number with a decimal point will always be stored by default as a double literal
We can use scientific exponent notation, with a number and e and another number
(positive or negative), e.g. 34.532E42 or 12e2
We can create a double literal by using a simple decimal literal integer type and
adding a D or d to the end
o This cannot be used with hex, octal or binary format
o This is redundant as as soon as the compiler realises you have a floating point
literal format it creates a double by default
o We must explicitly append to a literal an f or F to make a float
o We can represent NaN as a constant declaration in the Double with a capital
D or Float with a capital F classes
o These aern't the same and they don't even equal themselves
o This can represent an incomputable result, e.g. positive/minus infinity
1.5 Understanding logical and character primitive types, literal forms
boolean
pg. 56
SKILLCERTPRO
o true or false values, these are not numbers and only these values can be
used
char
o Single characters, using 16 bit UNICODE representation
o we use single quote marks to surround the character
o we can create a char literal using the unicode character number,
e.g. '\uXXXX' - the characters are not case sensitive but the u is
o These are converted by the input reading part of the Java compiler
o We can use characters in the \u format as part of the sourcecode, e.g. as part
of a variable name
o Characters such as \u000a, the linefeed character, when used in source code
will not make it compile
o We can get around this by escaping this, e.g. \n makes a newline
o \b or 08 backspace
o \t or 09 tab
o \n or 0a linefeed
o \f or 0c form feed
o \r or 0d carriage return
o \" or 22 double quote
o \' or 27 single quote
o \\ or 5c backslash
o We can use octal representation for characters with not more than 8
significant bits, these don't have a leading zero, numbers followed by a
backslash \ are assumed to be octal
o The largest octal escape value is \377
1.6 Casting primitive types
Casting is a version of polymorphism
Java is a strongly and statically types language, meaning every item of data in our
program has a precise type, known at compile time
We can use cast operator, parentesies containing a type name, e.g. (byte)
This only creates a new temporary value
If we attempt to assign a value to a primitive type, which doesn't have enough bits,
it'll only take the X most significant bits
Lesson 2: Differentiate between object reference variables and
primitive variables
2.1 Using the == operator with primitives and references
Primitive types are: boolean, char, byte, short, int, long, float, double
o The variable stores the value that it represents (written directly to variable)
Reference types are: Float, Double (all non primitive types start with uppercase
letter)
pg. 57
SKILLCERTPRO
o We allocate at least 4 bytes that can point at/refer to an object location
o When we cahnge the object, the object in memory is simply changed (the
pointer is not)
The == operator compares two values to see if they're equal or not
o If we perform this on two primitives, it directly compares the values
o If performed on reference types, it will only return true if they're pointing to
the exact same reference in memory, even if both contents are the same
2.2 Understanding method argument passing
We always pass by value in methods
When we pass primitive values into a method, we copy the value, any changes made
in the method are only in the scope of the method, and do not change the initial
variable
When we pass an object, we pass a copy of the reference to the object, therefore any
changes to the object in the method change the original object
Lesson 3: Know how to read or write to object fields
3.1 Selecting a field from a reference expression
To access a field in an object, we either need to have a variable that refers to the
object directly, or an expression that resolves to a reference to the object
public class Thing { public int numOne; public long numTwo; } Thing t = new Thing(); // The variable t is an expression (value that has a type at compilation time, and has a value at runtime) t.numOne = 7; // This is a L-value expression (can be put on the left hand side of an assignment) int value = t.numOne // We can read value of t, and assign to value
We can also assign and read using array notation
public class Box { public Thing getOneThing() { return new Thing(); } } Box b = new Box(); b.getOneThing(); // Type Thing, produces reference to a Thing b.getOneThing().numOne // L-value expression, accessing Thing object created in method public Thing[] getManyThings() {
pg. 58
SKILLCERTPRO
Thing[] ta = // Partially initialise array with Things return ta; } Box b = new Box(); b.getManyThings(); // Type reference Array of Thing b.getManyThings()[0]; // Type reference to a Thing b.getManyThings()[0].numTwo; // Type long
3.2 Using "this" to access fields
public class Thing{ public int numOne; public void doStuff() { this.numOne = this.numOne + 10; } } Thing t1 = newThing(); Thing t2 = newThing(); // These point to two different Thing objects, each object has a field, numOne
Methods e.g. doStuff are assumed to belong to an object and the method executes
within the context of the object, known as this
this is an expression of the type of the enclosing class
Method code is read only, so it's easy to share with all objects which use that method
when using this
The this is just a copy of the object passed in to the method at invocation, and
during the scope of this, the object cannot be mutated from outside the method
A variable not prefixed with something-dot
o A method local variable
o Member variable with an implied this
o It's a static variable in a class that encloses the variable
o It's a static import from a class that does not enclose the variable
3.3 Code examples
package fieldaccess; public class Box { private Thing[] things = { new Thing(), new Thing(), new Thing() }; public Thing getOneThing() { return things[2]; }; public Thing[] getManyThings() { return things; };
pg. 59
SKILLCERTPRO
public void showThings() { System.out.println("Things:"); for (Thing t : things) { System.out.println(t.toString()); } } } package mainmethod; Box b = new Box(); System.out.println("numOne in a boxed thing is " + b.getOneThing().numOne); b.getOneThing().numOne = 5432 System.out.println("numOne in a boxed thing is " + b.getOneThing().numOne);
Returns:
numOne in boxed thing is 0; numOne in boxed thing is 5432
Lesson 4: Explain an Object's Lifecycle (creation, "dereference
by reassignment" and garbage collection)
4.1 Understanding allocation and referencing
The garbage collector is responsible for working out whether an object might be
used again, and for releasing any objects back to the heap memory when they are
identified as never to be used again
The system can only determine if it is not possible to use an object again
If an object can be used again, but is not used again, it has the possibility of memory
leak
An object is always accessible through a variable of reference type
o When this variable goes out of scope, it can be garbage collected
o If they can be used late,r they're called reachable and won't be subject to gc
o Only unreachable objects are elegible for garbage collection
o The risk of releasing an object prematurely is completely avoided
4.2 Collecting Garbage
aMethod() { StringBuilder sb = new StringBuilder();
If we set sb = null, the StringBuilder object becomes eligible for collection
Every executing method, including methods further up the call tree have live stack
frames
Every variable in a live stack frame is a live variable
Every object referred to by a live variable is a live object
pg. 60
SKILLCERTPRO
Every variable in a live object is a live variable
Any other object referred to by that variable is a live object
Lesson 5: Develop code that uses wrapper classes such as
Boolean, Double and Integer
5.1 Understanding and identifying wrapper objects, understanding autobixing
Wrapper classes let us associate behaviour with data, with integrity protections
We can use Java's (Java.lang.Object) generalization mechanisms, allowing any data
looked at this way to be referred to as an object
Primitives are not object, so we cannot use generalization
Primitives do not have the same kind of data associated as with objects
Wrapper classes let us see primitive types as objects, e.g. add numbers into lists
The compiler generates code to automatically create a wrapper around the primitives,
called autoboxing (or autounboxing in the context of unboxing primitives from
objects)
boolean -> Boolean char -> Character byte -> Byte short -> Short int -> Integer long -> Long float -> Float double -> Double
5.2 Investigating the API of Integer
Integer.BYTES // num of bytes used to represent int Integer.MAX_VALUE // max val can hold Integer.MIN_VALUE // min val can hold Integer.SIZE // num of bits used to represent int Integer(int value) // converts int to Integer Integer(String s) // converts string to int Integer.byteValue() // returns val as byte after primitive conversion Integer.compareTo() // compare objects numerically Integer.doubleValue() // val of int as double Integer.equals() // compares to other object
On the command line, we can define system properties with a -D, e.g.
java -Dmy.value=99 String val = System.getProperty("my.value"); // val is "99" Integer value = Integer.getInteger("my.value"); // val is 99
pg. 61
SKILLCERTPRO
Module 4: Using Operators and Decision constructs
Lesson 1: Use Java operators; including parentheses to override
operator precedence
1.1 Using operators, operands and expressions
Operators tell the compiler to run code, predefined in the system, more usually
operating on primitive types
Infix operator expression <operator> expression - operator in middle
Prefix operator <operator> expression
Postfix operator expression <operator>
Java does not permit programmer defined operator overloading (but + and - invoke
different code when working with floating point numbers, rather than integers)
1.2 Using arithmetic operators + - * / %
% operator is modulus
o 5 % 3 = 2
o 10 % 4 = 2
o -10 % 3 = -1
o -10 % -3 = -1
o -10.5 % -3.1 = -1.2
We can get overflow when we perform operands on numbers fitting in their
respective types, but the result does not fit in
o We get strange results, due to unsigned bits etc.
Division by zero represents arithmetic exception
Floating point overflow sets result to infinity (NaN)
1.3 Using the plus operator with Strings
The plus() operator can be used with either String or numeric types
o String + AnyType => String concatenation (the other type is converted to
string, possibly using the object's toString() method)
o NumericType + NumericType => Addition
o AnyOtherCombination => Compiler Error
Java expressions are evaluated left to right
o "Hello" + 1 + 2 = Hello12
o 1 + 2 + "Hello" = 3Hello
1.4 Promoting operands
Promotion means representing smaller numbers as larger ones
pg. 62
SKILLCERTPRO
if one operand is a double, the other is promoted to double else if one operand is a float, the other is promoted to float else if one operand is a long, the other is promoted to long else int
If you add short, char or byte, we get an int result
short s = 99; byte b = 10; s = b + s; // compiler error! (this is an int)
1.5 Using increment and decrement operators
We can increment or decrement L-values (values on left side of assignment)
int x = 99; int y = ++x; // Pre-Increment // y => 100 & x => 100 int x = 99; int y = --x; // Pre-Decrement // y => 98 & x => 98 int x = 99; int y = x++; // Post-Increment // y => 99 & x => 100 int x = 99; int y = x--; // Post-Decrement // y => 99 & x => 98 int[] xa = {0,1,2,3,4}; int idx = 0; System.out.println("value is " + (xa[idx++] >= 0 && idx > 0)); // Value is true int[] xa = {0,1,2,3,4}; idx = 0; xa[++idx] = xa[idx] + 1000; for (int v : xa) { System.out.println("> " + v); } /* * > 0 * > 1001 * > 2 * > 3 * > 4
Increment and Decrement operators result in an expression the same size as the
expression they're operating on (e.g. short, byte and char stay as they were)
1.6 Using shift operators
Binary numbers read from right to left
pg. 63
SKILLCERTPRO
64 32 16 8 4 2 1 -------------------------- 0 1 0 1 0 1 0 = 42 42 >> 1 0 0 1 0 1 0 1 = 21
We lose precision as bits can drop off the end
The compiler optimises this for us
We might only use this bit shifting for specific applications, e.g. network protocol
packets
We can use >>> for unsigned shifts, where extra bits don't come in (bringing in 0s
from the left rather than 1s) - this only works with Int and Long types
o If we try this with e.g. a short, we pad the left out with 0s, to the length of an
Int
1.7 Using comparison operators
< less than
<= less than or equal to
> greater than
>= greater than or equal to
These can be used on primitive and wrapper types, but not Number type
== equal
!= not equal
Strings that are the same share the same object, even if created differently,
therefore will return true when used with comparison
1.8 Using logical operators
! boolean not
o !(x > 99) == (x < 99)
~ tilde (bit pattern not)
o ~000 == 111
& and o 1 & 1 -> 1
| or o 0 || 0 -> 0
^ xor o 1 ^ 0 -> 1 o 0 ^ 1 -> 1 o 0 ^ 0 -> 0 o 1 ^ 1 -> 0
pg. 64
SKILLCERTPRO
1.9 Using short-circuit operators
&& - If first operand evaluates to false, second operand is never computed at all
|| - If first operand is true, then second is not calculated
o Both of these are only applicable to boolean values
1.10 Using assignment operators
int x, y, z; x = y = z = 0;
Arithmetic operators: +=, -=, *=, /=, %=
Boolean operators: &=, |=, ^=
Bitwise operators: <<=, >>=, >>>=
These operators do not promote values to int, the assignment operator casts its
computed result into whatever type the assignment is assigned to
The left hand side is guaranteed to be evaluated once, and once only
1.11 Understanding assignment compatibility
A char is unsigned, so a byte or short cannot represent or be represented by
a char
The case operator has HIGH precidence
int x = 99; short s = x; // CompileError short s = (short) x; // All ok using cast operation
We cannot cast non numeric types to numeric types (we can convert, however)
Autoboxing can create objects from primitive types, but these are conversions
1.12 Understanding other elements of expressions
<reference> instanceof <classtype> int x = 0; if (x instanceof Object) // Error, x is not reference String s = "Hello"; Class cl = String.class(); if (s instanceof cl) // Error, must be class literal if (s instanceof String) // Ok! String s = "Hello"; if (s instanceof Number) // Impossible, error null instanceof Object // Always false String s = null;
pg. 65
SKILLCERTPRO
if (s instanceof String) // Not executed, returns false
The instanceof operator tells us if we can cast the left hand value to the value on the
right
t -> reference to a thing . -> dot operator selects a member x -> member to be selected String s = "Hello"; s -> expression of type String . -> dot selects an element of expression length() -> identifies element to select, () calls method
1.13 Using parentheses and operator precendence
The precedence of multiplicative (multiplication, division and modulo) operations is
higher than that of additive operations
4 + 4 / 2 = 6 (4 + 4) / 2 = 4 (3 + 4 / 2) * 7 = 35
Java evaluates from left to right
We must match number of parentheses, otherwise we get compilation error
Lesson 2: Test equality between Strings and other objects using
== and equals ()
2.1 Understanding the meaning of == and the intended meaning of equals ()
Date d1 = new Date(); Date d2 = new Date(); Date d3 = d2; d2 == d3; d1 != d2;
Providing the .equals() method has been applied correctly to the class, we can
check if the objects represent the same values
For StringBuilder() objects, it does not have an equals method to compare it's
contents, so will return false
2.2 Determining if equals() is implemented, and implementing equals()
All methods inherit the equals() method, even if they don't provide it explicitly
As a default, it provides the same as == if not overriden
pg. 66
SKILLCERTPRO
Lesson 3: Create if and if/else and ternary constructs
3.1 Understanding the basic form of if and if/else
Most basic form:
if (<boolean expression>) { <statement> } else { <other statement> }
3.2 Using braces with if/else. Effect of "else if"
If we want multi-line statements, we must use braces to form a block (otherwise we
may get a dangling else)
Else statements must attach to closest if statement (unless blocks are used)
3.3 Understanding the if / else if / else structure
if (<boolean expression>) { <statement> } else if (<other boolean expression){ <other statement> } else { <other statement> }
3.4 Using the ternary operator
<boolean> ? <value A> : <value B> if <boolean> then <value A> else <value B> int result = doTheTest() ? getOneValue() : getOtherValue();
If the second and third results (? and : results) are the same type, we will get the same
type back, e.g:
<b> ? (byte) 10 : 10 + 23 => <byte> <b> ? <byte> : <long> => <long> <b> ? <Byte> : <int> => <int> <b> ? <float> : <double> => <double>
Lesson 4: Use a switch statement
pg. 67
SKILLCERTPRO
4.1 Using the general form of switch, case, break and default
int x = ?? switch(x) { case 10: { ...; break; } case 20: ...; break; default: ...; break; }
The case value must be computable at runtime (no method calls, like with what's
allowed when using if)
4.2 Code examples for the general form of switch
int day = 1 switch (day) { // Opening and closing braces necessary case 0: // Colon necessary System.out.println("Monday"); break; case 1: // Needs to be a constant expression System.out.println("Tuesday"); break; default: System.out.println("No Day!"); break; }
We do not need break statements, but the program will loop through all options
after matching case
4.3 Understanding break
If we omit the break statement, we will fall through and execute statements that are
otherwise associated with other cases
switch(x) { case 1: case 2: case 3: case 4: System.out.println("Weekday"); break; case 5:
pg. 68
SKILLCERTPRO
case 6: System.out.println("Weekend"); break; }
The program will print 'Weekday' for cases 1 through 4, and 'Weekend' for cases 5
through 6
The order of the cases matters to the logic of the code, the compiler works top down
Falling through just lets us hand-optimise code
4.4 Identifying switchable types
We're allowed to switch on: int, short, byte, String, char and enum (set of named
values)
We're not allowed to switch on: long, float, double, boolean
o Optimisation is built into the implementation of switching on Strings
Module 5: Creating and Using Arrays
Lesson 1: Declare, instantiate and use a one-dimensional array
1.1 Understanding simple array declarations, and variables of array type
Array declarations follow the basic variable initialisation structure:
<typename> <variable name>; <typename> <variable name> = <initialisation>;
So to declare an array, we use the following:
int arrayOfInt[]; // Refers to array of integers int[] arrayOfInt; // Refers to array of integers int arrayOfInt[...]; // Refers to single int
1.2 Instantiating an array, array length
int[] aI; -> Array of integers, but we still need to instantiate it with the
assignment aI = new int[10];
o This creates an array of length 10
o As this is an array of int, each value is defaulted to 0
o Max size is about 8GB (20,000,00,000 int objects)
The length of array is determined by the number of elements in array (int expression)
pg. 69
SKILLCERTPRO
1.3 Initlaizing arrays by iteration, array indexes
int[] ai = new int[10];
These items are indexed from aI[0] -> aI[9]
Length of array is fixed at creation time and can never be changed
We can iterate through an array assigning values the following way:
int[] aI = new int[10]; for(int i=0; i<aI.length; i++) { aI[i] = getValue(); }
Arrays can also be used for Objects, e.g. StringBuilder
Each element is a reference variable to an Object, meaning each has a default value
(null for Objects)
StringBuilder[] sba = new StringBuilder[10] for(int i=0; i<sba.length; i++) { sba[i] = new StringBuilder("Hello" + i); }
1.4 Using a combined declaration and initialization of arrays
We can create an arrays and add values to it using the following:
int[] aI = {1, 2, 3, 4}; // Java doesn't mind about trailing commas int[] aI = {1, 2, 3, 4,}; Thing[] ta = { new Thing(), new Thing(99), existingThing };
1.5 Using immediate array creation not in a declaration
If we have a method:
public void doStuff(Thing[] ta) { ... }
We might like to provide an array to doStuff() without initialising a variable first doStuff(new Thing[] { newThing(), newThing(99 });
This makes it easy to tell the compiler what the base type should be
We are allowed literals, variables, expressions, object creation (expression of
the type object it creates) and null
pg. 70
SKILLCERTPRO
1.6 Initializing arrays by copying
Remember, arrays are fixed sizes
If we want a larger array, we can copy our array into another, larger, array
We can use System.arraycopy(<source array>, <starting index to copy>, <destination array>, <offset into destination array>, <num of items to copy>)
int[] aI = {1,2,3,4,5}; int[] aI2 = new int[10]; System.arraycopy(aI, 0, aI2, 0, aI.length);
We can now point the original aI to the new array: aI2 with aI = aI2;
Lesson 2: Declare, instantiate, initialize and use multi-
dimensional array
2.1 Declaring multi-dimensional arrays
These are constructed with <typename> <variablename>;
int[][] iaa; where int[] iaa[x] refers to a single array inside iaa where int iaa[x][y] refers to a single int
This can be instantiated with int iaa[][];
2.2 Using immediate initialization of multi-dimensional arrays
We can initialise in the standard curly brace method as follows:
o This creates 4 arrays, so 4 pointers (one for each inner array and a pointer for
the outer)
3x Array of Int, 1x Array of Array (of ints)
int[][] iaa = {. // iaa.length -> 3 {1,2,3}, {2,4,6}, {7,8,9} };
We can also just have basic array of arrays:
int[][] iaa = { // iaa.length -> 3 {1}, // iaa[0].length -> 1 {2,3}, // iaa[1].length -> 2 {4,5,6} // iaa[2].length -> 3 };
pg. 71
SKILLCERTPRO
// e.g. iaa[0][2].length -> 3
2.3 Using iterative initialization of multi-dimensional arrays
int[] ia = new int[10]; // This creates one array, length 10 int[][] iaa = new int[2][3]; /* * This creates 3 arrays: * 2 Sub arrays of length 3 * 1 Holder array of length 2 */
We are able to iterate through these arrays:
for(int i=0; i<iaa.length; i++) { for(int j=0; j<iaa[i].length; i++) { iaa[i][j] = getValue(); } }
And we're able to have arrays of different sizes, for example describe the size of
arrays of arrays, but not define the size of internal arrays:
int[][] iaa = new int[4][]; /* * We have created an array of 4 pointers * These all contain null values */ for(int i=0; i<iaa.length; i++) { iaa[i] = new int[i+1]; }
This loop code will make an array as follows:
{ {0}, {0,0}, {0,0,0}, {0,0,0,0} }
We are allowed to create int[4][], but not int[][4]
If we are performing a partial initialisation, we must add numbers to the brackets
from left to right
Arrays can be as deep as we want, e.g. int[][][][] iaaaa;
2.4 Code examples for multi-dimensional arrays
The following forms are legal:
Thing[][] taa; -> Pointer to Array of arrays
Thing[] taa[x]; -> Pointer to array of thing
Thing taa[x][y]; -> Pointer to individual thing
pg. 72
SKILLCERTPRO
Module 6: Using Loop Constructs
Lesson 1: Create and use while loops
1.1 Creating and using while loops
The basic while loop:
while(<boolean expression>) { <statement> }
The boolean statement can be a Boolean type (object), it will be unboxed at runtime
Test is made before entry, so loop body may never be executed
#### 1.2 Code examples of the while loop
We may accidentally make an infinite loop:
int x = 3; while ( x != 0) { System.out.println("x is" + x); }
Lesson 2: Create and use for loops including the enhanced for
loop
2.1 Understanding the simple use of the for loop
for(<setup>; <condition>; <prepare for next time>) { <programmer's code> }
2.2 Understanding the initialization section of the for loop
We can initialize many variables at a time:
for(int x=0, y=100, z; <test>; <next time>) { }
All variables initialized in the initialization section have to be the same type, but we
can use arrays:
We can only set variables of the same base type, other types are not allowed, as we
are not allowed to use semi colons again in this section
We are allowed to either declare variables or perform an expression in this section,
but not both
pg. 73
SKILLCERTPRO
for( int x=0, y=100, z, a[] = {1,2,3}, b[][], c = new int[5]; <test>; <ready for next> ){ <code here }
2.3 Understanding the test section of the for loop
Booleans will be unboxed to get the boolean primitive
This can result to false on first run, and never enter the loop
for(...; <test>; ...) { ...; } while(<test>) { ...; }
2.4 Understanding the increment section of the for loop
The initialization section permits either declarations or expression statements
o Expression statements are increment and decrement operations, assignments,
invocations of methods, and construction calls using the keyword, new
o We can provide a single expression or a comma seperated list of expressions
for(...; ...; x++, y = getValue(), doStuff(), new Banana()) { ...; }
2.5 Omitting sectinos of a for loop
Any section can be left blank, by changing the section for a semi colon ;
Leaving a test out makes it always true
The following equals while(true) for(;;) { ...; }
We can make a while loop from a for loop
for(; <test>;){ ...; }
2.6 Code examples for basic for loops
int t;
pg. 74
SKILLCERTPRO
int a = 0; int b = 0; int a = 0; for(t = (int)(Math.random() ** 10.0); a < 5; a++, b += 10, sayHello()) { System.out.println("tick..."); }
2.7 Understanding the simple use of the enhanced for loop
We use enhanced loop to iterate through collections of objects
ArrayList al = ...; for(Object obj: al) { System.out.println( "Object is " + obj); al.add(new Date()); // We should not do this line }
We should be careful to not change the collection while iterating through it, unless
explicitly ok to do so
2.8 Identifying the valid targets of the enhanced for loop
We can use an enhanced for loop with anything that implements the
interface Iterable, e.g. Iterator iterator()
o This interface provides 2 methods:
hasNext() tells us if the list has a next item (boolean)
next() gives us the next item
We can't iterate through an Iterator object, only something that implements
the Iterator interface
2.9 Using the enhanced for loop with generic collections
The compiler knows what the object being used in the for loop's type is when
we explicitly declare it
If we have the following, the compiler knows the obj is a String
o We will get a ClassCastException if we don't implement generics mechanism
correctly
ArrayList<String> als = ...; for(String obj: als) { ...; }
2.10 Code examples for enhanced for loops
ArrayList<String> als = new ArrayList<>(); als.add("Hello");
pg. 75
SKILLCERTPRO
als.add("Wilkommen"); als.add("Bienvenue"); for (String s: als) { System.out.println("String is " + s); }
### Lesson 3: Create and use do/while loops
3.1 Creating and using do/while loops
The loop is controlled by a simple test condition, an expression that evaluates to a
boolean result
The test occurs after the body of the loop, rather than the top
We can guarantee this is executed at least once
do { ...; } while(<test>);
Lesson 4: Compare loop constructs
4.1 Comparing while and do while loops
In a while loop, the code in the body is not guaranteed to run, a do loop ensures it's
run at least once
The while loop makes the test at the top, while the do while loop tests at the end
4.2 Comparing while and simple for loops
The for loop is essentially a while loop with some special extras
In both the for loop and the while loop, there is a boolean test that controls the loop
The loop will execute for as long as that test continues to evaluate to true
The test is at the top of the body of the loop
It's possible for the loop to execute zero times
The major difference is that the for loop adds the initialization section which is
typically used for declaring variables but can be used for other kinds of setup, and
the prepare for next time around section, which is effectively executed after the body
of the loop before execution jumps back to the top to re-perform the test.
4.3 Comparing while and enhanced for loops working on Iterables
An enhanced for loop is just a more intelligent while loop, with boilerplate code
behind the scenes
List<Thing> lt = ...;
pg. 76
SKILLCERTPRO
for(Thing t: lt) { ... } // Is equivalent to Iterator it = lt.iterator() while(it.hasNext()) { Thing t = it.next(); ...; }
4.4 Comparing while and enhanced for loops working on arrays
The enhanced for loop does not let us see the current index when inside the loop (or
outside)
Thing[] ta = ...; for(Thing t: ta) { ... } // Is equivalent to int idx = 0; while(idx < ta.length) { Thing t = ta[idx++]; }
Lesson 5: Use break and continue
5.1 Using break from a single loop
The break statement lets us escape early from a loop
We exit the loop without attention to the test
while(test()){ if(true) { break; } }
5.2 Using continue in a single loop
The continue keyword jumps back up to the test in a while loop, or the third segment
in a for loop (increment section)
We still loop around, but abandon the current iteration
while(test()) { if(aaa()) { continue; } }
#### 5.3 Using a labeled break from multiple loops
pg. 77
SKILLCERTPRO
We can use a label on any statement
The name of any method or variable is an identifer, so this is similar
Must begin with unicode of _ or $
<identifier>:<statement>
This can be useful when trying to break inside multiple while loops: while(<test>){ ...; middle:while(<other test>){ ...; break middle; } }
5.4 Using a labeled continue from multiple loops
We use a labeled continue in the same way as break
The label can be applied to a section of code by using indentation
while(<test>){ ...; middle: while(<other test>){ ...; continue middle; } }
Module 7: Working with Methods and Encapsulation
Lesson 1: Create methods with arguments and return values;
including overloaded methods
1.1 Creating methods
The declaration has optional modifiers, e.g. private, public, static
Followed by this, we have modifiers, the return type and the name, followed by an
argument list
<modifiers> return-type name (<argument list>)
Modifiers can include
o annotions, e.g. @override (beyond exam scope)
o access control modifiers: public, private, protected o abstract o static
pg. 78
SKILLCERTPRO
o final (cannot be overridden)
o synchronized (to do with threading, irrelevant)
o native implementation will not be written in Java, also irrelevent
o strictfp to do with floating points, do not need to know
Return types
o any primitive or Object
o can only define one return for each method
Name
o any legal identifier
o must not be the same name as any other method taking the same arguments
Arguments
o 0 or more arguments are taken o <type> <name>
o The names cannot conflict with each other, or other variables in method
The method returns to it's caller either when return is stated in the method, or at the
end curly brace. If a method is void, we can just use return;, but this is optional
#### 1.2 Code example for simple methods
public void simpleMethod() { if (Math.random() > 0.5) { System.out.println("Large number"); return; } else { System.out.println("Small number"); } System.println("The end"); } public String stringMethod(String initial) { return initial + "is now better"; }
1.3 Understanding basic syntax of overloaded methods
These are methods defined in one class, which have the same basic name
If we want to overload a method, we cannot just change the argument names, we
must adjust the number of argument types, or the type of argument that's being
passed in
class Thing { void doStuff() {...} void doStuff(String s) {...} void doStuff(float f, Date d) {...}
pg. 79
SKILLCERTPRO
}
1.4 Understanding rules and guidance for overloaded methods
Overloading is based on coded form of list of argument types, not the return value
It's bad practice to overload and change the return type as well
Example: Why do we have overloaded methods?
We may want to do the same thing with different arguments
Cake makeCake(Eggs e, Flour f) {...} Cake makeCake(PacketMix pm) {...}
1.5 Code example for overloaded methods
class Thing { void doStuff() {...} void doStuff(String s) {...} int doStuff(int f, Date d) {...} }
1.6 Investigating variable length argument lists
We might sometimes want to define a method that can handle any number of
something, not just a fixed number. In the JVM, we must take a predetermined
number of arguments (of predetermined type).
The compiler wraps the arguments into an array for us
public int addUpNumbers(int ... values) {...}
We can pass either a list of values or an array
addUpNumbers(1, 2, 3) addUpNumbers(new int[]{1,2,3}) addUpNumbers()
The vararg form will take 0 or more arguments
If we want to enforce at least one item: addUpNumbers(int first, int ... rest) {...}
Lesson 2: Apply the static keyword to methods and fields
2.1 Comparing class fields and object fields
Class Thing { private static int x;
pg. 80
SKILLCERTPRO
private int y; }
Each instance of Object of type Thing has a reference to type Class that it belongs to
Thing t = new Thing(); t.x; // Reference to x variable in Class Object t.y; // Reference to y variable in Thing object Thing t1 = new Thing(); t1.x; // Same reference as x t.x above t1.y; // New reference to y variable in Thing object
All objects in a class share the static fields of a class, but every object gets its own
version of a non-static field.
2.2 Using static on methods
Class Thing { private static int x; private int y; doStuff() {...} static doStaticStuff() {...} }
We usually invoke static methods with the classname, but it's legal to invoke with
instance name
o It ignores the instance it's invoked from
Thing t = new Thing(); t.doStuff(); Thing.doStaticStuff(); t.doStaticStuff();
We are not allowed to use this in static methods
Static should be used when we are dealing with properties or aspects of the thing
we're modelling that relate to the concept as a whole, rather than individual things.
2.3 Code Example
public class M7L2 { private int x; private static int y; public static void main(String[] args) { y = 99; System.out.println(y); // 99
pg. 81
SKILLCERTPRO
M7L2 object1 = new M7L2(); M7L2 object2 = new M7L2(); System.out.println(object1.y); // 99 System.out.println(object2.y); // 99 object1.x = 100; object2.x = 200; System.out.println(object1.x); // 100 System.out.println(object2.x); // 200 showY(); showX(); // Rejected, as we can not call this from a non static context object1.showX(); // X = 100, Y = 99 object2.showX(); // X = 200, Y = 99 } static void showY() { System.out.println(y); // 99 System.out.println(M7L2.y); // 99 System.out.println(this.y); // Rejected, as there is no this in static methods System.out.println(x); // Rejected, as x is not a static variable System.out.println(this.x); // Rejected, as there is no this in static methods } void showX() { System.out.println(x); System.out.println(y); }
Lesson 3: Create and overload constructors; including impact
on default constructors
3.1 Creating and overloading constructors
What is a constructor?
class Thing { Thing() {...}
Capitalization and spelling must be exact match
No return type (not even void)
We can pass normal argument lists
pg. 82
SKILLCERTPRO
We can provide accessibility specification, e.g. private, public...
We can provide a body if desired
To invoke the structure, we just use new Thing(<argument list>);
When we call new, the code does not jump straight into the body, there are a few
things first
o An object is created (memory allocated)
o If there is a parent class, the constructor for that will be called, this bubbles all
the way up to the parent class: java.lang.Object
o Instance initialisation is performed
o The constructor called runs
We are allowed to overload based on normal overloading rules
3.2 Differentiating between default and user defined constructors
class Thing { public Thing() { super(); } }
If we do not provide our own constructor, the compiler will create one for us,
the default constructor
Takes no arguments
Body just calls superclass constructor, which takes no arguments
If the superclass does not have this constructor, it errors
This constructor accessibility is the same as the class
o One exception: an enum always have private constructor (not on exam)
Lesson 4: Apply access modifiers
#### 4.1 Using the access modifiers public and private
public - accessible anywhere in program
private - visible inside the top level enclosing curly braces that surround its
declaration
o Aceessible to other classes, where we have class nesting
4.2 Using default access and the protected modifier
default - visible inside package
o we do not need to define, automatically default
protected - visible inside package and and subclasses
pg. 83
SKILLCERTPRO
Lesson 5: Apply encapsulation principles to a class
5.1 Designing for encapsulation
Ensure all member variables of a class are private
Best practice: allow modification of public variables, throwing Error if it's not updated
correctly
We use modifiers to seperate concerns between internal interactions and external
APIs
#### 5.2 Implementing encapsulation
Encapsulation helps us to know ehre to go in order to debug. It should also help
show to intended users to these classes that not part of the general API for use by
everyone.
We can make immutable objects final, just for clarity
public class Thing { private int x; public static final int y = 2; public static final String s = "Hello"; private static int z; private void modifyUtility() { ...; } void doStuff(AnyType a) { // validate here // throw error if invalud } }
Lesson 6: Determine the effect upon object references and
primitive values when they are passed into methods that
change the values
6.1 Changing values through method local variables
int x = 99; // 99 StringBuilder sb = new StringBuilder("Hello"); addOne(x); // 99 System.out.println(x); // 99 addOne(sb); System.out.println(sb); // "Hello world" void addOne(int x) { // x is copied to this variable, so the local variable ceases to exist x++; // 100
pg. 84
SKILLCERTPRO
System.out.println(x); } void addOne(StringBuilder sb) { sb.append(" world"; System.out.println(sb); }
Primitive values contain the values they represent
Non primitive (reference) values represent a reference to an object
o We do not change the reference to the object, rather the object being
referenced
6.2 Changing the value of method local variables
All method arguments are passed by value
All method local variables are copied
o Primitives have a completely independent copy of the value
o Changing a local variable with primitive type cannot change the original
o Objects pass the pointer to object
o If we change this object referred to, it's visible through all references
If we change the value in a method local variable to point to a different object, we do
not see the change in the caller
6.3 Code example
package m7l8; public class M7l8 { public static void add(int x) { x++; System.out.println(x); } public static void add(StringBuilder sb) { sb.append(" world"); System.out.println(sb); } public static void change(StringBuilder sb) { sb = new StringBuilder("Auf Wiedersehen!"); System.out.println(sb); } public static void main(String[] args) { int x = 99; add(x); System.out.println(x); // 99 Stringbuilder sb = new StringBuilder("Hello"); add(sb);
pg. 85
SKILLCERTPRO
System.out.println(sb); // "Hello world" sb = new StringBuilder("Hello"); change(sb); System.out.println(sb); // "Hello" }
Module 8: Working with Inheritance
Lesson 1: Describe inheritance and its benefits
1.1 Understanding interface and implementation inheritance
A key concept of Object-Orientated programming is generalization, allowing us to
specify a base implementation, and allowing us to build on top of this
with specialization. This refers to the concept that specialization is just reverse-
generalization.
We can call this specialization two things:
Interface Inheritance
o Making or fullfilling a promise
o Contract to describe certain capabilities - subclass provides everything the
parent has, and can be more
o The parent class does not have to describe how each capability is coded
Implementation inheritance
o We specify code about how methods work in the parent class
o Anything we can do in parent, we can do in subclass
o We can modify behaviour provided by parent
1.2 Basic coding of implementation inheritance
class Thing { ... stuff ... } class SpecialThing extends Thing { ... stuff .. // from 'Thing' ... extended stuff of our own ...
1.3 Changing inherited behaviour
We can annotate with @override
To change behaviour, we need a class with the same name and an identical argument
list
pg. 86
SKILLCERTPRO
We need to make sure to override, rather than overload
class Thing { public void sayHello() { System.out.println("Hello"); } } class SpecialThing extends Thing { public void sayHello() { System.out.println("Bonjour"); } }
The method cannot be less accessible
It must be available in all the places the original method would have been
accessible
If we have a primitive return type, the override method must return the same
type
If we have an Object return type, we can return an object which is a subclass of
the type originally defined
1.4 Code examples
package m8l1b; public class Person { private String name; public String getName() { return name; } public void greet() { System.out.println("Hello " + name); } public Person(String name) { this.name = name; } } public class Friend extends Person { private String relationship; public Friend(String name, String relationship) { super(name); this.relationship = relationship; }
pg. 87
SKILLCERTPRO
public void haveRelationship() { System.out.println("Relationship with " + name); } @Override public void greet() { System.out.println("Hello " + name + " my " + relationship); } }
1.5 Philosophy and terminology of inheritance (part 1)
Encapsulation means the data members of an object should be manipulated only by
methods defined in that object. We do this by ensuring member variables are
marked private. Data integrity should be codified.
A well designed object should have carefully thought out paradigms, such as
constructors and static values to ensure it can be created correctly.
Specialization is the opposite of Generalization
Liskov Substitution is the idea that the specialized form must be a perfect substitute
for a generalized form
Interface inheritance differs from implementation inheritance in that no
implementation gets reused, the class implementing an interface does not gain
member fields or methods as default.
Interfaces promise behaviours
We are not allowed multiple implemetation inheritances, for sake of clarity
1.6 Philosophy and terminology of inheritance (part 2)
While overriding can change semantics of a method, it's not possible to remove
definition of a method.
Return type must be the same
The method must not be less accessible
The method may not throw checked exceptions that would have been illegal from the
base class
Polymorphism is the ability to look at something in multiple ways. It describes the
ability to look as the specialized form of something as the generalized thing.
Sometimes when we create private member variables, we can
use getters and setter to mutate these variables. class Thing { private String name;
pg. 88
SKILLCERTPRO
public String getName() { return name; } public void setName(String n) { name = n; } }
### Lesson 2: develop code that demonstrates the use of polymorphism
#### 2.1 Understanding the concepts of polymorphism
class Animal class Dog extends Animal Animal a = new Dog(); Animal[] zoo = new Animal[100]; zoo[0] = new Tiger(); zoo[1] = new Lion(); public void feed(Animal a) ... Dog d = new Dog(); feed(d); for (Animal a: zoo) { feed(a); }
#### 2.2 Code example
package m8l2; public class Animal { public String getName() { return "Unknown"; } public String eats() { return "Unknown"; } public void eat(String food) { System.out.println("Nom"); } } public class Lion extends Animal { private static final String FAV_FOOD = "Vegan"; @Override public String getName() { return "Larry"; } @Override public String eats() {
pg. 89
SKILLCERTPRO
return FAV_FOOD; } } public class Dog extends Animal { @Override public String getName() { return "Woofles"; } @Override public void eat(String food) { System.out.println("Nom Nom Nom Woof"); } } public class ZooKeeper { public void feedAnimals(Animal [] animals) { for (Animal a : animals) { String name = a.getName(); String food = a.eats(); System.out.println(name + " likes " + food); } } }
#### 2.3 Understanding the core teminology of polymorphism
A class can only have a single parent class, but that parent can have parents
Parent classes
o Base class
o Super class
o Generalization
o Interface
o Contract
Child class
o Derived class
o Sub class
o Specialization
We can either use extends for implementation inheritance, or implements for interface
inheritance
pg. 90
SKILLCERTPRO
2.4 Understanding variable type and object type
The type of the object may be the same type as the variable, or the type of the object
may be a specialization of the type of the object (subclass or implementation of an
interface).
If you invoke behavior on a variable, the compiler will use the type of the variable, or
it might be an expression actually, to determine whether or not that method is
possible for the things that variable might refer to
2.5 Determining object type
We can use two methods to find out class of object at runtime:
.getClass() method
instanceof type
2.6 Code examples
private static void showAnimalType(Animal a) { Class theClass = a.getClass(); String className = theClass.getName(); Class parentClass = theClass.getSuperClass();
Lesson 3: Determine when casting is necessary
3.1 Understanding the Liskov substitution principle and the "is a" relationship
SomeType t = aThing;
The thing your assigning must substitute seamlessly into the thing you're assigning
to
If type of aThing is SomeType, we do not need to cast
o If SpecialSubtype extends SomeType, we can
say SpecialSomeType implements SomeType
Animal a = theDog; // OK! Dog d = a; // ? /* * This is not true if Animal a = theCat; * We use: * Dog d = (Dog) a; * * This will compile OK, but throw a ClassCastException at runtime */
pg. 91
SKILLCERTPRO
3.2 Recognizing impossible assignments
There are some circumstances where assignments are not possible, e.g:
Animal a = theCactus; // Animal and cactus have no relation to each other Animal b = (Dog) theCat; // Sometimes allowed at runtime
The assignment may be possible if the reverse assignment could have also been
possible
3.3 Understanding casting with interface types in assignments
If we have:
Animal (class), with Tiger and Puppy
Pet interface, with Puppy and Rock
Animal a = (Animal) thePet;
If thePet was Puppy, this assignment is ok, but if it is Rock, then this is cannot be done,
and will throw a Runtime exception. Tiger t = (Tiger) thePet;
We do not need to cast this, but the assignment works anyway.
Where interfaces are concerned, providing we use a cast, the compiler will almost
always permit the assignment.
When final is used, we cannot create any subclasses of this class, this will reject any
assignments that would have been permitted without the final decleration.
Lesson 4: Use super and this to access objects and constructors
4.1 Understanding "this" for accessing object features
When we declare a variable and use it to refer to an object, this is a pointer to an
object. We can invoke a method by calling this reference.
Under these circumstances, code invoked by the instance of the object can be called
with this
The keyword this, which provides an explicit reference to the current context object.
4.2 Understanding "super" for accessing parent features
Using super makes the code instantiation look inside the parent class for the scope
class Base { int x; String getMessage() { return "Hello";
pg. 92
SKILLCERTPRO
} } class Derived extends Base { int x; public void method(int x) { super.x = 100; // Base x } String getMessage() { return "Hello" + "everyone!"; } // Instead of the above we can use: String getMessage() { return super.getMessage() + "everyone!"; } }
4.3 Understanding "this()" for accessing overloaded constructors
class Thing { private int x; public Thing() { x = 99; } public Thing(int x) { this.x = x; } }
Intead of the above, we should use:
class Thing { private int x; public Thing() { this(99) } public Thing(int x) { this.x = x; } }
Transfer control to another method for this class that takes a matching argument
Instantiates method, calling default/overloaded constructors
4.4 Understanding "super()" for accessing parent constructors
A constructor is a special method to set up an object immediatlely after using new to
instantiate an object
pg. 93
SKILLCERTPRO
class Base { int x; Base(int x) { this.x = x; } } class Sub extends Base { int y; Sub(int x, int y) { super(x); this.y = y; } Sub(int y) { this(y, 100); } }
If we use super() to pass control to a parent class constructor, it must be the first
thing that happens in the constructor
We cannot construct a subclass without initialising the base class
o It always assumes super(); (no arguments)
4.5 Understanding the underlying principles of "this" and "super" for invoking other
constructors
Each subclass if built omn top of the parent class (with java.lang.Object being the
foundation)
It implicitly runs super() going foundations-upwards - if no constuctor matching this
signature is provided, we will receive a compiler error
We must call this or super first, we can choose one or the other
o super() always takes priority
4.6 Code examples
Sub(int x, int y) { super(this.calcValue(y)); // This is not allowed, as we need to initialise base class first } Sub(int x, int y) { super(Sub.calcValue(y)); // This is allowed, as calcValue is static }
Lesson 5: Use abstract classes and interfaces
5.1 Preventing instantiation
Once we have declared a class as being abstract, we will not be permitted to make an
invocation of new on that class directly.
pg. 94
SKILLCERTPRO
abstract lets us define constructors for classes which are accessible but prevent
those constructors from being called in any way other than by subclasses (by
using super())
5.2 Marking behaviours abstract
abstract class Animal { abstract String likesToEat(); }
Concrete classes must define implementation for this method likesToEat
All subclasses must either be abstract or define constructors for all abstract methods
5.3 Understanding the rules about abstract classes and methods
We can define constructors in abstract classes, and although they will not be called
by new, they can be called by super in subclasses
An abstract method can never be defined as private (it needs to be visible to the
subclass)
We cannot label an abstraxct method as final, as we want it to be overloaded in
subclasses to fulfill the promise of the contract
Abstract class needs not have abstract methods (can have concrete methods)
If we have a concrete class, we cannot declare abstract methods
If we have an abstract class but cannot implement all abstract methods in parent
class, this must be marked as abstract
5.4 Understanding and defining interfaces
We can have an interface with zero methods in
public interface Photographer { Image takePhoto(); int x = 99; // This does not create a variable int x; // Illegal, we need to define value }
All methods in an interface are public abstract (whether we say so or not)
All fields are public static final (initialisation must be immediate)
5.5 Implementing and using interfaces
We can implement more than one interface for a class, by providing a comma
seperated list
The extends clause preceeds the implements clause
Interfaces provide the ultimate in design for minimum knowledge
pg. 95
SKILLCERTPRO
5.6 Code example for interfaces
class Flyer { takeOff() } class Photographer { takePhoto() } class SpySatellite extends Asset implements Flyer, Photographer { public void takeOff(){...} public Image takePhoto(){...} }
5.7 Understanding the rules about interfaces
All methods in interfaces are public and abstract, but never final
Fields in interfaces are public, static and final
Constants in java should be ALL_UPPER_CASE
We are allowed interfaces which are specialisations of other interfaces by
using extends
5.8 Understanding static and default methods
A default method is an inheritable overridable instance method defined in an
interface, letting us have multiple implementation inheritance
Any method defined in an interface creates an obligation for every class that
implements that interface (that class must provide an implementation of the method)
default should only be used as a fallback
Module 9: Handling Exceptions
Lesson 1: DIfferentiate among checked exceptions,
RuntimeExceptions and Errors
1.1 Understanding exception types
Checked Exceptions -> Problems with the environment, e.g. user input
o We should write code to attempt to fix it
Unchecked Exceptions -> Should not happen
o RuntimeException
Errors (part of Unchecked) -> Problems external to the program
pg. 96
SKILLCERTPRO
o OOM (catastrophic)
Throwable -> Error Throwable -> Exception -> RuntimeException -> IndexOutOfBoundsException
Lesson 2: Create a try-catch block and determine how
exceptions alter normal program flow
2.1 Coding try and catch
try { ... ... } catch(IOException ioe) { ... } catch(OtherException oe) { ... }
#### 2.2 Passing an exception to our caller
We must admit to caller that checked exceptions can happen
public void authorizeCC(Card c, int amt) throws CCFailedException, OtherException { try { ... } catch( ____ ) { throw new CCFailedException(); } }
2.3 Using finally to clean up resources
Finally block is always executed:
Socket s; try { ... } catch( ___ ) { } finally { if (s != null) s.close(); }
We might not complete execution of finally block if we encounter an unchecked
exception
2.4 Using the try with resources mechanism
try ( Socket s = x.connect(); InputStream is = y.open();) {
pg. 97
SKILLCERTPRO
... } catch ( ___ ) { ... } }
All resources declared and initialised within the try block will be closed
The system does all checking to see if variables are null or not
We can still add a finally block of our own
We must declare and initialise variables in this block (as many as we want), seperated
by semicolons (last semicolon is optional)
We are allowed the following normally:
try + catch
try + finally
try + catch + finally
And with try with resources:
try
try + catch
try + finally
try + catch + finally
2.5 Code example for try / catch / finally
try { System.out.println("In try"); if (Math.random() > 0.5) { throw new FileNotFoundException(); } } catch (FileNotFoundException fnfe) { System.out.println("In catch"); }
2.6 Code example for try with resources
try (MyResource r = new MyResource();) { System.out.println("In try"); } catch (IOException ioe) { System.println("Close failure?"); } finally { System.out.println("Explicit finally"); }
Lesson 3: Describe the advantages of Exception handling
pg. 98
SKILLCERTPRO
3.1 Investigating the philosophy of the exception mechanism
Checked
o Can and should repair in code
Unchecked
o Usually catastrophic
RuntimeException
o We should debug these
4.1 Handling exceptions throw by called code
To handle an unchecked exception, we should wrap the code in a try block catching
either the specific exception or a parent class of that type
We should declare when exceptions are going to be throw in a method
4.2 Code example
public static void broken() throws AskForNewFilenameException { System.out.println("Starting"); boolean success = true; int retriesLeft = 2; while (!success) { try { System.out.println("In try"); if (Math.random() > 0.5) { System.out.println("Failed"); throw new FileNotFoundException(); } success = true; System.out.println("Success"); } catch (FileNotFoundException) { System.out.println("In catch"); if (0 == retriesLeft--) { System.out.println("Too many retries"); throw new AskForNewFilenameException(); } } finally { System.out.println("In finally"); } }
Lesson 5: Recognize common exception classes (such as
NullPointerException, ArithmeticException,
ArrayIndexOutOfBoundsException, ClassCastException)
5.1 Common Exception Classes
AssertionError
o Thrown by assert keyword (disabled by default for performance reasons)
pg. 99
SKILLCERTPRO
OutOfMemoryError
o Run out of memory
StackOverflowError
o Result of runaway recursion
IOException
o General input/output failures
SOAPException
o SOAP based web services call
SQLException
o Problems with databases
URISyntaxException
o Using HTTP and make malformed representation of resource trying to reach
XMLParseException
o Processing XML document
ArithmeticException
o Integer division of divide by zero
ArrayStoreException
o Putting wrong type of object in array
ClassCastException
o Casting invalid class
IndexOutOfBoundsException
o Tried to read non existant index
NullPointerException
o Object referred to as an unitialised object
Module 10: Working with selected classes from the
Java API
Lesson 1: Manipulate data using the StringBuilder class and its
methods
#### 1.1 Understanding the common StringBuilder constructors
String is a fundamental type built into a compiler, we can easily represent text
which can change easily using a StringBuilder (String is immutable)
StringBuilder Contructors
o public StringBuilder String s) o public StringBuilder(CharSequence cs) o public StringBuilder(int i) o public StringBuilder()
pg. 100
SKILLCERTPRO
The StringBuilder is able to automatically reallocate it's array, we should ensure the
StrinbBuilder is instantiated with a large enough size of storage array (by passing an
int) - start size is 16
If looking at worst case scenarios, we should pick smaller sizes and let the compiler
optimize
1.2 Using methods that modify StringBuilders
StringBuilder sb1 = new StringBuilder("Hello"); sb1.append(true); sb1.append(234); sb1.delete(7, 11); // First character to delete - First character after block to be deleted sb1.reverse(); sb1.setCharAt(2, 'A'); sb1.setLength(12); // Can be used to trunkate if shorter, else it will be oadded with `0` characters
1.3 Using methods that read and search in StringBuilders, and using methods that interact with
the internal storage of StringBuilders
We can use substring to read part of a StringBuilder
These do not change the text in the string buffer
They return new objects
StringBuilder sb = new StringBuilder("Yo"); sb.substring(0, 2); // Reads from 0 to 1 sb.charAt(3); // Returns char at index sb.getChars(3, 7, dest, 4); // First 2 is region to extract, 3rd is char array for the characters to be placed, the fourth is an offset into that array. sb.indexOf('yo'); // Returns index of start of parameter passed in sb.indexOf('yo', 7); // Same, but skips over leading characters sb.lastIndexOf('woo'); // Starts from back // These all return `-1` if value cannot be found sb.length(); // Length of array sb.ensureCapacity(int); // Grows the capacity to specified size (using multiple hops) sb.trimToSize(); // Ensures no memory wasted, will reallocate buffer