Zaawansowane programowanie obiektowe Lecture 2 Szymon Grabowski sgrabow@kis.p.lodz.pl http://szgrabowski.kis.p.lodz.pl/zpo11/ Łódź, 2011 Obfuscated code in Java? Why not... ( from J.Bloch & N.Gafter, Java Puzzlers: Traps, Pitfalls, and Corner Cases ) class PrintQuirks { static public void main(String[] args) { System.out.println( 'A' ); System.out.println( 'A' + 'B' ); } } Output: A 131 http://www.cs.armstrong.edu/liang/intro8e/studentcommonerrors.html 2 Inheritance An inherited class “extends” its parent. For example, the class Vehicle may have the following descendants: Car, Bike or Tank. New fields possible like Terminology: int number_of_doors in Car. superclass, New methods possible like base class, void loadMissile() in Tank. parent class public class Car extends Vehicle { int number_of_doors; ..... subclass, } derived class, extended class, child class 3 Hierarchy can be long, of course class Vehicle { ... } class Tank extends Vehicle { ... void loadMissile() { ... } // it wasn’t in the parent class } class Rudy102 extends Tank { ... void feedTheDog(byte germans) { ... } // it wasn’t in the parent class } 4 Inheritance, cont’d All non-private methods from the parent class are present in the child class. You can inherit from a single class (as opposed to C++). All Java classes are derived from the class Object. Constructors in the child class should call explicitly the constructor of the parent class. Keyword super. public class Vector3D extends Vector2D { .... public Vector3D(int x, int y, int z) { super(x,y); // calling the parent constructor this.z = z; // setting a remaining field } } 5 Creating an object of a derived class (what goes on) 1. The subclass constructor is launched. 2. If the first instruction in the constructor is super(args), then the superclass constructor is run, with arguments args. Remember: if super(args) is invoked in the subclass constructor, it must be its first instruction. 3. If no super(...), then the zero-argument constructor of the superclass is run. 4. The lines of the subclass constructor are executed. 6 Keyword final once more final class X { ... } means that X cannot be extended (for example, String class is final) final int someMethod(...); means that someMethod(...) cannot be overridden Terminology: don’t confuse (method) overloading and overriding! Overloading a function: same name but a different list of params. Overriding a function: same signature but in some descendant class. 7 final, cont’d final int[] a = { 1, 2, 3, 4 }; a[0]++; // OK ??? Yes. The reference is final (cannot be changed), not the pointed object. Therefore, of course, a = b; would be erroneous. Blank finals private final int i = 0; // Initialized final private final int j; // Blank final Value must be assigned to a blank final in every constructor. Why blank finals? Since they provide flexibility: a final field inside a class can now be different for each object. 8 Constant stuff No constant methods. I.e. everything may change the object. Method name convention: getMember: an accessor (getter) setMember: a mutator (setter) Constant instance fields: with final keyword. A constructor (of a given class or some ancestor class in the hierarchy) must set them to a value, and then it is fixed. Final arguments: e.g. void fun(final int j) { j++; } // j is read-only 9 Polymorphism, virtual methods A method that can be overridden = virtual method. (In Java, there’s no extra keyword.) Polymorphism: one name, many forms. Three distinct forms of polymorphism in Java [http://www.developer.com/tech/article.php/966001]: compile-time • method overloading; polymorphism • method overriding through inheritance; • method overriding through the Java interface. run-time polymorphism 10 Polymorphism, simple example (based on [Barteczko’04], pp. 304–305) class Car extends Vehicle { ... } ... Car c = new Car(...); Vehicle v = c; // ! v.start(); // start() from Vehicle overridden in Car Can the compiler (javac) know it should run start() from the class Car rather than Vehicle? Perhaps in this example, yes. But not in general. 11 Polymorphism, cont’d (based on [Barteczko’04], pp. 304–305) Consider this: public static void main(String args[]) { Car c = new Car(...); Motorcycle m = new Motorcycle(...); // Motorcycle also extends Vehicle Vehicle v; if (args[0].equals("Jawa")) v = m; else v = c; v.start(); // can the compiler know what is v ?!?! } (Run-time) polymorphism implies late binding. 12 (Almost) all methods in Java are virtual Methods that cannot be redefined: • static ones; • methods with final keyword (of course...); • private methods. Performance problems? (Yeah, probably.) Interview with Anders Hejlsberg, the lead C# architect ( http://www.artima.com/intv/nonvirtual.html ) Q: Why is non-virtual the default in C#? A: There are several reasons. One is performance. We can observe that as people write code in Java, they forget to mark their methods final. Therefore, those methods are virtual. Because they're virtual, they don't perform as well. There's just performance overhead associated with being a virtual method. (...) 13 What is derived from the Object class [ http://www.developer.com/tech/article.php/966001 ] The class Object defines default versions of the following methods: • clone() • equals(Object obj) • finalize() Every class inherits • getClass() them, • hashCode() and can override • notify() (the non-final ones). • notifyAll() • toString() • wait() • wait(long timeout) • wait(long timeout, int nanos) 14 equals for Object class (i.e., default implementation) The equals method for class Object is comparison of references; more precisely: for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). 15 equals [ based on J. Bloch, Effective Java, 2001, Chap. 3. http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf ] Overriding equals – when NOT to: • class instances are inherently unique (e.g. Thread), • testing for equality makes little sense (e.g. Random), • a superclass overrides equals and its implementation is satisfactory (e.g. most Set implementations inherit equals from AbstractSet). NOTE, HOWEVER: if you are sure equals will never be invoked, then you should override it! Like this: public boolean equals(Object o) { throw new UnsupportedOperationException(); } 16 Overriding equals, the contract [ based on J. Bloch, Effective Java, 2001, Chap. 3 ] equals should be • reflexive, i.e. x.equals(x), • symmetric, i.e. x.equals(y) ↔ y.equals(x), • transitive, i.e. x.equals(y) && y.equals(z) → x.equals(z), • consistent: multiple equals invocations on the same x, y should return the same, provided no info used in in equals comparisons on the object is modified, • x != null → x.equals(null) == false 17 Overriding equals, why symmetry? [ based on J. Bloch, Effective Java, 2001, Chap. 3 ] Let’s have a class for strings with case-insensitive equality test. String is final, but we can use composition instead of inheritance: public final class CaseInsensitiveString { private String s; .... // some new cute methods, working on s } 18 Overriding equals, why symmetry? (cont’d) [ based on J. Bloch, Effective Java, 2001, Chap. 3 ] 19 Overriding equals, why symmetry? (cont’d) [ based on J. Bloch, Effective Java, 2001, Chap. 3 ] cis.equals(s) returns true s.equals(cis) returns false no symmetry OK, no symmetry, but so what? Now let’s have a list collection... List list = new ArrayList(); ...and add cis to it: list.add(cis); What does list.contains(s) return? Returns false. (Bloch claims it depends on Java implementation, hmm?) 20 Always override hashCode when you override equals 21 Abstract classes Abstract class – cannot have instances (objects). Methods can also be abstract (no definition). Abstract methods – only in abstract classes. But not all methods in an abstract class have to be abstract. public abstract class Shape { } What for? To have a common design for inherited classes. 22 Can an abstract class have a constructor? Yes. But don’t make it / them public. (It’s not forbidden, only pointless…) 23 http://stackoverflow.com/questions/260666/abstract-class-constructor-in-java Interfaces An interface is an abstract class which has only abstract methods. Using an interface: a class promises to implement all the methods declared in a given interface. interface Barkable { void bark(); void barkLoud(); void howl(); void whine(); } class Dog implements Barkable { void bark() { ... } ..... } 24 Interfaces, cont’d Interfaces declare public abstract methods (hence the words public, abstract are redundant). Interfaces may also store static constant fields. (Again, the words final static are not necessary.) Interface implementation: a class implementing all the interface methods (and now the word public is required). 25 Interfaces, example (based on [Barteczko’04]) 26 Interfaces in real world – e.g. CharSequence [http://java.sun.com/j2se/1.4.2/docs/api/java/lang/CharSequence.html] The public interface CharSequence is implemented by CharBuffer, String, StringBuffer. A CharSequence is a readable sequence of characters. This interface provides uniform, read-only access to many different kinds of character sequences. Its methods: char charAt(int index) int length() CharSequence subSequence(int start, int end) String toString() 27 Is it safe? [ http://www.manning-source.com/books/forman/forman_chp5.pdf ] 28 It isn’t safe 29 Now it’s safe [ http://www.manning-source.com/books/forman/forman_chp5.pdf ] TimeIntervalImpl2 makes defensive copies in both the constructor and the accessors, which means that no outside object holds a reference to the parts of the time interval. 30 Adapters Sometimes we really care for implementing only some (few) methods from an interface. But the language rules require implementing all of them. Some implemented methods can thus be “dummy” – but they must appear. Tedious, boring. An adapter is a class that implements an interface, with empty definitions for all of the functions. The idea is that if we subclass the adapter, we will only have to override the functions that we are interested in. 31 Adapters, example interface R2D2 { String display(); String show(); int calculate(int a, int b); float generate(); double mean(); } abstract class R2D2Adapter implements R2D2 { public String display(){return "";} public String show(){return "";} public int calculate(int a, int b){return 0;} public float generate(){return 0.0f;} public double mean(){return 0.0d;} } 32 Adapters, example, cont’d public class Robot extends R2D2Adapter { public String display() { String s = "Adapting R2D2 to Robot"; System.out.println(s); return s; } public static void main(String args[]) { Robot r = new Robot(); r.display(); } } 33 Legal assignments, casts [ members.tripod.com/~psdin/comlang/basicJava.PDF ] refOfSuper = refOfSub is valid // refOfSub = refOfSuper is not valid: compile error (even when the refOfSuper really refers to the sub object) refOfSub = (Sub) refOfSuper is valid may cause ClassCastException at run-time if - refOfSuper actually refers to a super object, - refOfSuper refers to object of another subclass of that super class 34 Reference assignment rules [ members.tripod.com/~psdin/comlang/basicJava.PDF ] (Enforced at compile-time.) SourceType srcRef; DestinationType destRef = srcRef; If SourceType is a class type, then - either DestinationType is a superclass of SourceType; - or DestinationType is an interface type which is implemented by the class SourceType. 35 Reference assignment rules, cont’d [ members.tripod.com/~psdin/comlang/basicJava.PDF ] If SourceType is an interface type, then - either DestinationType is Object; - or DestinationType is a superinterface of subinterface SourceType. If SourceType is an array type, then - either DestinationType is Object; - or DestinationType is an array type, where the element type of SourceType can be converted to the element type of DestinationType. 36 Assignments and casts – example [ members.tripod.com/~psdin/comlang/basicJava.PDF ] class A{ } class B extends A{ } class C{ } public class Class1 { public static void main(String[] args) { A a; B b; C c; a = new A(); b = new B(); // b = (B)a; // ok? WRONG. Will throw java.lang.ClassCastException. a = b; // ok? OK. a ref to subclass B object. // b = a; // ok? WRONG. Compile error; can't implicitly convert. // c = (C)a; // ok? WRONG. Compile error; can't convert A to C. b = (B)a; a = new A(); 37 // b = (B)a; // ok? WRONG. java.lang.ClassCastException. Shadowed variables [ members.tripod.com/~psdin/comlang/basicJava.PDF ] A variable in a subclass shadows an inherited variable if both have the same name. class A { int x; ... } class B extends A { int x; ... } How to distinguish them? Easily. In the child class: use x or this.x for x from this class, and super.x or ((ParentClass)this).x to for the shadowed x. Outside both classes: cast an object to the appropriate type. 38 Wrapper classes [ http://www.jchq.net/certkey/0803certkey.htm ] Wrappers are classes that wrap up primitive values (e.g., integers, doubles) in classes that offer utility methods to manipulate the values. What for? Say, you want to have a Vector (from java.util) of integers but the Vector class can only store objects, not primitive type entities. 39 Wrapper classes, example [ http://www.jchq.net/certkey/0803certkey.htm ] import java.util.*; public class VecNum { public static void main(String argv[]) { Vector v = new Vector(); v.add(new Integer(1)); v.add(new Integer(2)); for (int i=0; i < v.size(); i++) { Integer iw =(Integer) v.get(i); System.out.println(iw.intValue()); } } } 40 Wrapper classes, cont’d [ http://www.janeg.ca/scjp/pkglang/wrapper.html ] The wrapper classes are in java.lang (imported by default, no need to type import...) • one for each primitive type: Boolean, Byte, Character, Double, Float, Integer, Long, and Short, • Byte, Double, Float, Integer and Short extend the abstract Number class, • all are public final, i.e., cannot be extended, • get around limitations of primitive types. 41 Wrapper classes, cont’d [ http://www.janeg.ca/scjp/pkglang/wrapper.html ] Selected methods All except Character: valueOf(String s). Integer, Short, Byte, Long: parseType methods, eg. parseInt(), parseShort(), etc. that take a String and parse it into the appropriate type. Integer and Long: also have the static methods toBinaryString(), toOctalString() and toHexString() which take an integer value and convert it to the appropriate String representation. Character: public static int digit(char ch, int radix), public static int getNumber(char ch), public static char toLowerCase(char ch)... 42 Wrapper classes, examples Integer i = new Integer(20); byte b = i.byteValue(); ... double d = Double.parseDouble("3.14"); ... int i = Integer.parseInt("10011110",2); what can we deduce from this notation..? Simple question [http://java.sun.com/developer/technicalArticles/Interviews/bloch2006_qa.html] Finite or infinite loop? for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) doSomething(i); 43 Beware... Integer[] arr = new Integer[100]; // OK? It’s not finished. Created an array of 100 references to Integer objects, not the objects themselves. Trying to access arr[i] will throw an exception. So, after the line above, write e.g. arr[0] = new Integer(30); arr[1] = new Integer(rand.nextInt(100)); .... 44 Static factory methods [ J.Bloch, Effective Java] The standard way for a class to allow a client to obtain an instance is to provide a public constructor. There is an interesting alternative though: a public static factory method: a static method that returns an instance of the class. Simple example (Java 1.4+): public static Boolean valueOf(boolean b) { return (b ? Boolean.TRUE : Boolean.FALSE); } 45 Static factory methods, cont’d Less obvious example: BigInteger.probablePrime(...) – returns a BigInteger object which, with high probability, represent some prime (with length in bits acc. to passed parameter) Why factor methods instead of constructors? 1. They have names so can be easier to use / read. 2. They may return a reference to a readily-built object (no time/space then wasted for yet another object...). 3. They can return object of a subclass (any subtype of their return type). 46 Static factory methods, cont’d A drawback of static factory methods: they’re less ‘visible’ in API (javadoc) documentation. Naming conventions: valueOf – mostly for type conversions. Such a function returns an instance that has, loosely speaking, the same value as its parameters. getInstance – returns an instance described by its parameters but not having the same value. E.g., in the case of singleton classes, it returns the sole instance. 47 Static factory methods are often more readable (than constructors) 48 http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java null stuff [ based on http://norvig.com/java-iaq.html ] Is null an object? No. Because (null instanceof Object) is false. Can I call a method on null, like x = null; x.m(); ? No (if m is a non-static method). There is a single null, not one per class, i.e. for example ((String)null == (Date)null). 49 Exceptions Exception = some unexpected run-time erroneous situation. ...Or let us give the Sun official definition (from java.sun.com): An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Examples: trying to open a non-existent file, division by zero. Exceptions are raised (thrown). Exceptions are handled. Exceptions in Java are objects from exception classes. Exception names are actually class names. Class hierarchy starts from Throwable. 50 Exception handling basics When an erroneous situation happens, it is impossible to continue the current program execution “context” (eg. if the resulting value x cannot be obtained because of div by 0 error, how could we continue calculations with x? If a file cannot be open, how can we later read from it or so?). Now the exception handling mechanism takes control. 51 Simple method, high level look [ http://www1.cs.columbia.edu/~lok/3101/lectures/04-softwareeng.pdf ] readSomeDevice { open the device figure out how much to read create our destination object actually do the reading close the device } 52 Traditional approach [ http://www1.cs.columbia.edu/~lok/3101/lectures/04-softwareeng.pdf ] errno readFile() { int errorCode = 0; open the file; if (theFileIsOpen) { // determine file length if (gotTheFileLength) { // allocate memory; if (gotEnoughMemory) { // read the file if (readFailed) { errorCode = -1; } } else { errorCode = -2; } } else { errorCode = -3; } close the file; if (fileNotClosed && errorCode == 0) { errorCode = -4; } else { errorCode = errorCode and -4; } } else { errorCode = -5; } return errorCode; } 53 Exception approach [ http://www1.cs.columbia.edu/~lok/3101/lectures/04-softwareeng.pdf ] readFile() { try { open the file; determine its size; allocate that much memory; read the file into memory; close the file; } catch (fileOpenFailed) { doSomething; } catch (sizeDeterminationFailed) { doSomething; .......... } catch (fileCloseFailed) { doSomething; } } 54 Exception class hierarchy fatal errors are here 55 java.lang.Error, java.lang.RuntimeException [ members.tripod.com/~psdin/comlang/basicJava.PDF ] java.lang.Error: • LinkageError, VirtualMachineError, AWTError, ...; • usually irrecoverable; • don't try to catch ’em. java.lang.RuntimeException: • ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException, ... • often due to programmatic errors, rather than special runtime conditions. 56 Checked vs. unchecked exceptions [ members.tripod.com/~psdin/comlang/basicJava.PDF ] Unchecked exceptions: RuntimeException, Error, and their subclasses. A method is NOT oblidged to deal with them. Checked exceptions: those which are not unchecked. You HAVE TO catch them: either directly in the method in which the exception occurs, or pass on the method that can throw a checked exception (directly or undirectly), to its caller. 57 Exception stuff keywords try { ... } – specifies a block of code that might throw an exception catch (ExceptionClass e) { ... } – exception handler; handles the type of exception indicated by its argument finally { ... } – this block always executes when the try block exits throw someThrowableObject – simply throws a given exception public void someMethod() throws SomeException { ... } – specifies what someMethod() can throw. A method can only throw those checked exceptions that are specified in its throws clause. 58 Exception handling, basic scheme int a, b, c; String s; try { /* in the try block we keep the code lines that can cause an exception */ a = b/c; // if e.g. c==0, then ArithmeticException will be raised // CAVEAT: not for floating-point number division! // 1.0 / 0.0 --> Infinity !!! s = Integer.toString(a); } catch(ArithmeticException ex) { // exceptions are handled in a catch block s = "*" ; } 59 A few notes After one try { ... } block, there can be many (disjoint) catch { ... } blocks. Each catch { ... } works like a mini-method: accepts only a single parameter of a specific exception type. try { // here can be fires, floods, plane hijacks and other disasters } // nothing in between catch(type1 id1) { // id1 exception handling, e.g. evacuate people } catch(type1 id2) { // id2 exception handling, e.g. extinguish fire } ... 60 How to catch smartly The order of catch blocks DOES matter. The execution goes (only) to the first catch block that fits the occurring exception. Many might fit! The conclusion is therefore: first specify more specific exceptions, then more general ones! E.g. try { ... } catch (FileNotFoundException e) { ... } // subclass catch (IOException e) { .... } // superclass /* after try { ... } block (and possibly handling an exception) we are here */ 61 Multi-catch (Java 7!) [ http://download.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html ] The new code: ex is implicitly final! 62 try-with-resources (Java 7!) [ http://download.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html ] New syntax: try (…) { …}, no catch(…). Result: no explicit br.close(). Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource. A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed. 63 finally. Look at this! Output 64 finally. Modified code output 65 Exception example ([Barteczko’00]) (1/4) import java.awt.*; import java.awt.event.*; class NotValidZipException extends Exception { // exception class public String msg = "Valid zipcode is of form dd-ddd"; NotValidZipException(String s) { // constructor msg = "Bad zipcode: "+s+". "+msg; } } 66 Example (2/4) class ZipField extends TextField { // component class ZipField() { super(); } ZipField(String s) { super(s); } ZipField(int n) { super(n); } public String getZip() throws NotValidZipException { final int N = 6, P = 2; String zip = getText(); boolean valid = true; char[] c = zip.toCharArray(); if (c.length != N || c[P] != '-') valid = false; for (int i = 0; i<N && valid; i++) { if (i == P) continue; if (!Character.isDigit(c[i])) valid = false; } if (!valid) throw new NotValidZipException(zip); return zip; } } 67 Example (3/4) class Exc3 extends Frame implements ActionListener { ZipField zf = new ZipField(10); public static void main(String[] args) { new Exc3(); } Exc3() { setLayout(new FlowLayout()); Button b = new Button("Enter"); b.addActionListener(this); add(zf); add(b); pack(); setVisible(true); } 68 Example (4/4) public void actionPerformed(ActionEvent e) { String txt = null; try { txt = zf.getZip(); } catch(NotValidZipException exc) { System.out.println(exc.msg); return; } System.out.println("You entered: " + txt); } } 69 A simpler example [ http://www.freshsources.com/Apr01.html ] Suppose, for example, that in main we call a function f which calls a function g which finally calls a function h. // In main() try { f(); } catch (MyException e) { System.out.println(e); } Now, all we have to do to raise an exception in h is to throw it, like this: // In h() throw new MyException("optional text here"); 70 When should I throw exceptions? Throw exceptions only in truly exceptional situations. Not e.g. when not finding an element in an array (this is a normal situation and can be handled by returning –1 (pseudo)index). Consider a stack data structure. The contract of the pop method requires that the stack not be empty when it is called, so if you try to pop something from an empty stack, that's exceptional. There is no meaningful value to return in this case, and you shouldn’t have made the call in the first place. Similar logic applies to the top and push methods. 71 FixedStack class example [ http://www.cogs.susx.ac.uk/courses/dats/notes/html/node15.html ] class FixedStack { private int capacity; private int size; private Object[] data; ... public Object pop() throws StackException { if (size <= 0) throw new StackException("underflow"); return data[--size]; } public void push(Object o) throws StackException { if (size == capacity) throw new StackException("overflow"); data[size++] = o; } ... } 72 FixedStack, cont’d [ http://www.cogs.susx.ac.uk/courses/dats/notes/html/node15.html ] class StackException extends Exception { StackException() {} StackException(String msg) { super(msg); } } 73 Ops, FixedStack is gonna fall on me! 74 What use of finally? [ http://drdobbs.com/cpp/184403915 ] Problems? f.close() occurs twice in the code – a bit unelegant 75 What use of finally? Cont’d [ http://drdobbs.com/cpp/184403915 ] Nicer! 76 One more example import java.util.*; class Numbers1 { public static void main(String args[]) { String num1 = "123"; String num2 = "-10"; String num3 = "3.5"; // now, not an integer String result = null; try { // a conversion may fail int a = Integer.parseInt(num1); // conversion int b = Integer.parseInt(num2); double c = Double.parseDouble(num3); result = String.valueOf(a+b+c); // conversion System.out.println("Result = " + result); } catch(NumberFormatException e) { System.out.println("Bad numeric format!"); } } } 77 Exception handling – only for error messages?? No. Sometimes we can fix a run-time error. E.g. ask the user to re-enter the data. ([Barteczko’04]) 78 Example, cont’d ([Barteczko’04]) 79 Exception declaration IS NOT part of the signature [ based on http://wazniak.mimuw.edu.pl/index.php?title=PO_Wyj%C4%85tki__%C4%87wiczenia ] Recall: similarly the return value is not part of the method signature. 80 A little puzzle [ http://www.csc.uvic.ca/~csc330/ ] "Java"? No... Why not? 81 Puzzle, solution [ http://www.csc.uvic.ca/~csc330/Assignment1/Ass1-answers.pdf ] There are four constructors for the class StringBuffer. None of the constructors accepts a parameter of type char, which is what the program uses. However, in Java a value of type char can be coerced to a value of type int. So the instantiation is equivalent to new StringBuffer(74) because 'J' has the ASCII code 74. That particular invocation creates a new StringBuffer which is empty but which has an initial capacity of 74 characters. (But later, ‘a’ etc. will be appended, so the output is: ava (beware, word.length() == 3, but word.capacity() == 74). 82 Another puzzle; how to draw a random int from [0, n)? [ based on J. Bloch, Effective Java, 2001, Chap. 7 ] 1. Random rnd = new Random(); // java util.Random ... r = Math.abs(rnd.nextInt()) % n; 2. r = (int)(Math.random() * n); Ad 1: consider n = 2 * (Integer.MAX_VALUE / 3); ?!?! 3. r = Random.nextInt(n); 83 Private constructors A class can be public or “default” (i.e., no keyword in front of the class keyword). Private or protected classes are possible only in special cases (inner classes, we’ll talk about them another time...). But what about a private constructor? If all the constructors in a class X are private, we cannot explicitly create objects of X from outside of the class. 84 Private constructors, example (1/2) [TIJ, chapter 5] 85 Private constructors, example (2/2) [TIJ, chapter 5] 86 Singleton pattern for enums (no longer needed…) [ http://media.wiley.com/assets/264/21/0764557599_bonus_AppC.pdf ] The only objects that will ever be created with this class are the static objects the class creates for itself the first time the class is referenced. Now (since 1.5) Java has enum keyword. 87