In this tutorial you will learn more Java and will look at exceptions and assertions in Java. This will allow you to write a simple Java app that you can then use in your IDE
About this Tutorial –
Objectives –
This course is aimed at object-oriented developers (e.g. C++ or C#) who need to transition into Java. It is also aimed at those learning to program for the first time; the course covers the Java programming constructs and APIs quickly, focussing on the differences between Java and other OO languages.
Audience
This training course is aimed at OO developers who need to transition into Java.
Prerequisites
No previous experience in Java programming is required. But any experience you do have in programming will help. Also no experience in eclipse is required. But again any experience you do have with programming development environments will be a valuable.
Experience using a contemporary OO language such as C++ or C# would be useful but is not required.
Contents
The Java course cover these topics and more:
- Flow Control: Decision making: if and if-else; The switch statement; Looping: for loops; while loops; do-while loops; for-each style loops; Assertionsv
- Concurrency: Overview of multithreading; Creating new threads; Object locking; Using wait, notify, and notifyAll
- Collections: Overview of Java SE collection classes; Generics; Using List-based collection classes; Using Set-based collection classes; Using Map-based collection classes; Collection techniques
Exam Preparation
The Java course will help you prepare for these certifications:
- Oracle Certified Java Associate – Exam 1Z0-803
- Oracle Certified Java Professional – Exam 1Z0-804
Quick Access
Overview
Estimated Time – 1.5 Hours
Not what you are looking? Try the next tutorial – Inner Classes
Lab 1: Exceptions
- Overview
- Exceptions are a run-time mechanism for indicating exceptional conditions in Java
- If you detect an “exceptional” condition, you can throw an exception
- An exception is an object that contains relevant error info
- Somewhere up the call stack, the exception is caught and dealt with
- If the exception is not caught, your application terminates
- Exceptions are a run-time mechanism for indicating exceptional conditions in Java
- Categories of Exceptions in Java
- There are lots of things that can go wrong in a Java app
- Therefore, there are lots of different exception classes
- Each exception class represents a different kind of problem
- The Java library defines hundreds of standard exception classes (see later for some examples)
- Java classifies exceptions into 3 categories:
- There are lots of things that can go wrong in a Java app
- What Exceptions do you have to Catch?
- How do you know what exceptions you have to catch in your code?
- Try to compile your code, the compiler will tell you soon enough
- Alternatively, take a look in JavaDoc for a method call, and it will tell you the list of checked exception you have to catch
- Example
- See the JavaDoc for the FileWriter constructor
- You’ll see that it throws an IOException
- You MUST deal with this exception in your code (why?)
- How do you know what exceptions you have to catch in your code?
- How to Handle Exceptions
- try block
- Contains code that might cause an exception
- catch block(s)
- Zero or more
- Specify an exception class, to catch exception object
- Perform recovery code
- finally block (optional)
- Will always be executed
- Perform tidy-up code
- Note:
- try must be followed immediately by catch and/or finally
- Code Example:
try {
// Code that might cause an exception ...
} catch (ExceptionType1 ex) {
// Code to handle ExceptionType1...
} catch (ExceptionType2 ex) {
// Code to handle ExceptionType1...
}
...
finally {
// Performs unconditional tidying-up...
}
- try block
- Example
- This example illustrates simple exception handling
- Based on file I/O
import java.io.*;
...
public static void demoSimpleExceptions() {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter("Myfile.txt")));
out.println("Hello world.");
out.println("Thank you, and goodnight.");
}
catch (IOException ex) {
System.err.println(ex.getMessage());
}
finally {
if (out != null) {
out.close();
}
}
}
- View code file.
- Based on file I/O
- This example illustrates simple exception handling
- Exceptions Hierarchies
- Java organizes exceptions into an inheritance hierarchy
- Represents specializations of general error conditions
- Example
- When you define a catch handler:
- It will catch that exception type, plus any subclasses
- You can define multiple catch handlers
- When an exception occurs, the runtime examines the catch handlers in sequence, looking for a suitable handler
try {
...
}
catch (FileNotFoundException ex) {
...
}
catch (IOException ex) {
...
}
- When an exception occurs, the runtime examines the catch handlers in sequence, looking for a suitable handler
- Notes:
- You must organize your catch handlers from specific to general
- Don’t catch Exception (this would also catch runtime exceptions)
- Java organizes exceptions into an inheritance hierarchy
- Propagating Exceptions
- Imagine this scenario:
- You’re writing a low-level library class
- Lots of checked exception might occur
- You could catch these exceptions in your code, but you wouldn’t know what to do in your catch handlers
- You can propagate these exception(s) back to the caller:
- “I don’t know how to handle this, over to you”
- How to propagate checked exceptions
- Tag the method with a throws clause
- Specify a comma-separated list of checked exception types that might emanate from your method
void myMethod() throws CheckedExceptionType1, CheckedExceptionType2 ...{
...
}
- The compiler ensures the caller catches these exceptions
- Imagine this scenario:
- Rethrowing a Checked Exception
- Imagine this scenario:
- You’re writing a low-level library class
- You want to catch the checked exception locally, to do some intermediate processing (e.g. log the exception)
- Lots of checked exceptions might occur
- You also want to force the caller to do “full” processing
- You can catch and rethrow checked exceptions:
- Define a catch handler
- Do some local processing
- Use the throw keyword, to rethrow the checked exception object
try {
...
} catch (CheckedExceptionType1 ex) {
...
throw ex;
}
- Imagine this scenario:
- Throwing and catching runtime exceptions
- In Employee.java, locate the payRise() method
- Add code to throw runtime exceptions, as indicated by the TODO comments
// Give the employee a pay rise.
public double payRise(double amount) {
if (amount <= 0) { String message = String.format("Pay rise %.2f rejected, must be positive.", amount); throw new IllegalArgumentException(message); } else if (retired) { String message = String.format("Pay rise for %s rejected, employee is retired.", name); throw new IllegalStateException(message); } else { salary += amount; return salary; } } - View code file.
- Then in UsingCompany.java, add try/catch logic to deal with these exceptions
try {
... theCompany.giveEmployeePayRise(id, amount);
} catch (CompanyException ex) {
System.out.printf("Company exception: %s [id %s].\n", ex.getMessage(), ex.getId());
if (ex.getCause() != null) {
System.out.printf(" Cause: %s.\n", ex.getCause());
}
}
- View code file.
- Add code to throw runtime exceptions, as indicated by the TODO comments
- Run the application, and make sure all the options work as expected. For example, ensure the following behaviour is exhibited:
- You can't give an employee a negative pay rise, not even in the current economic climate!
- You can't give a retired employee a pay rise
- You can give a non-retired employee a positive pay rise
- In Employee.java, locate the payRise() method
Lab 2: Java SE 7 exception techniques
- Try with Resources
- In Java SE 7, the try syntax has been extended
- You can declare one or more objects in (), separated by ;
- The objects must implement java.lang.AutoCloseable
- The close() method is automatically closed after the try block
- Then any catch/finally code is executed
try (resource1; resource2; resource3; ...)
{
} // close() methods called here, in reverse order
- Usages:
- Guarantees resources are closed, neater that try/finally
- Many classes in Java SE 7 now implement AutoCloseable
- Example:
- See DemoTryWithResources.java
- In Java SE 7, the try syntax has been extended
- Handling Multiple Exception Types
- In Java SE 6, you must list catch handlers separately
- Can cause duplication in catch-handler blocks
- In Java SE 7, you can specify a single catch handler that is capable of handling multiple exception types
- Reduces duplication
- Jave SE 6
try {
...
}
catch (IOException ex) {
logger.log(ex);
throw ex;
}
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
- Jave SE 7
try {
...
}
catch (IOException | SQLException ex) {
logger.log(ex);
throw ex;
}
- In Java SE 6, you must list catch handlers separately
- Rethrowing Exceptions
- In Java SE 6, a throws clause can only specify the exact exceptions that are thrown
- Can be limiting if you're rethrowing exceptions
- In Java SE 7, a throws clause can specify any of the actual exceptions that might have been thrown
- The Java SE 7 compiler analyzes the try block more thoroughly
- Jave SE 6
public void func() throws Exception {
try {
if (...) throw ExA;
if (...) throw ExB;
}
catch (Exception e) {
// Do some stuff, then rethrow
throw e;
}
}
- Jave SE 7
public void func() throws ExA, ExB {
try {
if (...) throw ExA;
if (...) throw ExB;
}
catch (Exception e) {
// Do some stuff, then rethrow
throw e;
}
}
- In Java SE 6, a throws clause can only specify the exact exceptions that are thrown
- Defining a custom exception class
- In CompanyException.java, define a custom exception class named CompanyException
- The exception class should cater for the following information about a company-related problem:
- An error message
- The id of the employee that was being processed when the exception occurred
- An "inner exception" cause. This will enable a CompanyException object to encapsulate a lower-level technical exception object
public class CompanyException extends Exception {
private static final long serialVersionUID = 1L;
private String id;
public CompanyException(String message) {
super(message);
}
public CompanyException(String message, String id) {
super(message);
this.id = id;
}
public CompanyException(String message, Throwable cause, String id){
super(message, cause);
this.id = id;
}
public String getId() {
return id;
}
}
- View code file.
- Run the application, and make sure all the options work as expected
Lab 3: Exception classes
- Standard Exception Classes
- Defining Custom Exception Classes
- You can define your own domain-specific exception classes
- Define a class that extends Exception
- Define a string constructor, plus other constructors/methods
public class MyDomainException extends Exception {
private Date timestamp = new Date();
int severity = 0;
public MyDomainException(String message) {
super(message);
}
public MyDomainException(String message, int severity) {
super(message);
this.severity = severity;
}
public MyDomainException(String message, Throwable cause, int severity) {
super(message, cause);
this.severity = severity;
}
... // Getters for timestamp and severity
}
- View code file.
- You can define your own domain-specific exception classes
- Throwing Exceptions
- To throw an exception:
- Use the throw keyword
- Specify an exception object (typically a newly-created one)
- Example:
public static void demoCustomExceptions() {
try {
System.out.println("Hello from demoCustomExceptions()");
throw new MyDomainException("It's gone pear-shaped", 5);
}
catch (MyDomainException ex) {
System.err.printf("%s at %s, severity %d", ex.getMessage(),
ex.getTimestamp(),
ex.getSeverity());
}
- View code file.
- To throw an exception:
- Throwing and catching checked exceptions
- In Company.java, add code to throw CompanyException exceptions, as indicated by the TODO comments in the following methods:
- hireEmployee()
// Hire employee (i.e. add to company).
public void hireEmployee(Employee emp) throws CompanyException {
String id = emp.getId();
if (employees.containsKey(id)) {
throw new CompanyException("Cannot add employee, duplicate id.", id);
} else {
employees.put(id, emp);
}
}
- View code file.
- fireEmployee()
// Fire employee (i.e. remove employee from company).
public void fireEmployee(String id) throws CompanyException {
if (!employees.containsKey(id)) {
throw new CompanyException("Cannot remove employee, id not recognized.", id);
} else {
employees.remove(id);
}
}
- View code file.
- retireEmployee()
// Retire employee (but keep their info).
public void retireEmployee(String id) throws CompanyException {
Employee emp = employees.get(id);
if (emp == null){
throw new CompanyException("Cannot retire employee, id not recognized.", id);
} else {
emp.retire();
}
}
- View code file.
- giveEmployeePayRise()
// Give employee a pay rise.
public void giveEmployeePayRise(String id, double amount) throws CompanyException {
Employee emp = employees.get(id);
if (emp == null){
throw new CompanyException("Cannot give employee a pay rise, id not recognized.", id);
} else {
try {
emp.payRise(amount);
} catch (IllegalArgumentException ex) {
throw new CompanyException("Cannot give employee a payrise.", ex, id);
} catch (IllegalStateException ex) {
throw new CompanyException("Cannot give employee a payrise.", ex, id);
}
}
}
- View code file.
- hireEmployee()
- Then modify UsingCompany.java, to catch these exceptions
try {
... theCompany.giveEmployeePayRise(id, amount);
} catch (CompanyException ex) {
System.out.printf("Company exception: %s [id %s].\n", ex.getMessage(), ex.getId());
if (ex.getCause() != null) {
System.out.printf(" Cause: %s.\n", ex.getCause());
}
}
- View code file.
- In Company.java, add code to throw CompanyException exceptions, as indicated by the TODO comments in the following methods:
Lab 4: Assertions
- Coding without Assertions
- The following example shows the sort of code that you would write prior to assertions (i.e. prior to Java 1.4)
- Performs run-time tests for preconditions and postconditions
private static void testWithoutAsserts() {
try {
int tz1 = getTimeZoneWithoutAsserts(60);
if (tz1 != 4) {
System.out.println("Invalid timezone result: " + tz1);
}
int tz2 = getTimeZoneWithoutAsserts(200);
} catch (IllegalArgumentException ex) {
System.out.println(ex);
}
}
private static int getTimeZoneWithoutAsserts(int longitude) {
if (longitude < -180 || longitude >= 180) {
throw new IllegalArgumentException("longitude " + longitude + " out of range");
}
return longitude / 15;
}
}
- View code file.
- Performs run-time tests for preconditions and postconditions
- The following example shows the sort of code that you would write prior to assertions (i.e. prior to Java 1.4)
- Assertions Syntax
- Assertions are a Java 1.4 (onwards) mechanism for performing development-time tests
assert booleanTest;
assert booleanTest : exceptionMessage;
- Assertions causes the application to terminate via an AssertionError if the test fails
- Assertions are a Java 1.4 (onwards) mechanism for performing development-time tests
- Assertions Example
- The following example shows how to rewrite the previous code to use assertions
private static void testWithAsserts() {
int tz1 = getTimeZoneWithAsserts(60);
assert tz1 == 4 : "Invalid timezone result: " + tz1;
int tz2 = getTimeZoneWithAsserts(200);
}
private static int getTimeZoneWithAsserts(int longitude) {
assert longitude >= -180 && longitude < 180 : "longitude " + longitude + " out of range"; return longitude / 15; } - View code file.
- Here's the AssertionError for this example
- The following example shows how to rewrite the previous code to use assertions
- Compiling for Assertions
- From Java 1.4 compiler onwards:
- assert is treated as a keyword
- If you have legacy code that has identifiers (variables, methods, etc.) named assert:
- You'll get a compiler error in Java 1.4 onwards
- The only way to avoid the compiler error is to explicitly tell the java compiler to treat source code as Java 1.3 syntax:
javac -source 1.3 MyLegacyCode.java
- From Java 1.4 compiler onwards:
- Enabling and Disabling Assertions
- Assertions are disabled by default
- To enable assertions, specify these JVM arguments:
- -ea Enables assertions for all classes (except system classes)
- -esa Enables assertions for system classes
- To disable assertions, specify these JVM arguments:
- -da Disables assertions for all classes (except system classes)
- -dsa Disables assertions for system classes
- Note:
- -ea and -da enable you to enable/disable assertions for particular classes and/or packages (and sub-packages)
- Example:
java -ea:mypackage1 -ea:mypackage2 -da:mypackage1.SomeClass MyApp
- Best Practice
- Using assertions
- Open TestCompanyAndEmployee.java, and add code to test the various capabilities of your Employee class
- Retire -
// Ensure employees can retire.
aCompany.retireEmployee("2");
Employee retiredEmp = aCompany.getEmployee("2");
assert (retiredEmp != null) : "Could not get retired employee.";
assert (retiredEmp.isRetired()) : "Employee retirement not recorded properly.";
- View code file.
- Fired -
// Ensure employees can be fired.
aCompany.fireEmployee("3");
Employee firedEmp = aCompany.getEmployee("3");
assert (firedEmp == null) : "Spuriously got fired employee.";
- View code file.
- Get employees-
// Ensure we can get existing employees.
Employee emp1 = aCompany.getEmployee("1");
assert (emp1 != null) : "Could not get existing employee.";
// Ensure we can't get non-existent employees.
Employee noSuchEmp = aCompany.getEmployee("99");
assert (noSuchEmp == null) : "Spuriously got non-existent employee.";
- View code file.
- Retire -
- Hint: Call various methods, and use assert to ensure you get the expected results; the comments give you some suggestion - Don't forget to enable assertions before you run the application
- Open TestCompanyAndEmployee.java, and add code to test the various capabilities of your Employee class
Well done. You have completed the tutorial in the Java course. The next tutorial is
12. Inner Classes
Copyright © 2016 TalkIT®
If you would like to see more content like this in the future, please fill-in our quick survey.