MCS_lecture6_Java_Testing_IO_Threads

Download Report

Transcript MCS_lecture6_Java_Testing_IO_Threads

Polymorphism
28-Mar-16
Legal assignments
class Test {
public static void main(String args[]) {
double d;
int i;
d = 5;
// legal
i = 3.5;
// illegal
i = (int) 3.5;
// legal
}
}


Widening is legal
Narrowing is illegal (unless you cast)
2
Legal method calls
class Test {
public static void main(String args[]) {
myPrint(5);
}
static void myPrint(double d) {
System.out.println(d);
}
}
5.0


Legal because parameter transmission is equivalent to
assignment
myPrint(5) is like double d = 5; System.out.println(d);
3
Illegal method calls
class Test {
public static void main(String args[]) {
myPrint(5.0);
}
static void myPrint(int i) {
System.out.println(i);
}
}
myPrint(int) in Test cannot be applied to (double)


Illegal because parameter transmission is equivalent to
assignment
myPrint(5.0) is like int i = 5.0; System.out.println(i);
4
Overloading
class Test {
public static void main(String args[]) {
myPrint(5);
myPrint(5.0);
}
static void myPrint(int i) {
System.out.println("int i = " + i);
}
static void myPrint(double d) { // same name, different parameters
System.out.println("double d = " + d);
}
}
int i = 5
double d = 5.0
5
Why overload a method?

Sometimes so you can supply defaults for the
parameters


int increment() {
return increment(1);
}
Notice that one method can call another of the same name
Sometimes so you can supply additional information:
void printResult(String message) {
System.out.println(message);
printResult();
}
6
Multiple constructors

You can “overload” constructors as well as methods



Counter() { count = 0; }
Counter(int start) { count = start; }
One constructor can “call” another constructor in the
same class, but there are special rules





You call the other constructor with the keyword this
The call must be the very first thing the constructor does
Point(int x, int y) { this.x = x; this.y = y; sum = x + y; }
Point() { this(0, 0); System.out.println("At origin"); }
A common reason for overloading constructors is (as above)
to provide default values for missing parameters
7
Superclass construction

The very first thing any constructor does, automatically, is call
the default constructor for its superclass


