Transcript class
Zaawansowane
programowanie obiektowe
Lecture 2
Szymon Grabowski
[email protected]
http://szgrabowski.kis.p.lodz.pl/zpo/
Thx to Wojciech Bieniecki for sharing stuff
and friendly advices
Łódź, 2009
Obfuscated code in Java? Why not...
class PrintQuirks {
static public void main(String[] args) {
System.out.println( 'A' );
System.out.println( 'A' + 'B' );
}
}
Output:
A
131
Joshua Bloch and Neal Gafter wrote a book
Java Puzzlers: Traps, Pitfalls, and Corner Cases.
Chapter for download:
http://www.ftponline.com/books/chapters/
032133678X.pdf
2
String vs StringBuffer (1/3)
Objects of class String are immutable in Java.
String s = "test";
s[0] = 'b'; // compile-error:
// array required, but java.lang.String found
There is charAt(int i) method in String, but only to read.
So, how can we e.g. append a character to a String?!
Short answer: we cannot.
We need to create another String:
String s1 = "ice-cream";
s1 = s1 + "s"; // SLOW esp. if s1 is long
// creates a temp object
3
String vs StringBuffer (2/3)
[http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html]
Class StringBuffer – smth like String but its objects
can be modified.
At any point in time it contains some particular
sequence of chars, but its length and content
can be changed through certain method calls.
StringBuffer sb = new StringBuffer(new String("start"));
sb.append("le"); // "startle"
or:
sb.insert(4, "le"); // start starlet
4
String vs StringBuffer (3/3)
[http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html]
[http://mindprod.com/jgloss/immutable.html]
Every string buffer has a capacity.
Initially (JDK 6) – 16 characters for an empty
string buffer, and 16 + |str| if using
public StringBuffer(String str) constructor.
If the internal buffer overflows,
it is automatically made larger.
Why String immutable?
• thread-safe. Two threads can both work on an immutable object at
the same time without any possibility of conflict;
• immutable objects are much better suited to be Hashtable keys.
If you change the value of an object that is used as a hash table
key without removing it and re-adding it, you lose the mapping.
5
Packages
Packages are class libraries.
To include (“import”) a package in your code,
write smth like import java.util.*;
Or you want to import a single class for a package?
Example: import java.util.ArrayList;
java.lang package is automatically imported.
Using an imported class: either (in the same example)
java.util.ArrayList or just ArrayList.
More convenient than in C/C++: you can import a package
more than once (no compiler complaint...),
you can write the import... line in any place in your code.
6
Packages, cont’d
Collisions possible:
Say that you’ve created a class Vector in a package
called school.my_cool_data_structures.
But you’ve also imported java.util.
Now, the line Vector v = new Vector();
makes a collision.
Solution: use full path.
java.util.Vector v = new java.util.Vector();
or
school.my_cool_data_structures.Vector v =
new school.my_cool_data_structures.Vector()
7
How to create an own package
Very simply.
Just write the code of your class (in a file with the same
name as the class name)
and start it with line e.g.
package myutils.text;
Your class will be added to the package myutils.text.
Of course, there can be many classes in a package.
Remember: earlier in the file than the package... line
may be only comments.
8
Access modifiers (for classes, methods, fields)
[ http://www.particle.kth.se/~lindsey/JavaCourse/Book/
Part1/Java/Chapter05/access.html ]
Java provides 4 access modifiers:
1.public – access by any other class anywhere.
2.protected – accessible by the package classes
and any subclasses that are in other packages.
3. default (also known as “package private”) – accessible
to classes in the same package but not by classes in other
packages, even if these are subclasses.
4.private – accessible only within the class.
Even methods in subclasses in the same package
do not have access.
A Java file can have only one public class!
9
Access modifiers, visualized
[ members.tripod.com/~psdin/comlang/basicJava.PDF ]
no!
If there is no direct access to a field (property),
provide accessor / mutator (aka get / set) methods.
10
Why private (or protected)?
To avoid accidental “spoiling” of some data.
To provide a proper class interface
(ensapsulation rule: hide unimportant details).
C++ programmers, beware:
put public / protected / private in front of
EACH method or field you want to specify that way.
(In C++, in contrast, an access specifier is valid for all
the definitions following it
until another access specifier occurs.)
11
Default package
class X { // file X.java
int x;
void doSomething() { ... }
}
class Y { // file Y.java in the same directory
void someMethod() {
X x = new X(); x.doSomething();
// does it work? Can Y see components of X ?
}
}
X’s components are NOT public.
So the question is:
are Y and X in the same package?
We didn’t write package ...
Yes!
Because they are in the same directory
and have no explicit package name.
12
Field initialization
Fields are initialized to ZERO (0, false for the boolean type,
null for references (i.e., object types)).
BEWARE: local variables are not initialized
(have random values)! Like in C/C++, by the way.
But trying to read an unitialized variable
yields a compile error.
You can also explicitly initialize a field, e.g.
class Pair {
static String text = "Pairs";
static int x = -1;
int a = x+1;
.....
13
Field initialization, cont’d
We can also init object fields, e.g.
class X {
Flower f = new Flower();
...
}
Or like that:
class X {
int i = f(); int j = g(i);
.....
}
But not
.....
int j = g(i); int i = f(); // order matters!
14
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
15
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
}
16
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
}
}
17
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.
18
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.
19
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.
20
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
21
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
22
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.
23
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.
24
(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. (...)
25
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()
• notifyAll()
• toString()
• wait()
• wait(long timeout)
• wait(long timeout, int nanos)
26
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.
27
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() { ... }
.....
}
28
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).
29
Interfaces, example (based on [Barteczko’04])
interface Speakable {
int QUIET = 0;
int LOUD = 1;
String getVoice(int voice);
}
interface Moveable {
void startMoving();
void stopMoving();
}
class Dog extends Animal implements Speakable, Moveable {
Dog() {}
Dog(String s) { super(s); }
String getType() { return "Dog"; }
public String getVoice(int voice) {
if (voice == LOUD) return "WOOF... WOOF... WOOF...";
else return "woof... woof...";
}
public void startMoving() {
System.out.println("Dog " + name + " is running.");
}
public void stopMoving() {
System.out.println("Dog " + name + " stood still.");
}
}
30
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()
31
Is it safe?
[ http://www.manning-source.com/books/forman/forman_chp5.pdf ]
32
It isn’t safe
33
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.
34
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. Adapters free us from
some typing.
35
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;}
}
36
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();
}
}
37
Adapters, formally speaking
(based on [http://web.mit.edu/1.124/LectureNotes/Swing.html])
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.
38
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
39
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.
40
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.
41
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();
42
// 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.
43
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.
44
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());
}
}
}
45
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.
46
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)...
47
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);
48
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));
....
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
finally. Look at this!
Output
62
finally. Modified code
output
63
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;
}
}
64
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;
}
}
65
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);
}
66
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);
}
}
67
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");
68
Whence exceptions?
(based on [ http://www.freshsources.com/Apr01.html ])
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.
69
FixedStack class example
[ http://www.freshsources.com/Apr01.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;
}
...
}
70
FixedStack, cont’d
[ http://www.freshsources.com/Apr01.html ]
class StackException extends Exception {
StackException() {}
StackException(String msg) { super(msg); }
}
71
Ops, FixedStack is gonna fall on me!
([http://www.freshsources.com/Apr01.html])
72
What use of finally?
([ http://www.freshsources.com/Apr01.html ] again)
Problems?
f.close()
occurs twice
in the code –
a bit
unelegant
73
What use of finally? Cont’d
([ http://www.freshsources.com/Apr01.html ] again)
Nicer!
74
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!");
}
}
}
75
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])
76
Example, cont’d ([Barteczko’04])
77
A little puzzle
[ http://www.csc.uvic.ca/~csc330/ ]
"Java"? No...
Why not?
78
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).
79