Download Lecture 5. The Core Java Language – Packages and Exceptions

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Programming for
Geographical Information Analysis:
Core Skills
Lecture 6:Using others’ code II:
Packages and Exceptions
Review
Classes contain variables and methods.
We can turn these into objects containing data and methods.
We can limit who sees these using:
public
:everyone can use it.
private
:only the code in the class can use it.
protected : only inheriting code can use it.
We can also set them as static – meaning we can use the
methods without making an object.
Review
We can turn (super)classes into subclasses.
E.g. a Point class can be used to make a Land class.
Subclasses invisibly pick up all the superclass code and can use
the public bits.
Alternatively we can use Interfaces, which are a set of
promises.
extends : you get everything.
implements : you promise everything.
If a method expects a parent type, it can take a subclass in, but
can only use parent methods and variables.
This lecture
Packages
Exceptions
Documentation
Packages
Packages are groups of classes.
Often you put an application in its own package.
Also ‘libraries’ of useful classes.
Packages allow us to use other people’s code.
Saves name clashes with other people.
Namespace
Packages are named after the directory they are in.
Directory structures should reflect your internet address.
This means we know where classes are on our machine, and
who wrote them.
You should build up package hierarchies. E.g…
/uk/ac/leeds/mass/
/uk/ac/leeds/mass/aevans/
One package for everyone, one specifically for aevans’ use.
Note that directories can’t just start with numbers. All package
names and directories should be lowercase.
Naming packages
The name is each directory name separated by dots:
/uk/ac/leeds/mass/
uk.ac.leeds.mass
A class is declared as being in a package before its class
declaration:
package uk.ac.leeds.mass;
public class MyClass {
}
Using packages
If we want to use a class we haven’t written, we need to
import it:
package uk.ac.leeds.mass;
import java.awt.Point;
class MyClass {
public static void main (String args[]) {
Point p = new Point();
}
}
Equally we can import a whole package if we want to use several
Classes in it…
import java.awt.*;
No major overhead – just directs compiler to find the files, doesn’t put
them all in your program.
Alternative is to give the full classname:
java.awt.Point a = new java.awt.Point();
But this only really worthwhile if two imported packages (or your own
package) have the same class name in them.
Note, though, not hierarchical:
import java.awt.*;
Doesn’t import:
import java.awt.events.*;
Compiling and running with packages
How do the compiler and interpreter know where different
packages are?
java.lang invisibly available (e.g. java.lang.System).
Other core java packages need importing, but found
automatically.
For others, they look in the CLASSPATH environment variable
for the directories where they should start looking for the tree.
This path usually contains “.”, which directs them to the current
directory.
Directory trees
If we want to compile a class in
presidents we have to run the
compiler from the src directory, with
the command…
javac us\gov\presidents\Obama.java
or
javac us\gov\presidents\*.java
to compile everything.
If we use a uk.ac.leeds.geog class
in Obama, that will also be found because
the directory tree starts the same place.
To run we use the full name of the main
class:
java us.gov.presidents.Obama
CLASSPATH
But what if the trees don’t start in the same place?
We set the environmental variable ‘CLASSPATH’.
Environmental variables are just variables all computers keep
which store user preferences. You can tell the ‘javac’ and ‘java’
programs the classpath using…
javac –classpath path;path; File.java
(in UNIX: path:path)
The programs will look in any directory listed in the CLASSPATH
for the start of directory trees.
One path should be “.” if you want to include the present
directory.
Note that if your code is unpackaged this can become quite
complicated, as the classpath must include the directory your
code is running from, and the root of the hierarchy. Assuming
you are in the latter, you'll need this kind of thing:
javac unpackaged/lazyCode/*.java
java -classpath unpackaged/lazyCode/;. MyClass
What you CAN'T do is this:
java unpackaged/lazyCode/MyClass
The JVM will just assume you're trying to run from a package.
IDEs/jar
Most IDEs will put files in their own structure.
They will construct the –classpath option suitably when they
run.
They generally also allow you to add extra libraries, and sort
out the classpath for you.
These are often in the form of jar files. Jar files are zip files with
an extra text file. IDEs sometimes generate these from your
code, as you can set them to run when double clicked in
Windows etc.
You can make them yourself using the jar tool:
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/j
ar.html
Example: Array alternatives
‘Collection’ classes in java.util that allow you to store stuff.
Pros: these are like arrays, but store anything, and expand
automatically.
Cons: tend to be less efficient than arrays and can take up a
lot of space if you’re not careful.
java.util.Vector
java.util.ArrayList
java.util.Stack
java.util.Hashtable
java.util.Properties
java.util.Bitset
java.util.Enumeration
Objects
How do they store anything?
Most objects we create automatically inherit from a built in class
called “java.lang.Object”.
This is useful, because it allows us to make storage classes that can
store anything.
Their storage methods take in generic objects.
This means we have to cast anything in them back to the proper
class.
Vector
Like an array, however, of variable size.
Vector()
Vector(int size)
Vector(int size, int increment)
When full, the Vector doubles in size, or increases by the
increment given.
Vector methods
addElement(Object ob)
insertElementAt(Object ob, int index)
Add elements in at the top or index position.
elementAt(int index)
Gets an element at the index position.
contains(Object ob)
Checks the object is in the Vector.
Example
import java.util.*;
public class GIS {
Vector store = new Vector(5,5);
public GIS () {
Point p = new Point();
store.add(p, 10);
// some time later
for (int i = 0; i < store.size(); i++) {
Point p1 = (Point) store.elementAt(10);
}
}
}
Review
To use others’ code:
Import the package/classes.
Make sure you are compiling from the right location, or set
the classpath.
This lecture
Packages
Exceptions
Documentation
Problems
Encapsulation demands that we don’t need to know what
goes on in other’s classes.
Fine and dandy, but what if our code causes their code to
break horribly?
FileReader f = new FileReader(someFileThatDoesn’tExist);
To understand the framework for dealing with this, we need to
understand Exceptions.
Exceptions
When something goes wrong we don’t want the program to crash.
We want some way of doing something about it.
When the JVM detects an problem, it generates an Exception object
at that point in the running code which represents that problem.
We can catch these and do something with them.
For example, if you try and add something to an array outside its size
the JVM makes an object of type…
ArrayIndexOutOfBoundsException
Exceptions
Different problems generate different exceptions.
If we build classes other people will use, we can define our
own exceptions that are generated when the classes are
misused.
We call this ‘throwing’ an exception.
If code potentially throws an exception, we must deal with
the potentially thrown exception.
Catching exceptions
try {
Operations that throw an exception.
} catch (ExceptionType anyName) {
Operations that deal with the anyName exception.
}
The catch statement is the ‘Exception Handler’.
The code stops acting at the problem point and jumps to the
handler.
Example
try {
FileWriter f = new FileWriter(someFile);
} catch (Exception e) {
return “File not found”;
}
f.write(“Hello World”);
Though this looks fine, there’s a scope problem.
Example
FileWriter f = null;
try {
f = new FileWriter(someFile);
} catch (Exception e) {
return “File not found”;
}
f.write(“Hello World”);
Note the separation of the variable label creation from the
object creation to avoid scoping issues.
Different problem objects
Exceptions are subclasses of a broader class Throwable.
Two main subclass branches…
Errors
Exceptions
Error objects are used in catastrophic system problems.
Exceptions are more frequent.
One of the most common subclasses of Exception is the
RuntimeException.
Propagating
RuntimeExceptions can be left uncaught.
In this case they ‘propagate’ through the code.
The code stops at the problem point and jumps to where the
method was called, and the exception object gets passed to that
point.
This continues until the main method is reached if it’s not handled.
The default handler then handles the problem.
Usually the program breaks and a ‘stack trace’ is printed. This lists all
the methods the problem has propagated through.
public class RubbishMaths {
Example
public RubbishMaths() {
int answer = 12/0;
}
}
public class MathsExample {
public static void main (String args[]) {
RubbishMaths r = new RubbishMaths();
}
}
Nesting catches
Note that the relationship between subclasses and their
parent class means that we can nest catches…
try {
try {
// Operation
} catch (RuntimeException rte) {
// Do something with rte.
}
} catch (Exception e) {
// Do something with e if it’s not a RuntimeException.
}
Laddered catches
try {
// Operation
} catch (OurException oe) {
// Do something with oe
} catch (Exception e) {
// Do something with e if it’s not of type
// OurException.
}
What to do with Exceptions
All exceptions except RuntimeExceptions, must be caught.
The usual thing in debugging is to print the error and the stack trace.
e.printStackTrace();
Can also write its name to a standard error log…
System.err.println(e);
…but this is usually the screen anyhow.
In a real program we should do something about the error so the
user doesn’t get a message.
Finally
If there’s something you want to happen, even if there is an
error, you should put it in a ‘finally’ block under your ‘try’.
Finally blocks are always executed, even if written after
returns.
try {
// Operation.
} catch (Exception e) {
// Do something with e.
} finally {
// Do something important.
}
Making Exceptions
By saying that a method or an object must catch an
exception, we can force programmers using our objects to
prepare for problems.
We can use the keyword throws to do this.
If someone uses our object they must catch the thrown
object or throw it again.
Eventually something must deal with it, or the program
won’t compile.
Creating our own Exceptions
Subclass the class ‘Exception’ to make a new exception class, eg.
public class OurException extends Exception {
In our main class, declare that a method will be throwing an
object if everything goes wrong…
public void name () throws OurException {
At some point in the code, throw the exception…
throw new OurException();
Summary
Exceptions and Errors give us a chance to manage problems
without the user knowing.
The also allows us to force people who use our classes to deal
with problems we know may arise.
Exceptions can be caught and handled, or thrown out of the
method for someone else to deal with.
Exceptions propagate back through all the method calls and
objects inside one another until they reach a suitable handler.
Review
try {
// whatever
} catch (ExceptionType label) {
// fix stuff
}
This lecture
Packages
Exceptions
Documentation
The Java Packages
We’ve now seen most of the core language.
Some of this is actually in the package java.lang, for
example, the System and Math Classes. These you don’t
have to import - java.lang is always there for you.
The rest of Java is in packages that do specific stuff.
We’ll spend the rest of the course looking at packages you can
use.
import java.io.*;
Example
public class Write {
public Write() {
FileWriter f = null;
try {
f = new FileWriter (someFile);
} catch (IOException ioe) {
ioe.printStackTrace();
}
f.write(“Hello World”);
f.close();
}
public static void main (String args[]) {
new Write();
}
}
Some of the main packages
java.io (file reading/writing)
java.awt and javax.swing (windows applications)
java.applet (web applications)
java.net (network communication)
java.util and java.lang (bits and pieces)
But, how do we know how to use these packages and classes?
Documentation
We’ve seen that we should comment our code for
developers, using // comments.
But that relies on seeing our code.
Better to supply API (Application Programming Interface)
documentation that says what each class and method
does.
One of the great things about Java is that comments can
(and should) be written so that they can be automatically
turned into documents about the programs.
You do this with the ‘javadoc’ program.
The Docs
Each class in the core language has a webpage
that lists its variables and methods, along with
examples of use.
The two comment types
Comments you don’t want to put in the documentation start // After
this you can’t write code on the same line, just comments E.g.,
// End of Class.
}
// This bit of code calculates horror
// on a rating of one to ten.
Comments you want in the documentation should be associated
with a block or object and be laid out thus…
/**
* This is a class for working out
* how long we’ve been sat here.
*/
The documentation
The documentation comes out as webpages.
This means that if you can write HTML you can format
your documentation.
The ‘docs’ (as we pros like to call them) list
the methods, what you pass to them and get out of them,
any important variables,
other info.
They're available for all the core classes and interfaces:
http://docs.oracle.com/javase/8/docs/api/
Generics
Only thing you won’t recognise in the docs is the use of angle
brackets, thus:
Class Vector<E>
add(E e)
Or
containsAll(Collection<?> c)
addAll(Collection<? extends E> c)
These mean the class stores java.lang.Object type objects, but can
be forced to be more specific to reduce potential casting errors.
Example
These storage objects can be parameterized. i.e. they can be given
a specific type other than Object.
Vector<String> v = new Vector<String>();
You can also declare these in Method parameters…
void myMethod(Vector<String> v) {
You can build your own parameterizable types that take in Classes
of a particular type…
class ClassName<T extends OptionalClass> {
private Vector<T> items = new Vector<T>();
void add(T item) {
}
T get(int index){
items.add(item);
}
return items.get(index);
}
Find your class or package, and click on the link.
Docs
Practical
Documentation
Next lecture
Reading and writing files
Assessment 1
Take the code so far, and add in image processing
routine.
You’ll get additional classes to:
Provide you with proper data.
Display a 2D double array as an image.
Advice
The core element is looping through a 2D array using
nested loops.
In the loop, you’ll need to collect the values of neighbouring
cells (see lecture 3).
Because of this, you’ll need to think about boundary
problems. The easiest starting point for these is to adjust
the loop counter so it runs from, e.g.
int i = 1; i < array.length – 1; i++
Marks
Code that does the job.
Efficient but clear algorithm.
Well thought through boundary.
Clearly laid out code.
Well documented.
Extras.