class Foo extends Bar {
Foo() { // constructor
super(); // invisible call to superclass constructor
...
You can replace this with a call to a specific superclass
constructor



Use the keyword super
This must be the very first thing the constructor does
class Foo extends Bar {
Foo(String name) { // constructor
super(name, 5); // explicit call to superclass constructor
...
8
Polymorphism



Polymorphism means many (poly) shapes (morph)
In Java, polymorphism refers to the fact that you can
have multiple methods with the same name in the same
class
There are two kinds of polymorphism

Overloading (which you have just seen)


Two or more methods with different signatures
Overriding (which you will see shortly)

Replacing an inherited method with another having the same signature
9
Signatures



In any programming language, a signature is what
distinguishes one function or method from another
In C, every function has to have a different name
In Java, two methods have to differ in their names
or in the number or types of their parameters




foo(int i) and foo(int i, int j) are different
foo(int i) and foo(int k) are the same
foo(int i, double d) and foo(double d, int i) are
different
In C++, the signature also includes the return type

But not in Java!
10
Shadowing
class Animal {
String name = "Animal";
public static void main(String args[]) {
Animal animal = new Animal();
Dog dog = new Dog();
System.out.println(animal.name + " " + dog.name);
}
}
public class Dog extends Animal {
String name = "Dog";
}
Animal Dog

This is called shadowing—name in class Dog shadows
name in class Animal
11
Overriding
class Animal {
public static void main(String args[]) {
Animal animal = new Animal();
Dog dog = new Dog();
animal.print();
dog.print();
}
void print() {
System.out.println("Superclass Animal");
}
}


This is called
overriding a
method
Method print in
Dog overrides
method print in
Animal
public class Dog extends Animal {
void print() {
System.out.println("Subclass Dog");
}
}
Superclass Animal
Subclass Dog
12
How to override a method

Create a method in a subclass having the same name
and the same number and types of parameters



Parameter names don’t matter
The return type must be the same
The overriding method cannot be more private than the
method it overrides
13
Why override a method?

Dog dog = new Dog();
System.out.println(dog);


Prints something like Dog@feda4c00
The println method calls the toString method, which is
defined in the Object class



Hence, every object can be printed (though it might not look pretty)
The method public String toString() may be overridden
If you add to class Dog the following:
public String toString() {
return name;
}
Then System.out.println(dog); will print the dog’s
name, which may be something like: Fido
14
A little puzzle
public class main {
int main = 5;
public static void main(String args[]) {
main main = new main();
System.out.print(main);
}
}



This is a legal program (!); what does it print?
Answer: main@ecf76e
Next question: why?
15
Namespaces

Java figures out what kind of thing a name
refers to, and puts it in one of six different
namespaces:






package names
type names
field names
method names
local variable names (including parameters)
labels
16
The puzzle solved
public class main { // type name
int main = 5; // field name
public static void main(String args[]) { // method name
main main = new main(); // local names (incl. args)
System.out.print(main);
}
}



Java prints out object main@ecf76e in local variable main
We haven’t talked about package names or labels
Note that this is terrible style!
17
Another little puzzle

public class Test {
static int five() { return 5; }
public static void main(String args[]) {
System.out.print(five);
}
}
cannot resolve symbol
symbol :variable five location: class Test
Answer: five() is a method, but five looks like a
local variable
18
What you should remember



A namespace is a place that Java keeps track
of names
Java uses six different namespaces
If you name things intelligently, and don’t use
the same name for different things, you don’t
have to worry much about namespaces
19
Access
28-Mar-16
Instance and class variables

You can declare variables within a class




These variables are called instance variables, or fields
Every object of that class has its own copy of those fields
The fields describe something about the object
You can also declare static variables within a class



There is only one of each static variable
A static variable is also called a class variable
The static variable describes something about the class as
a whole
21
Method variables

You can declare variables within a method or within a
constructor




These are called method variables, not fields
Method variables are basically used for computation
Method variables are strictly temporary, and are used only
within that method
When a method returns (completes), all its variables are
discarded
22
Example: a “Rabbit” class

class Rabbit {
static int population;
double hunger;
double fear;
double courage = 0.75;
// class variable (counts Rabbits)
//instance variable
// instance variable
// instance variable

void eat() {
double temp;
// method variable
temp = courage * hunger;
if (temp > fear) {
System.out.println(“Eating!”);
hunger = hunger - 1;
}
}
}
23
Statements



You can declare variables inside a class or inside a
method or a constructor
You can put statements (executable code) only within
methods and constructors, not inside a class
Declarations with initializations are still declarations,
not statements
24
Statements must be in methods
(or in constructors)
class Rabbit {
double hunger;
// OK--declaration
double fear = 5.0; // OK--still a declaration
hunger = 5.0;
// illegal--assignment statement
Rabbit ( ) {
hunger = 5.0; // OK—statement in a constructor
}
void eat ( ) {
hunger = hunger - 1; // OK—statement in a method
}
}
25
Access from inside a class


Inside a class, you can access other fields and methods
inside the class just by naming them
Example:
class Person {
int age;
void birthday( ) { age = age + 1; }
void growOlder( ) { birthday( ); }
}

Equivalently, you can use the keyword this:
void birthday( ) { this.age = this.age + 1; }
void growOlder( ) { this.birthday( ); }
26
Accessing from outside a class, 1

Outside a class (from some other class) you access
instance variables and methods by




Naming the object you want to talk to
Putting a dot
Naming the variable or method
Example:
// if NOT in class Person, say:
if (john.age < 75) john.birthday();

Inside the class, the keyword this means “this object”:

if (this.age < 75) this.birthday(); // "this" may mean john
27
Accessing from outside a class, 2

Outside a class (from some other class) you access
class variables and methods by




Naming the class you want to talk to
Putting a dot
Naming the variable or method
Examples:
Person.population = Person.population + 1;
x = Math.abs(y);
28
Responsibility

In Java, objects are considered to be active



They have behaviors
They are responsible for their own data
Data (variables) must be kept consistent


Example: population should never be negative
In order for a class or object to be responsible for its
own data, it must keep control of that data
29
Loss of control


Suppose a Rabbit object, bugsBunny, has a
variable named hunger
Inside the class, this method is fine:
void eat ( ) {
hunger = hunger - 1;
}

From outside the class, the following is legal:


bugsBunny.hunger = bugsBunny.hunger - 1;
But should we be allowed to “reach inside” a rabbit?
The class needs to protect itself from errors in other classes
(and from malicious behavior)
30
private variables and methods

If you declare a variable or method to be private,
that variable or method can only be accessed from
within the class



private methods also make sense, e.g. digest()
If you declare a variable or method to be public, then
any code anywhere can access it
Typically, a class or object has both


Methods for use by the rest of the program
Methods and variables that it alone should control
31
Levels of access


private -- access only from within the class
“package” -- access from within the class, or from
any class in the same directory (“folder”)



This is the default; there is no package keyword
protected -- access from within the class, or from
within any subclass, or from any other class in the
same directory
public -- access from anywhere at all
32
Levels of access, II

To make a variable or method visible





Only within this class: private
From this class and its subclasses: not possible
From this class and its subclasses, and any other class in
this directory: “package” (default)
From this subclass and its subclasses, and any other
classes in this directory: protected
From anywhere: public
33
Getters and setters

One way to control access is via getters and setters:
class Rabbit {
private double hunger;
// getter
public double getHunger() {
return hunger;
}
// setter
public void setHunger(double hunger) {
this.hunger = hunger;
}

This seems silly, but it’s much safer and more flexible
34
Immutable objects

Suppose a Planet has a mass, and you want to be able to
see its mass but not change it:
class Planet {
private long mass;
// Constructor
Planet(long mass) {
this.mass = mass;
}
//getter
long getMass() {
return mass;
}
// Notice there is no setter!
}
35
Where’s the API?
36
General approach



If you know the name of the package, click it in the
upper left panel; or click All Classes
Click on the class in the lower left panel
Scroll in the right pane to find the summary of the
field, method, or constructor you want


Or just read the general description
For more information, click the link in the
summary to go to the detailed information
37
The main information area







General description of the class
Field summary
Constructor summary
Method summary
Field detail
Constructor detail
Method detail

In each case, the
“summary” is the first
sentence of the “detail”
38
Reading the method descriptions I

An example from the String class:

public char charAt(int index)







Returns the character at the specified index
public means accessible from anywhere
char is the return type
charAt is the name of the method
int is the type of parameter expected
index is just a suggestive name
Example use: char firstChar = myStr.charAt(0);
39
Reading the method descriptions II

Another example from the String class:
 public static String valueOf(int i)

Returns the string representation of the int argument.

public means accessible from anywhere
static means this is a class method (see use below)
String is the return type, and is a hyperlink
valueOf is the name of the method
int is the type of parameter expected
i is just a suggestive name

Example use: String numeral = String.valueOf(m / n);





40
How was this documentation produced?


All Java documentation was produced by the javadoc
program from javadoc (or just doc) comments in the
source code
Your doc comments can be used in the same way to
produce professional-looking documentation
41
Value of the API




Version
packages
classes
methods
Java 1.0
8
212
1545
Java 1.1
23
504
3851
Java 1.2
60
1781
15060
Java 1.3
77
2130
17158
Java 1.4
135
2738
?
Java 1.5
?
?
?
You can only learn a small fraction of these
When you learn the kinds of things that are in the API, and
learn to find your way around in it, you become a far more
effective and efficient programmer
A good craftsman knows his/her tools
42
Error Prevention
28-Mar-16
Errors and Exceptions

An error is a bug in your program




dividing by zero
going outside the bounds of an array
trying to use a null reference
An exception is a problem whose cause is outside your
program


trying to open a file that isn’t there
running out of memory
44
What to do about errors and exceptions

An error is a bug in your program


An exception is a problem that your program may
encounter




It should be fixed
The source of the problem is outside your program
An exception is not the “normal” case, but...
...your program must be prepared to deal with it
This is not a formal distinction–it isn’t always clear
whether something should be an error or an exception
45
Dealing with exceptions

Most exceptions arise when you are handling files




A needed file may be missing
You may not have permission to write a file
A file may be the wrong type
Exceptions may also arise when you use someone
else’s classes (or they use yours)


You might use a class incorrectly
Incorrect use should result in an exception
46
The problem with exceptions

Here’s what you might like to do:



But here’s what you might have to do:








open a file
read a line from the file
open a file
if the file doesn’t exist, inform the user
if you don’t have permission to use the file, inform the user
if the file isn’t a text file, inform the user
read a line from the file
if you couldn’t read a line, inform the user
etc., etc.
All this error checking really gets in the way of
understanding the code
47
Three approaches to error checking
1. Ignore all but the most important errors
 The code is cleaner, but the program will misbehave when it
encounters an unusual error
2. Do something appropriate for every error
 The code is cluttered, but the program works better
 You might still forget some error conditions
3. Do the normal processing in one place, handle the
errors in another (this is the Java way)
 The code is at least reasonably uncluttered
 Java tries to ensure that you handle every error
48
The try statement

Java provides a new control structure, the try statement
(also called the try-catch statement) to separate
“normal” code from error handling:
try {
do the “normal” code, ignoring possible exceptions
}
catch (some exception) {
handle the exception
}
catch (some other exception) {
handle the exception
}
49
Exception handling is not optional


As in other languages, errors usually just cause
your program to crash
Other languages leave it up to you whether you
want to handle exceptions



There are a lot of sloppy programs in the world
It’s normal for human beings to be lazy
Java tries to force you to handle exceptions


This is sometimes a pain in the neck, but...
the result is almost always a better program
50
Error and Exception are Objects


In Java, an error doesn’t necessarily cause your
program to crash
When an error occurs, Java throws an Error object
for you to use



You can catch this object to try to recover
You can ignore the error (the program will crash)
When an exception occurs, Java throws an
Exception object for you to use


You cannot ignore an Exception; you must catch it
You get a syntax error if you forget to take care of any
possible Exception
51
The exception hierarchy

Throwable: the superclass of “throwable”
objects


Error: Usually should not be caught (instead,
the bug that caused it should be fixed)
Exception: A problem that must be caught


RuntimeException: A special subclass of
Exception that does not need to be caught
Hence, it is the Exceptions that are most
important to us (since we have to do
something about them)
52
The Exception hierarchy II
Throwable
Error
Need not
be caught
Exception
Must be caught
RuntimeException
53
A few kinds of Exceptions

IOException: a problem doing input/output






FileNotFoundException: no such file
EOFException: tried to read past the End Of File
NullPointerException: tried to use a object that was actually
null (this is a RuntimeException)
NumberFormatException: tried to convert a non-numeric
String to a number (this is a RuntimeException)
OutOfMemoryError: the program has used all available
memory (this is an Error)
There are about 200 predefined Exception types
54
What to do about Exceptions

You have two choices:

You can “catch” the exception and deal with it


You can “pass the buck” and let some other part
of the program deal with it


For Java’s exceptions, this is usually the better
choice
This is often better for exceptions that you create
and throw
Exceptions should be handled by the part of
the program that is best equipped to do the
right thing about them
55
What to do about Exceptions II

You can catch exceptions with a try statement


When you catch an exception, you can try to repair the
problem, or you can just print out information about what
happened
You can “pass the buck” by stating that the method in
which the exception occurs “throws” the exception

Example:
void openFile(String fileName) throws IOException { ... }

Which of these you do depends on whose responsibility
it is to do something about the exception


If the method “knows” what to do, it should do it
If it should really be up to the user (the method caller) to
decide what to do, then “pass the buck”
56
How to use the try statement

Put try {...} around any code that might throw an
exception


This is a syntax requirement you cannot ignore
For each Exception object that might be thrown, you
must provide a catch phrase:



catch (exception_type name) {...}
You can have as many catch phrases as you need
name is a formal parameter that holds the exception object
You can send messages to this object and access its fields
57
finally



After all the catch phrases, you can have an optional
finally phrase
try { ... }
catch (AnExceptionType e) { ... }
catch (AnotherExceptionType e) { ... }
finally { ... }
Whatever happens in try and catch, even if it does a
return statement, the finally code will be executed


If no exception occurs, the finally will be executed after the
try code
In an exception does occur, the finally will be executed after
the appropriate catch code
58
How the try statement works




The code in the try {...} part is executed
If there are no problems, the catch phrases are skipped
If an exception occurs, the program jumps immediately
to the first catch clause that can handle that exception
Whether or not an exception occurred, the finally code
is executed
59
Ordering the catch phrases

A try can be followed by many catches


The first one that can catch the exception is the one that will
catch the exception
Bad:
catch(Exception e) { ... }
catch(IOException e) { ... }

This is bad because IOException is a subclass of
Exception, so any IOException will be handled by the
first catch

The second catch phrase can never be used
60
Using the exception

When you say catch(IOException e), e is a formal
parameter of type IOException




A catch phrase is almost like a miniature method
e is an instance (object) of class IOException
Exception objects have methods you can use
Here’s an especially useful method that is defined for
every exception type:
e.printStackTrace();
 This prints out what the exception was, and how you got to
the statement that caused it
61
printStackTrace()

printStackTrace() does not print on System.out,
but on another stream, System.err



From JBuilder: It shows up in the output window, in red
From the command line: both System.out and
System.err are sent to the terminal window
printStackTrace(stream) prints on the given
stream

printStackTrace(System.out) prints on System.out,
and this output is printed along with the “normal” output
62
Throwing an Exception

If your method uses code that might throw an exception,
and you don’t want to handle the exception in this
method, you can say that the method “throws” the
exception

Example:
String myGetLine( ) throws IOException { ... }

If you do this, then the method that calls this method
must handle the exception
63
Constructing an Exception

Exceptions are classes; you can create your own
Exception with new


Exception types have two constructors: one with no
parameters, and one with a String parameter
You can subclass Exception to create your own
exception type

But first, you should look through the predefined exceptions
to see if there is already one that’s appropriate
64
Throwing an Exception

Once you create an Exception, you can throw it


throw new UserException("Bad data");
You don’t have to throw an Exception; here’s
another thing you can do with one:

new UserException("Bad data").printStackTrace();
65
Why create an Exception?



If you are writing methods for someone else to use, you
want to do something reasonable if they use your
methods incorrectly
Just doing the wrong thing isn’t very friendly
Remember, error messages are a good thing—much
better than not having a clue what went wrong

Exceptions are even better than error messages, because they
allow the user of your class to decide what to do
66
About the assert statement




The purpose of the assert statement is to give you a way to catch
program errors early
The assert statement is new in Java 1.4
The assert statement uses a new keyword, assert
The new keyword may break older programs that use assert as a
user-defined name



Hence, there is a way to use the old syntax
With the old syntax, assert statements are syntax errors
There is also a way to “turn off” assert statements


When they are turned off, Java just ignores assert statements
Unfortunately, this also means that your assert statements may be off
when you think they are working and doing their job
67
Syntax

There are two forms of the assert statement:
1.
assert booleanExpression;



2.
This statement tests the boolean expression
It does nothing if the boolean expression evaluates to true
If the boolean expression evaluates to false, this statement throws an
AssertionError
assert booleanExpression : expression;



This form acts just like the first form
In addition, if the boolean expression evaluates to false, the second
expression is used as a detail message for the AssertionError
The second expression may be of any type except void
68
Notes on writing assertions

An AssertionError is an Error, not an Exception




You do not need to put it in a try statement
You do not need to catch the error
Using an assert statement does not entail any extra work on
your part
The second expression is seldom necessary


If an AssertionError is thrown, Java automatically gives you
a stack trace, complete with the line number
Use the second expression only if you have useful information
to add to the error message
69
Examples
if (x < 0) {
...
}
else if (x == 0) {
...
}
else {
assert x > 0;
...
}
switch(suit) {
case Suit.CLUBS:
...
break;
case Suit.DIAMONDS:
...
break;
case Suit.HEARTS:
...
break;
case Suit.SPADES:
...
break;
default:
assert false: suit;
}
70
Assertions vs. Exceptions

When do you use assertions instead of exceptions?




An exception tells the user of your program that
something went wrong
An assertion documents something about your program



Both catch problems in your program, but...
The intended usage is very different!
When an assertion fails, it tells you that you have a bug
You create Exceptions to deal with problems that you
know might occur
You write assertions to state things you know (or think
you know) about your program
71
When to throw Exceptions

Use Exceptions when you:

Test whether the parameters to a public method or public
constructor are legal


Do any input/output


If it’s public, then other people besides you, the author of this class,
can call it
You, the class author, cannot ensure the files will be there or be correct
if they are there
In short,


Think of yourself as the author of this class only
Anything that could go wrong, that you have no control over
within this class, deserves an Exception
72
When to use assertions


Frequently!
Assertions are intended to be cheap to write





Just drop them into your code any time you think of them
Example: assert age >= 0;
How hard is that?
Assertions are not intended as a debugging device (though they
can be used that way)
Rather, assertions should be used to specify things that you
believe to be true at various points in your program


Assertions provide documentation, not just error checking
Assertions are documentation that can be checked by the running program!
73
Invariants


An invariant is something that should always be true
An internal invariant is a “fact” that you believe to be true at a
certain point in the program


A control-flow invariant is typically an assertion that you
cannot get to certain code



assert x > 0; was an example of an internal invariant
assert false: suit; was an example
Caution: It is a syntax error to put any code where Java knows you
cannot get to it (say, immediately following a return statement)
A class invariant is one that an object must satisfy in order to
be a valid member of a class

Example: assert person.age >= 0 && person.age < 150;
74
When not to use assertions

Do not use assertions to do necessary work



Assertions can be disabled (“turned off”)
It’s a really bad idea to have your program work
correctly only when assertions are turned on!
Do not use assertions to check the arguments to
public methods


Argument checking is part of the contract, and should
work with or without assertions
There are more appropriate Exceptions to throw:
IllegalArgumentException, NullPointerException,
and IndexOutOfBoundsException are the main ones
75
Assertions can be disallowed

Earlier versions of Java did not have assertions





It’s possible that someone used assert as a variable or method name
We still want to be able to use older programs
This means we need to be able to disallow assert as a keyword
There is no problem with pre-existing binaries (.class files)
that used assert as a user-defined name
The problem can arise when you recompile old source code



By default, javac uses the old syntax (no assert statements), but
this will probably change with 1.5
To use assert statements, set a flag in your IDE, or add the flag
-source 1.4 to your javac command line
Note that the compiler javac has changed, not the interpreter java
76
Assertions can be disabled



Disallowing assertions means they are not legal syntax;
disabling assertions means they are legal but are turned
off
By default, assertions are both disallowed and disabled
To enable assertions, use the -enableassertions (or ea) flag on the java command line

You can also enable or disable assertions for a given package
or class, but we won’t go into that here
77
Ensuring assertions are enabled

You don’t need to explicitly check whether
assertions are allowed by the compiler


You’ll get a syntax error for your assert statement if they
are not allowed
The following code, placed at the top of a class, will
check whether assertions are enabled:
static {
boolean assertsEnabled = false;
assert assertsEnabled = true; // Intentional side effect!!!
if (!assertsEnabled)
throw new RuntimeException("Asserts must be enabled!!!");
}
78
Characters and Strings
28-Mar-16
Characters


In Java, a char is a primitive type that can hold one
single character
A character can be:




A letter or digit
A punctuation mark
A space, tab, newline, or other whitespace
A control character

Control characters are holdovers from the days of teletypes—they are
things like backspace, bell, end of transmission, etc.
80
char literals

A char literal is written between single quotes (also
known as apostrophes):
'a'

'5'
'?'
''
Some characters cannot be typed directly and must be
written as an “escape sequence”:



'A'
Tab is '\t'
Newline is '\n'
Some characters must be escaped to prevent ambiguity:


Single quote is '\'' (quote-backslash-quote-quote)
Backslash is '\\'
81
Additional character literals
\n newline
\t
tab
\b
backspace
\r
return
\f
\\
\'
\"
form feed
backslash
single quote
double quote
82
Character encodings





A character is represented as a pattern of bits
The number of characters that can be represented
depends on the number of bits used
For a long time, ASCII (American Standard Code for
Information Interchange) has been used
ASCII is a seven-bit code (allows 128 characters)
ASCII is barely enough for English

Omits many useful characters:
¢½ç“”
83
Unicode

Unicode is a new standard for character encoding that is
designed to replace ASCII
“Unicode provides a unique number for every character,
no matter what the platform, no matter what the
program, no matter what the language.”

Java uses a subset of Unicode to represent characters


The Java subset uses two bytes for every character


Java 1.5 expands this by allowing some three-byte characters
Except for having these extra characters available, it seldom
makes any difference to how you program
84
Unicode character literals




The rest of the ASCII characters can be written as
octal numbers from \0 to \377
Any Unicode character (in the Java subset) can be
written as a hexadecimal number between \u0000
and \uFFFF
Since there are over 64000 possible Unicode
characters, the list occupies an entire book
 This makes it hard to look up characters
Unicode “letters” in any alphabet can be used
in identifiers
85
Glyphs and fonts


A glyph is the printed representation of a character
For example, the letter ‘A’ can be represented by any of
the glyphs
A A A A A


A font is a collection of glyphs
Unicode describes characters, not glyphs
86
Strings




A String is a kind of object, and obeys all the rules for
objects
In addition, there is extra syntax for string literals and
string concatenation
A string is made up of zero or more characters
The string containing zero characters is called the
empty string
87
String literals



A string literal consists of zero or more characters
enclosed in double quotes
"" "Hello" "This is a String literal."
To put a double quote character inside a string, it
must be backslashed:
"\"Wait,\" he said, \"Don't go!\""
Inside a string, a single quote character does not
need to be backslashed (but it can be)
88
String concatenation



Strings can be concatenated (put together) with
the + operator
"Hello, " + name + "!"
Anything “added” to a String is converted to a string
and concatenated
Concatenation is done left to right:
"abc" + 3 + 5
gives "abc35"
3 + 5 + "abc"
gives "8abc"
3 + (5 + "abc") gives "35abc"
89
Newlines




The character '\n' represents a “newline” (actually, it’s an
LF, the linefeed character)
When “printing” to the screen, you can go to a new line by
printing a newline character
You can also go to a new line by using System.out.println
with no argument or with one argument
When writing to the internet, you should use "\r\n" instead
of println because println is platform-specific




On UNIX, println uses LF for a newline
On Macintosh, println uses CR instead of LF for a newline
On Windows, println uses CR-LF for a newline
When you use the character constants, you are in control of what is
actually output
90
System.out.print and println





System.out.println can be called with no arguments
(parameters), or with one argument
System.out.print is called with one argument
The argument may be any of the 8 primitive types
The argument may be any object
Java can print any object, but it doesn’t always do a
good job


Java does a good job printing Strings
Java typically does a poor job printing types you define
91
Printing your objects

In any class, you can define the following instance method:
public String toString() { ... }



This method can return any string you choose
If you have an instance x, you can get its string
representation by calling x.toString()
If you define your toString() method exactly as above, it
will be used whenever your object is converted to a String


This happens during concatenation:
"My object is " + myObject
toString() is also used by System.out.print and
System.out.println
92
Constructing a String

You can construct a string by writing it as a literal:
"This is special syntax to construct a String."

Since a string is an object, you could construct it with
new:
new String("This also constructs a String.")

But using new for constructing a string is foolish,
because you have to write the string as a literal to pass it
in to the constructor

You’re doing the same work twice!
93
String methods


This is only a sampling of string methods
All are called as: myString.method(params)



length() -- the number of characters in the String
charAt(index) -- the character at (integer) position index,
where index is between 0 and length-1
equals(anotherString) -- equality test (because == doesn’t
do quite what you expect


Hint: Use "expected".equals(actual) rather than
actual.equals("expected") to avoid NullPointerExceptions
Don’t learn all 48 String methods unless you use
them a lot—instead, learn to use the API!
94
Vocabulary







escape sequence -- a code sequence for a character,
beginning with a backslash
ASCII -- an 7-bit standard for encoding characters
Unicode -- a 16-bit standard for encoding characters
glyph -- the printed representation of a character
font -- a collection of glyphs
empty string -- a string containing no characters
concatenate -- to join strings together
95
Testing & JUnit
28-Mar-16
Test suites

Obviously you have to test your code to get it working in the
first place



You can do ad hoc testing (running whatever tests occur to you at the
moment), or
You can build a test suite (a thorough set of tests that can be run at any
time)
Disadvantages of a test suite

It’s a lot of extra programming


You don’t have time to do all that extra work


This is true, but use of a good test framework can help quite a bit
False—Experiments repeatedly show that test suites reduce debugging time
more than the amount spent building the test suite
Advantages of a test suite


Reduces total number of bugs in delivered code
Makes code much more maintainable and refactorable

This is a huge win for programs that get actual use!
97
XP approach to testing

In the Extreme Programming approach,



Tests are written before the code itself
If code has no automated test case, it is assumed not to work
A test framework is used so that automated testing can be done after
every small change to the code



This may be as often as every 5 or 10 minutes
If a bug is found after development, a test is created to keep the bug from
coming back
Consequences



Fewer bugs
More maintainable code
Continuous integration—During development, the program always
works—it may not do everything required, but what it does, it does right
98
Rhythm

“There is a rhythm to developing software unit tests first.
You create one test to define some small aspect of the problem
at hand.
Then you create the simplest code that will make that test pass.
Then you create a second test.
Now you add to the code you just created to make this new test
pass, but no more!
Not until you have yet a third test.
You continue until there is nothing left to test.”
 http://www.extremeprogramming.org/rules/testfirst.html
99
JUnit

JUnit is a framework for writing tests



JUnit was written by Erich Gamma (of Design Patterns fame) and Kent
Beck (creator of XP methodology)
JUnit uses Java’s reflection capabilities (Java programs can examine their
own code)
JUnit helps the programmer:






define and execute tests and test suites
formalize requirements and clarify architecture
write and debug code
integrate code and always be ready to release a working version
JUnit is not yet (as far as I know) included in Sun’s SDK, but an increasing
number of IDEs include it
JBuilder, BlueJ and Eclipse now provide JUnit tools
100
Terminology

A test fixture sets up the data (both objects and primitives) that
are needed to run tests

Example: If you are testing code that updates an employee record, you
need an employee record to test it on

A unit test is a test of a single class
A test case tests the response of a single method to a particular set
of inputs
A test suite is a collection of test cases
A test runner is software that runs tests and reports results

An integration test is a test of how well classes work together




JUnit provides some limited support for integration tests
101
Structure of a JUnit test class


Here’s what you do to test a class named Fraction:
public class FractionTest
extends junit.framework.TestCase {


public FractionTest() { }


Creates a test fixture by creating and initializing objects and values
protected void tearDown()


This is the default constructor
protected void setUp()


This is the unit test for the Fraction class; it declares (and possibly
defines) values used by one or more tests
Releases any system resources used by the test fixture
public void testAdd(), public void testToString(), etc.

These methods contain tests for the Fraction methods add(), toString(),
etc. (note how capitalization changes)
102
Assert methods I

Within a test,




An assert method is a JUnit method that performs a test, and
throws an AssertionFailedError if the test fails


JUnit catches these Errors and shows you the result
static void assertTrue(boolean test)
static void assertTrue(String message, boolean test)



Call the method being tested and get the actual result
assert what the correct result should be with one of the provided assert
methods
These steps can be repeated as many times as necessary
Throws an AssertionFailedError if the test fails
The optional message is included in the Error
static void assertFalse(boolean test)
static void assertFalse(String message, boolean test)

Throws an AssertionFailedError if the test fails
103
Example: Counter class

For the sake of example, we will create and test a trivial
“counter” class




We write the test methods before we write the code



The constructor will create a counter and set it to zero
The increment method will add one to the counter and return the new
value
The decrement method will subtract one from the counter and return
the new value
This has the advantages described earlier
Depending on the JUnit tool we use, we may have to create the class
first, and we may have to populate it with stubs (methods with empty
bodies)
Don’t be alarmed if, in this simple example, the JUnit tests are
more code than the class itself
104
JUnit tests for Counter
public class CounterTest extends junit.framework.TestCase {
Counter counter1;
public CounterTest() { } // default constructor
protected void setUp() { // creates a (simple) test fixture
counter1 = new Counter();
}
protected void tearDown() { } // no resources to release
}
public void testIncrement() {
assertTrue(counter1.increment() == 1);
assertTrue(counter1.increment() == 2);
}
Note that each test begins
with a brand new counter
public void testDecrement() {
assertTrue(counter1.decrement() == -1);
}
This means you don’t
have to worry about the
order in which the tests
are run
105
The Counter class itself
public class Counter {
int count = 0;


public int increment() {
return ++count;
}
public int decrement() {
return --count;
}
public int getCount() {
return count;
}
}



Is JUnit testing overkill for this
little class?
The Extreme Programming view is:
If it isn’t tested, assume it doesn’t
work
You are not likely to have many
classes this trivial in a real program,
so writing JUnit tests for those few
trivial classes is no big deal
Often even XP programmers don’t
bother writing tests for simple getter
methods such as getCount()
We only used assertTrue in this
example, but there are additional
assert methods
106
Assert methods II



assertEquals(expected, actual)
assertEquals(String message, expected, actual)
 This method is heavily overloaded: expected and actual must be both
objects or both of the same primitive type
 For objects, uses your equals method, if you have defined it properly, as
public boolean equals(Object o)—otherwise it uses ==
assertSame(Object expected, Object actual)
assertSame(String message, Object expected, Object actual)
 Asserts that two objects refer to the same object (using ==)
assertNotSame(Object expected, Object actual)
assertNotSame(String message, Object expected, Object actual)
 Asserts that two objects do not refer to the same object
107
Assert methods III



assertNull(Object object)
assertNull(String message, Object object)
 Asserts that the object is null
assertNotNull(Object object)
assertNotNull(String message, Object object)
 Asserts that the object is null
fail()
fail(String message)
 Causes the test to fail and throw an AssertionFailedError
 Useful as a result of a complex test, when the other assert methods
aren’t quite what you want
108
The assert statement

Earlier versions of JUnit had an assert method instead of an
assertTrue method


There are two forms of the assert statement:





The name had to be changed when Java 1.4 introduced the assert
statement
assert boolean_condition;
assert boolean_condition: error_message;
Both forms throw an AssertionFailedError if the boolean_condition is
false
The second form, with an explicit error message, is seldom necessary
When to use an assert statement:



Use it to document a condition that you “know” to be true
Use assert false; in code that you “know” cannot be reached (such as a
default case in a switch statement)
Do not use assert to check whether parameters have legal values, or other
places where throwing an Exception is more appropriate
109
JBuilder




JBuilder provides support for testing
You can create objects on the test bench and move
them to the fixture (and back again)
JBuilder also makes it easy to run a single test, a suite
of tests, or all tests
JBuilder display of JUnit results is professional level
110
JUnit in JBuilder

To use JUnit in
JBuilder, go to
File->New->Test
and select Test
Case or Test
Suite
111
Viewing test results
Unexpected errors and
exceptions
Failed
tests
112
Simple Java I/O
Part I
General Principles
28-Mar-16
Prologue
“They say you can hold seven plus or minus two pieces of
information in your mind. I can’t remember how to open files
in Java. I’ve written chapters on it. I’ve done it a bunch of
times, but it’s too many steps. And when I actually analyze
it, I realize these are just silly design decisions that they
made. Even if they insisted on using the Decorator pattern
in java.io, they should have had a convenience constructor
for opening files simply. Because we open files all the time,
but nobody can remember how. It is too much information to
hold in your mind.”
—Bruce Eckel, http://www.artima.com/intv/aboutme2.html
114
Streams





All modern I/O is stream-based
A stream is a connection to a source of data or to a
destination for data (sometimes both)
An input stream may be associated with the keyboard
An input stream or an output stream may be
associated with a file
Different streams have different characteristics:


A file has a definite length, and therefore an end
Keyboard input has no specific end
115
How to do I/O
import java.io.*;



Open the stream
Use the stream (read, write, or both)
Close the stream
116
Why Java I/O is hard



open
use
close
Java I/O is very powerful, with an overwhelming
number of options
Any given kind of I/O is not particularly difficult
The trick is to find your way through the maze of
possibilities
117
Opening a stream



open
use
close
There is data external to your program that you want to
get, or you want to put data somewhere outside your
program
When you open a stream, you are making a connection
to that external place
Once the connection is made, you forget about the
external place and just use the stream
118
Example of opening a stream

open
use
close
A FileReader is a used to connect to a file that will be
used for input:
FileReader fileReader =
new FileReader(fileName);


The fileName specifies where the (external) file is to be
found
You never use fileName again; instead, you use
fileReader
119
Using a stream



open
use
close
Some streams can be used only for input, others only for
output, still others for both
Using a stream means doing input from it or output to it
But it’s not usually that simple--you need to manipulate
the data in some way as it comes in or goes out
120
Example of using a stream
open
use
close
int ch;
ch = fileReader.read( );


The fileReader.read() method reads one character and
returns it as an integer, or -1 if there are no more
characters to read
The meaning of the integer depends on the file encoding
(ASCII, Unicode, other)
121
Manipulating the input data



open
use
close
Reading characters as integers isn’t usually what you
want to do
A BufferedReader will convert integers to characters;
it can also read whole lines
The constructor for BufferedReader takes a
FileReader parameter:
BufferedReader bufferedReader =
new BufferedReader(fileReader);
122
Reading lines
open
use
close
String s;
s = bufferedReader.readLine( );

A BufferedReader will return null if there is
nothing more to read
123
Closing





open
use
close
A stream is an expensive resource
There is a limit on the number of streams that you can
have open at one time
You should not have more than one stream open on the
same file
You must close a stream before you can open it again
Always close your streams!
124
Simple Java I/O
Part II
LineReader and LineWriter
28-Mar-16
Text files

Text (.txt) files are the simplest kind of files




text files can be used by many different programs
Formatted text files (such as .doc files) also contain
binary formatting information
Only programs that “know the secret code” can
make sense of formatted text files
Compilers, in general, work only with text
126
My LineReader class
class LineReader {
BufferedReader bufferedReader;
LineReader(String fileName) {...}
String readLine( ) {...}
void close( ) {...}
}
127
Basics of the LineReader constructor

Create a FileReader for the named file:
FileReader fileReader =
new FileReader(fileName);

Use it as input to a BufferedReader:
BufferedReader bufferedReader =
new BufferedReader(fileReader);

Use the BufferedReader; but first, we need to
catch possible Exceptions
128
The full LineReader constructor
LineReader(String fileName) {
FileReader fileReader = null;
try { fileReader = new FileReader(fileName); }
catch (FileNotFoundException e) {
System.err.println
("LineReader can't find input file: " + fileName);
e.printStackTrace( );
}
bufferedReader = new BufferedReader(fileReader);
}
129
readLine
String readLine( ) {
try {
return bufferedReader.readLine( );
}
catch(IOException e) {
e.printStackTrace( );
}
return null;
}
130
close
void close() {
try {
bufferedReader.close( );
}
catch(IOException e) { }
}
131
How did I figure that out?


I wanted to read lines from a file
I thought there might be a suitable readSomething method,
so I went to the API Index






Note: Capital letters are all alphabetized before lowercase in the Index
I found a readLine method in several classes; the most
promising was the BufferedReader class
The constructor for BufferedReader takes a Reader as an
argument
Reader is an abstract class, but it has several implementations,
including InputStreamReader
FileReader is a subclass of InputStreamReader
There is a constructor for FileReader that takes as its
argument a (String) file name
132
The LineWriter class
class LineWriter {
PrintWriter printWriter;
LineWriter(String fileName) {...}
void writeLine(String line) {...}
void close( ) {...}
}
133
The constructor for LineWriter
LineWriter(String fileName) {
try {
printWriter =
new PrintWriter(
new FileOutputStream(fileName), true);
}
catch(Exception e) {
System.err.println("LineWriter can't " +
"use output file: " + fileName);
}
}
134
Flushing the buffer




When you put information into a buffered output
stream, it goes into a buffer
The buffer may not be written out right away
If your program crashes, you may not know how
far it got before it crashed
Flushing the buffer is forcing the information to be
written out
135
PrintWriter



Buffers are automatically flushed when the program
ends normally
Usually it is your responsibility to flush buffers if
the program does not end normally
PrintWriter can do the flushing for you
public PrintWriter(OutputStream out,
boolean autoFlush)
136
writeLine
void writeLine(String line) {
printWriter.println(line);
}
137
close
void close( ) {
printWriter.flush( );
try { printWriter.close( ); }
catch(Exception e) { }
}
138
Simple Java I/O
Part III
JChoosers
28-Mar-16
About JFileChoosers



The JFileChooser class displays a window from
which the user can select a file
The dialog window is modal--the application cannot
continue until it is closed
Applets cannot use a JFileChooser, because applets
cannot access files
140
Typical JFileChooser window
141
JFileChooser constructors

JFileChooser()


JFileChooser(File currentDirectory)


Creates a JFileChooser starting from the user’s directory
Constructs a JFileChooser using the given File as the path
JFileChooser(String currentDirectoryPath)

Constructs a JFileChooser using the given path
142
Useful JFileChooser methods I

int showOpenDialog(Component
enclosingJFrame);


int showSaveDialog(Component enclosingJFrame);


Asks for a file to read; returns a flag (see below)
Asks where to save a file; returns a flag (see below)
Returned flag value may be:



JFileChooser.APPROVE_OPTION
JFileChooser.CANCEL_OPTION
JFileChooser.ERROR_OPTION
143
Useful JFileChooser methods II

File getSelectedFile()



showOpenDialog and showSaveDialog return a flag telling
what happened, but don’t return the selected file
After we return from one of these methods, we have to ask the
JFileChooser what file was selected
If we are saving a file, the File may not actually exist yet
144
Using a File

Assuming that we have successfully selected a File:


File file = chooser.getSelectedFile();
if (file != null) {
String fileName = file.getCanonicalPath();
FileReader fileReader = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fileReader);
}
File file = chooser.getSelectedFile();
if (file != null) {
String fileName = file.getCanonicalPath();
FileOutputStream stream = new FileOutputStream(fileName);
writer = new PrintWriter(stream, true);
}
145
Simple Java I/O
Part IV
Serialization
28-Mar-16
Serialization




You can also read and write objects to files
Object I/O goes by the awkward name of serialization
Serialization in other languages can be very difficult,
because objects may contain references to other objects
Java makes serialization (almost) easy
147
Conditions for serializability

If an object is to be serialized:




The class must be declared as public
The class must implement Serializable
The class must have a no-argument constructor
All fields of the class must be serializable: either
primitive types or serializable objects
148
Implementing Serializable


To “implement” an interface means to define all the
methods declared by that interface, but...
The Serializable interface does not define any
methods!


Question: What possible use is there for an interface that does
not declare any methods?
Answer: Serializable is used as flag to tell Java it needs to do
extra work with this class
149
Writing objects to a file
ObjectOutputStream objectOut =
new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(fileName)));
objectOut.writeObject(serializableObject);
objectOut.close( );
150
Reading objects from a file
ObjectInputStream objectIn =
new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(fileName)));
myObject = (itsType)objectIn.readObject( );
objectIn.close( );
151
What have I left out?



Encrypted files, compressed files, files sent over
internet connections, ...
Exceptions! All I/O involves Exceptions!
try { statements involving I/O }
catch (IOException e) {
e.printStackTrace ( );
}
152
Threads and Multithreading
28-Mar-16
Multiprocessing



Modern operating systems are multiprocessing
Appear to do more than one thing at a time
Three general approaches:



Cooperative multiprocessing
Preemptive multiprocessing
Really having multiple processors
154
Multithreading




Multithreading programs appear to do more than one
thing at a time
Same ideas as multiprocessing, but within a single
program
More efficient than multiprocessing
Java tries to hide the underlying multiprocessing
implementation
155
Why multithreading?

Allows you to do more than one thing at once




Play music on your computer’s CD player,
Download several files in the background,
while you are writing a letter
Multithreading is essential for animation


One thread does the animation
Another thread responds to user inputs
156
Threads

A Thread is a single flow of control



When you step through a program, you are following a
Thread
Your previous programs all had one Thread
A Thread is an Object you can create and control
157
Sleeping

Every program uses at least one Thread

Thread.sleep(int milliseconds);



A millisecond is 1/1000 of a second
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
sleep only works for the current Thread
158
States of a Thread

A Thread can be in one of four states:






Ready: all set to run
Running: actually doing something
Waiting, or blocked: needs something
Dead: will never do anything again
State names vary across textbooks
You have some control, but the Java scheduler has more
159
State transitions
waiting
start
ready
running
dead
160
Two ways of creating Threads

You can extend the Thread class:



Or you can implement the Runnable interface:



class Animation extends Thread {…}
Limiting, since you can only extend one class
class Animation implements Runnable {…}
requires public void run( )
I recommend the second for most programs
161
Extending Thread


class Animation extends Thread {
public void run( ) { code for this thread }
Anything else you want in this class
}
Animation anim = new Animation( );




A newly created Thread is in the Ready state
To start the anim Thread running, call anim.start( );
start( ) is a request to the scheduler to run the Thread --it
may not happen right away
The Thread should eventually enter the Running state
162
Implementing Runnable


class Animation implements Runnable {…}
The Runnable interface requires run( )




Animation anim = new Animation( );
Thread myThread = new Thread(anim);
To start the Thread running, call myThread.start( );


This is the “main” method of your new Thread
You do not write the start() method—it’s provided by Java
As always, start( ) is a request to the scheduler to run the
Thread--it may not happen right away
163
Starting a Thread





Every Thread has a start( ) method
Do not write or override start( )
You call start( ) to request a Thread to run
The scheduler then (eventually) calls run( )
You must supply public void run( )

This is where you put the code that the Thread is
going to run
164
Extending Thread: summary
class Animation extends Thread {
public void run( ) {
while (okToRun) { ... }
}
}
Animation anim = new Animation( );
anim.start( );
165
Implementing Runnable: summary
class Animation extends Applet
implements Runnable {
public void run( ) {
while (okToRun) { ... }
}
}
Animation anim = new Animation( );
Thread myThread = new Thread(anim);
myThread.start( );
166
Things a Thread can do







Thread.sleep(milliseconds)
yield( )
Thread me = currentThread( );
int myPriority = me.getPriority( );
me.setPriority(NORM_PRIORITY);
if (otherThread.isAlive( )) { … }
join(otherThread);
167
Animation requires two Threads



Suppose you set up Buttons and attach Listeners to
those buttons...
…then your code goes into a loop doing the
animation…
…who’s listening?


Not this code; it’s busy doing the animation
sleep(ms) doesn’t help!
168
How to animate

Create your buttons and attach listeners in your first
(original) Thread
Create a second Thread to run the animation
Start the animation
The original Thread is free to listen to the buttons

However,





Whenever you have a GUI, Java automatically creates a
second Thread for you
You only have to do this yourself for more complex programs
169
Things a Thread should NOT do


The Thread controls its own destiny
Deprecated methods:





myThread.stop( )
myThread.suspend( )
myThread.resume( )
Outside control turned out to be a Bad Idea
Don’t do this!
170
How to control another Thread




Don’t use the deprecated methods!
Instead, put a request where the other Thread can
find it
boolean okToRun = true;
animation.start( );
public void run( ) {
while (controller.okToRun) {…}
171
A problem
int k = 0;
Thread #1:
k = k + 1;


Thread #2:
System.out.print(k);
What gets printed as the value of k?
This is a trivial example of what is, in general, a
very difficult problem
172
Tools for a solution

You can synchronize an object:



You can synchronize a method:



synchronized (obj) { ...code that uses/modifies obj... }
No other code can use or modify this object at the same time
synchronized void addOne(arg1, arg2, ...) { code }
Only one synchronized method in a class can be used at a time
(other methods can be used simultaneously)
Synchronization is a tool, not a solution—
multithreading is in general a very hard problem
173