Introduction to Java 2 Programming

Download Report

Transcript Introduction to Java 2 Programming

Introduction to Java 2
Programming
Lecture 5
Quick Recap; Error-handling
Overview
• Quick Recap
– We’re half way through!
– Review some of the material we’ve already
covered
– Walk through some of the exercises
• Java Error Handling
– Handling and creating Exceptions
The CLASSPATH
• The CLASSPATH is
–
–
–
–
How Java finds compiled classes
A system property
Contains directories and/or jar files
Is a common source of frustration!
• Classify Java tools into three groups:
– File based
– CLASSPATH based
– And “mixed mode” (I.e. used both)
The CLASSPATH
• File based tools (e.g. javadoc, jar)
– Accept parameters referring to files.
– Read the directory structure to find related files
javadoc c:\intro2java\src\intro2java\*.java
– Result in file-based errors
• CLASSPATH based tools (e.g. java, javap)
– Refer to classes and not files
– Ignore the file-system, except for those directories
mentioned in the CLASSPATH
java intro2java.Person
– Result in exceptions or errors, e.g.
ClassNotFoundException; NoClassDefFoundErrors
The CLASSPATH
• Mixed mode tools (e.g. javac)
– Accept parameters referring to files
– Read the CLASSPATH to find related classes
javac c:\intro2java\src\intro2java\*.java
– Results in file errors (relating to parameters),
and “cannot resolve symbol” errors (relating to
missing classes)
CLASSPATH Tips
• Always add “the current working directory” to the
CLASSPATH
SET CLASSPATH=%CLASSPATH%;.
• Keep classes and source separate (e.g. bin and src
directories)
• Use a “global” classes directory, e.g. c:\classes
– Add this to the CLASSPATH
– Always compile into that directory
SET CLASSPATH=%CLASSPATH%;c:\classes
javac –d c:\classes *.java
Constructors
• Why do we use them?
– Give us chance to ensure our objects are properly
initialised
– Can supply default values to member variables
– Can accept parameters to allow an object to be
customised
– Can validate this data to ensure that the object is created
correctly.
• A class always has at least one constructor
– …even if you don’t define it, the compiler will
– This is the default constructor
Constructors
public class EmailAddress
{
public EmailAddress(String address)
{
if (address.indexOf(“@”) == -1)
{
//not a valid address, signal an error?
}
//must be valid…
}
//methods
}
Constructors
• When do they get called?
– When we use the new keyword
– Cannot be called explicitly like other methods
– But one constructor can refer to another, using the
super keyword
EmailAddress myAddress = new EmailAddress(“[email protected]”);
• Constructors and inheritance
– An object must ensure that its parent is properly
initialised, by calling one of its constructors
– Example…
Constructors
public class Parent {
private String msg;
public Parent(String message) {
msg = message;
}
}
public class Child {
public Child()
{
super("Parent message");
}
}
Inheritance
• What happens when we call a method?
– The JVM tries to find the implementation of that method and
execute the code
– Starts searching with the objects class, then works upward to its
parent…its parent’s parent…etc, etc.
• When do we override a method?
– When we want to change the implementation, either completely or
partially
• To completely change the implementation, just define a
new version
• To partially change the implementation use the super
keyword to refer to the parent implementation
Inheritance – Using Super
• In an E-Commerce system we might have a class
responsible for calculating prices e.g:
public class Pricer
{
public float calculatePrice(Product p)
{
//implementation details irrelevant for example
}
}
• The Product parameter lets the Pricer calculate the price
Inheritance – Using Super
• Assume we want to extend this functionality so that the
calculation also includes tax (i.e. adding on VAT).
• US purchases don't include tax, but UK ones do, so we
can't just rewrite the original method.
• Instead we create a subclass, called UKPricer that does
the extra work.
public class UKPricer extends Pricer
{
public float calculatePrice(Product p)
{
//this implementation will also add on VAT…
}
}
Inheritance – Using Super
• Ideally we want to reuse the code in the base class, as all we
need to do is add on the extra 17.5% to the final price.
• We can do better than copy-and-paste using super…
public class UKPricer extends Pricer
{
public float calculatePrice(Product p)
{
//call the superclass method
float withoutTax = super.calculatePrice(p);
float tax = withoutTax * 17.5 / 100;
return withoutTax + tax;
}
}
Controlling Inheritance
• Inheritance can be restricted using the final
keyword
– Applies to both methods and classes
– A final class cannot be extended
– A final method cannot be overridden
• Inheritance can be forced by using the abstract
keyword
– Again applies to both methods and classes
– An abstract class must be extended, cannot be used to
create objects
– An abstract method must be overrided by a sub-class
Encapsulation
• Encapulation is information hiding, but what to
hide?
– Everything that isn’t part of the interface (contract) of
an object
– This means all member variables
• Encapulation is enforced in Java by the visibility
modifiers
– Public, protected, private, and package access
– Modifiers can be applied to variables, methods and
classes
Visibility Modifiers
Modifier
Class
Subclass Package
Private
X
Protected
X
X
X
Public
X
X
X
Package
X
X
World
X
Passing Parameters
• Java has two ways of passing parameters
– Pass by Reference
– Pass by Value
• Pass by Value applies to primitive types (int,
float, etc)
• Pass by Reference applies to objects and
arrays
Passing Parameters
public class PassByValueTest
{
public static void add(int x)
{
x++;
}
public static void main(String[] args)
{
int x = 0;
System.out.println(x);
add(x);
System.out.println(x);
}
}
Passing Parameters
public class PassByReferenceTest
{
public static void reverse(StringBuffer buffer)
{
buffer.reverse();
}
public static void main(String[] args)
{
StringBuffer buffer = new StringBuffer(“Hello”);
System.out.println(buffer);
reverse(buffer);
System.out.println(buffer);
}
}
Upcasting
• Inheritance describes an isA relationship
– E.g. A MotorVehicle isA type of Vehicle
• Parent and child objects share a base type
– So children can be treated as if they were an
instance of the parent
– This is known as upcasting
Upcasting
• The type of the object determines its possible
behaviours
– Because we define them in the class
• The object reference limits the behaviours we can
invoke to those defined by the type of the
reference
– If an child class is upcast we can only invoke the base
class methods
– We’ve “forgotten” the real type of the object
Upcasting Example 1
• Parent and Child
Upcasting Example 2
• PersonViewer, need to change references
• Key to understanding this is that the
compiler doesn’t determine the method to
call at compile time, but at runtime –
dynamic binding.
• This is Polymorphism
Method Overloading
• Already introduced overriding
• Overloading is defining methods with the
same name, but different parameters
• Enhanced Person Viewer example
Error Handling in Java
• Java uses Exceptions to handle errors
– Events that happen whilst running a program that
disrupts the normal flow of instructions
• Exceptions can range in severity
– Hardware or memory problems
– Program errors; Bugs, etc.
• Exceptions are objects
– Carry message, and state about what the program was
doing when the problem was encounter
– Because Exceptions are objects, you can subclass them
to create your own
Exceptions
• Exceptions are handled by separate blocks
of code (exception handlers)
– Separates error handling from normal code
– Better than return codes
• JVM is responsible for finding an error
handler for each exception
– Walks backwards through the call stack
– If it can’t find one, then the JVM will exit
Exceptions – Terminology
• Throwing an exception
– Creating an Exception object, and asking the JVM to
deal with it
• Catching an exception
– Dealing with the Exception object.
– Exception handlers catch exceptions
• Stack Trace
– Debug information about the application state (call
stack) when Exception was generated.
Exceptions – Syntax
• Throwing an Exception
• Create a new Exception object (actually one
of its subclasses)
• Use the throw keyword to ask Java to deal
with it
throw new Exception(“error message”);
Exceptions – Syntax
• Identifying methods that throw exceptions
• Added a throws keyword to the method definition
public void readFile throws IOException, FileNotFoundException
{
//..code...
}
• A method must list all exceptions that are thrown
in the method body
– Otherwise encounter compilation errors
Exceptions – Syntax
• Throwing an Exception
• Create a new Exception object (actually one
of its subclasses)
• Use the throw keyword to ask Java to deal
with it
throw new Exception(“error message”);
Exceptions – Syntax
• Handling exceptions
• Use a try..catch block
try {
readFile();
} catch (FileNotFoundException fe) {
//handler for file not found
} catch (IOException ioe) {
//handler for general I/O exceptions
}
Exceptions – Syntax
• Alternatively use a try..catch..finally block
• The finally clause is always executed and is
used for critical clean-up
try {
readFile();
} catch (IOException ioe) {
//handler for general I/O exceptions
} finally {
//ALWAYS run
closeFile();
}
Exceptions – Syntax
• Viewing the stack trace
Exception.printStackTrace();
• Example
Exceptions – Syntax
java.lang.Exception: Error message
at
intro2java.GenerateStackTrace.methodThree(GenerateSta
ckTrace.java:18)
at
intro2java.GenerateStackTrace.methodTwo(GenerateStack
Trace.java:13)
at
intro2java.GenerateStackTrace.methodOne(GenerateStack
Trace.java:8)
at
intro2java.GenerateStackTrace.main(GenerateStackTrace
.java:27)
Exceptions – Syntax
• Defining new types of Exceptions is easy,
just sub-class an existing one.
public MyException extends Exception
{
public MyException() { … }
public MyException(String msg) { super(msg); }
}