Você está na página 1de 283

Java Foundations

n + 1, Inc Febuary 2008

Copyright (c) 2008 n + 1, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no BackCover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.

Page 2

c 2008 n + 1, Inc All Rights Reserved

Contents
1 Java Runtime Environment 1.1 Overview of J2SE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 1.1.2 1.1.3 1.1.4 1.2 2 What is Java? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Contents of the J2SE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . First Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 16 17 18 19 20 21 23 24 26 28 29 31 33 34 35 38 41 43 3

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Java Fundamentals 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 Java Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Variables and Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Operations (Unary Operators) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Operations (Arithmetic Operators) . . . . . . . . . . . . . . . . . . . . . . . . . . Java Operations (Comparison Operators) . . . . . . . . . . . . . . . . . . . . . . . . . Java Operations (Assignment Operators) . . . . . . . . . . . . . . . . . . . . . . . . . Code Blocks and Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.10 Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Introduction to Classes and Objects

CONTENTS 3.1 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.1.3 3.1.4 3.2 Nature of Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dening Classes and Creating Objects . . . . . . . . . . . . . . . . . . . . . . . 44 45 47 48 51 52 53 54 57 59 60 61 62 63 65 66 67 69 70 71 73 74 75 76 80 81

Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 3.2.2 Introduction to Access Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.3 4

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Strings and Arrays 4.1 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 4.1.2 4.1.3 4.1.4 4.2 String Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Testing String Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Converting Strings to Primitives . . . . . . . . . . . . . . . . . . . . . . . . . .

Array Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 4.2.2 4.2.3 Array Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Strings split method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Command Line Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4.3 5

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Methods 5.1 Methods and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 5.1.2 5.2 Overloading Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Method Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 Constructor Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Page 4

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA 5.2.2 5.2.3 5.3 6 Default Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overloading A Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 85 89 91 92 93 95 96 97 99

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Inheritance 6.1 Java Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.1 6.1.2 6.1.3 6.1.4 6.2 Inheritance and Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overriding methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using super . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Constructors and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2.1 6.2.2 6.2.3

Package Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 package Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

6.3

Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.3.1 6.3.2 6.3.3 Access Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Static Modier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Final Modier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

6.4 7

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 115

Interfaces and Abstract Classes 7.1

Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 7.1.1 7.1.2 7.1.3 Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Interface Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Polymorphism and Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

7.2

Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7.2.1 Abstract Classes and Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

7.3 Page 5

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 c 2008 n + 1, Inc All Rights Reserved

CONTENTS 8 Utility Classes 8.1 141

java.lang Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 8.1.1 8.1.2 8.1.3 8.1.4 8.1.5 Object class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Math Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 System and Runtime Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

8.2

Working With Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 8.2.1 8.2.2 Calendar Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Formatting Data for Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

8.3 9

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 163

Collections 9.1 9.2

Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 Collections and Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Looping through Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

9.3

Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 181

10 Java I/O

10.1 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 10.1.1 Exception Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 10.1.2 The Throwable Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 10.1.3 Creating a New Exception Type . . . . . . . . . . . . . . . . . . . . . . . . . . 188 10.1.4 Exception Order in Catch Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Page 6 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA 10.1.5 Raising an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 10.1.6 Returning Exceptions from Methods . . . . . . . . . . . . . . . . . . . . . . . . 192 10.2 Java I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 10.2.1 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 10.2.2 Readers and Writers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 10.2.3 Serialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 10.3 Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 11 JDBC 209

11.1 JDBC Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 11.2 Driver Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.3 Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 11.4 Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 11.5 ResultSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 11.6 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 11.7 Lab Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Appendices A 227

Lab Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 Lab 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Lab 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 Lab 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Lab 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Lab 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 Lab 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Lab 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Lab 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Lab 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 c 2008 n + 1, Inc All Rights Reserved

Page 7

CONTENTS A.10 B Lab 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266

GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272

Page 8

c 2008 n + 1, Inc All Rights Reserved

List of Tables
1.1 2.1 2.2 2.3 2.4 2.5 3.1 4.1 4.2 4.3 6.1 6.2 8.1 8.2 8.3 8.4 8.5 Frequently Used J2SE Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Number Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Truth tables for AND and OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key for Monthly Payment Formula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Results of the cleanName Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 24 24 25 31 32 57 63 64 65

Mappings of Package Name to Directory Structure . . . . . . . . . . . . . . . . . . . . 100 Access Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Object methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Math Class Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Calendar Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Calendar Constant Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Conversion Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 9

LIST OF TABLES 8.6 8.7 9.1 9.2 9.3 9.4 Formatting Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Date Format Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 List Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Iterator Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Set Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Map Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

10.1 Throwable Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 10.2 Exception Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 10.3 Low Level Stream Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 10.4 Data Steam Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 10.5 Low Level Reader/Writer Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 10.6 High Level Reader/Writer Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 11.1 Isolation Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 11.2 Statement Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 11.3 PreparedStatement Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 11.4 Concurrency / Scrollable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 11.5 SQL - Java Data Type Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

Page 10

c 2008 n + 1, Inc All Rights Reserved

List of Figures
4.1 Java Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

11

LIST OF FIGURES

Page 12

c 2008 n + 1, Inc All Rights Reserved

List of Programs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 Hello World Program . . . . . . . . . . . . . . . . SimpleAccount Class . . . . . . . . . . . . . . . . MoneyAccount Class . . . . . . . . . . . . . . . . Program using MoneyAccount . . . . . . . . . . BankAccount Class . . . . . . . . . . . . . . . . . Program to use BankAccount . . . . . . . . . . . Passing Primitive Data to a Method . . . . . . . Passing an Object by Reference . . . . . . . . . . Simple Constructor Example . . . . . . . . . . . Invalid Constructor . . . . . . . . . . . . . . . . . Overloaded Constructor . . . . . . . . . . . . . . Example of the this keyword . . . . . . . . . . . Example of this with Constructors . . . . . . . . Base Account Class . . . . . . . . . . . . . . . . . Derived SavingsAccount Class . . . . . . . . . . Using SavingsAccount Class . . . . . . . . . . . . Overriding Account Class . . . . . . . . . . . . . Using super . . . . . . . . . . . . . . . . . . . . . Account Constructor Example . . . . . . . . . . . Account Constructor Example . . . . . . . . . . . Package Example . . . . . . . . . . . . . . . . . . Importing Classes from Package . . . . . . . . . Account Encapsulation Example . . . . . . . . . SavingsAccount Encapsulation Example . . . . . Static Example . . . . . . . . . . . . . . . . . . . . Using Static Variables in Methods . . . . . . . . . Using Static Method to Set Static Variable . . . . Example Using Static Modiers . . . . . . . . . . Example Using Final Modier . . . . . . . . . . . InterestAccount Interface . . . . . . . . . . . . . . SavingsAccount Implementing InterestAccount InterestAccount Interface . . . . . . . . . . . . . . First Solution . . . . . . . . . . . . . . . . . . . . Operation Interface . . . . . . . . . . . . . . . . . Operation Implementations . . . . . . . . . . . . Operation Factory . . . . . . . . . . . . . . . . . . 13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 46 53 54 55 56 76 78 82 84 85 87 88 93 93 94 95 96 97 98 101 102 106 107 108 110 111 112 113 119 120 122 124 124 125 126

LIST OF PROGRAMS 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 Operation Calculator . . . . . Second Solution . . . . . . . . Handling Change . . . . . . . Multiple Operation Parser . . Simple Abstract Class . . . . . Simple Abstract Class . . . . . Web Form Interface . . . . . . Abstract Web Form Class . . . Abstract Web Form Class . . . Overriding toString method . Generic Object Storage . . . . Using Scanner Class . . . . . Generic Object Storage . . . . Generics Storage . . . . . . . . Multiple Generic Types . . . . List Example . . . . . . . . . . Iterator Example . . . . . . . . For List Example . . . . . . . Set Example . . . . . . . . . . Map Example . . . . . . . . . Program Causes Exception . . Program Handles Exception . Exception Methods . . . . . . Custom Exception . . . . . . . Throwing Exceptions . . . . . Streaming Out Binary Data . Streaming In Binary Data . . Writing Text Data to a File . . Reading Text Data from a File Serializable Wine Object . . . Serializing an Object to a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 128 129 130 132 132 134 135 136 144 145 150 164 165 166 170 172 174 176 178 184 185 187 188 194 199 200 203 204 206 207

Page 14

c 2008 n + 1, Inc All Rights Reserved

Chapter 1

Java Runtime Environment


Objectives
Understand the history of Java Understand the design goals of Java Learn the contents of the J2SE Development Kit Write rst Java program Understand how the virtual machine works

15

CHAPTER 1. JAVA RUNTIME ENVIRONMENT

1.1 Overview of J2SE


In 1991, James Gosling wanted to design a new computer language built, especially, for small consumer devices. He wanted to be able to write the code once and then run it on a number of dierent chip platforms. The large variation of chips for embedded devices made it impossible to write an application which would run on the various chips. Jamess vision was to create a virtual machine that ran a common bytecode across multiple chips. Thus all that was necessary was a virtual machine engine for each chip set and OS, and the applications would run across all of them. This was the birth of Javas write once and run anywhere mantra. Sun Microsystems gave him the resources to create a rst generation of the language. Originally, the project was not called Java but instead had the name Oak1 . James wanted Oak to be based on Pascal, but his teams development skills were in C++ so Javas roots derived from C. In 1992 the team delivered their rst product called *7. It was developed for a bid to create home control boxes for managing cable television. They lost the bid. About the same time they leaned Oak was already taken as a programming language, so they changed the name for Oak to Java. Java languished for the next two years, as the team could not deliver a product with their new language. Then along came the Internet. Initially web browsers could only display static content or static images. The Java people had the bright idea to create a browser using Java to showcase the capabilities of Java. The HotJava browser was released in 1994. Since the browser was written in Java, it was easy for them to embed animation and GUI forms. Netscape saw the potential for this technology and embedded Java in their browsers by 1995. Java had hit the big time and from there exploded into the product that it is today. Currently there are three versions of Java 2. The Java2 Standard Edition for desktop applications, Java2 Enterprise Edition for business solutions, and Java2 Micro Edition for small embedded devices.

has it that James originally named the project Oak because he had a view of an Oak tree outside his window that he very much liked.

1 Legend

Page 16

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

1.1.1 What is Java?


Java was developed with the following goals in mind: Simple Javas simple syntax makes it easy to learn, yet provides a rich enough foundation to build complex systems. Simplicity is also obtained by removing the need for programmers to manage memory utilization within their programs. Object Oriented Java is fully object oriented language supporting encapsulation, inheritance, and polymorphism. Distributed Javas base API makes it quick and simple to write applications that talk to each other across the network. This makes it easy to write distributed software components and applications. Robust Javas robustness comes from the solid construction of the Java virtual machine that has only become more stable with maturity. Javas robustness has been demonstrated by not only the popularity of the language, but its use in key enterprise processes by large organizations. Secure The Java virtual machine provides a customizable Sandbox in which software can run safely without risk to the operating system or the systems users. In addition to the VMs security, the Java API provides developers with access to cryptography, authentication and authorization services, and secure socket services (SSL). Interoperable Java needed to be able to inter-operate in todays heterogeneous environment. Java originally provided this by having full CORBA support. Since the advent of web services, Java has been at the fore front of web service implementations making it even easier to interoperate with other systems. High Performance Javas performance was designed to be able to run core business systems. In this environment it is important to be a reliable solution that can scale to meet newer needs. The Java J2EE environment delivers this high performance. Portable Java is designed to be compiled into bytecode. This bytecode is run inside of the Java virtual machine. Since most platforms have a virtual machine available, it is truly a write once and run anywhere programming language. Multi-threaded Java provides simple yet fully functional multi-threading capabilities, giving the user even more exibility in solving real world problems.

Page 17

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 1. JAVA RUNTIME ENVIRONMENT

1.1.2 Contents of the J2SE


The Java2 Standard Edition SDK (Software Development Kit) provides developers with all of the basic tools necessary to compile, run, and deploy Java applications. The table below outlines the most used tools provided by the SDK. Tool javac Description The java compiler. This takes the .java les and compiles them into java bytecode (.class le) to be executed by the virtual machine The runtime environment. This tool loads the Java virtual machine and executes the bytecode specied on the command line Documentation tool. It is used to generate API documentation from the source .java les. It uses special comments to create API detail. Java archiving tool. It is similar to the Unix tar command in that it archives a set of les in a single .jar le. Table 1.1: Frequently Used J2SE Tools In addition to these tools, there is an Applet viewer to test applet capabilities before deployment. There is a mechanism for managing cryptographic keys. There are tools for handling Java RMI and Corba remote communication along with utilities for generating hooks that allow calls to native C/C++ code within a Java application.

java javadoc

jar

Page 18

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

1.1.3 First Program


To begin understanding how to write Java code, it is important to take a look at a simple example. Program listing 1.1.3 is an implementation of the hello world application. The rst line creates a class called HelloWorld. Classes will be covered in greater detail later. For now, think of a class as a holding container for procedural code. In this case, main is the starting point for the application. In fact, the public static void main(String [] args) method is the entry point for every application. In this case the entire application is contained within the main and prints out a line to the console. Program Listing 1 Hello World Program public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }

The class denition must be placed into a le called HelloWorld.java. Note that the name of the container class and the le have the same spelling and the capitalization. The practice is mandatory in Java and provides two benets. First each class has its own Java le. Secondly, it makes it easier to organize and manage larger projects. To compile the application, the javac command is used. It takes as an argument the names of the .java les to compile2 . They can be listed naming each le or using the * for wildcards. $> javac HelloWorld.java The results of the compilation is a le that has the same name as the .java le with a .class extension instead of .java. Inside this le is the bytecode used by the Java virtual machine to run the application. Bytecode is executable code within the virtual machine. The virtual machines job is to convert the bytecode into machine code that is run by the processor. To invoke the Java virtual machine, the java command is used. On the command line pass the name of the Java class that has the main() method. The virtual machine loads the .class le into memory and begins execution at the main(). Note that the name of the class does not carry the .class extension. $> java HelloWorld Hello World!

2 javac

will not only compile the current .java le but will compile any dependent .java les as well.

Page 19

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 1. JAVA RUNTIME ENVIRONMENT

1.1.4 Environment Variables


When a user is running an application on top of an operating system, the application runs within a OS shell. The shell provides a layer of interaction between the kernel and the application. Part of the shell environment is to provide system variables that can be utilized by the application to interact with the OS. A common environment variable is the PATH. It species where to search the le system for an invoked application. The Java virtual machine is a user application that runs within a shell. Thus, it can utilize environment variables set within the shell. The two most important are the CLASSPATH and PATH environment variables. The PATH variable should include the path in the le system to the bin directory for the installed JDK. The more important environment variable is the CLASSPATH. This tells the virtual machine where to look for the compiled class le to load. Linux example of setting CLASSPATH bash$> export CLASSPATH=/var/lib/java/blah.jar;. Window example C:> set CLASSPATH=/var/lib/java/blah.jar;.

Page 20

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

1.2 Lab Activity


Part 1. Make sure your path information is set up correctly. To test run the following command from the command prompt. $> java -version If the version is not returned then you need to make sure the java.exe is included in your PATH environment variables. Part 2. Open HelloWorld.java using a simple editor and create the HelloWorld program. Compile the le by using the following command $> javac HelloWorld.java Once the code compiles you should be left with a HelloWorld.class le which can be executed by running $> java HelloWorld You should get a line with Hello World. The next step is to change the output to a custom message that you devise. Recompile the java le using the javac command and run the simple application again to get the custom message.

Page 21

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 1. JAVA RUNTIME ENVIRONMENT

Page 22

c 2008 n + 1, Inc All Rights Reserved

Chapter 2

Java Fundamentals
Objectives
Learn the primitive data types available to Java Understand proper naming conventions for Java variables Learn the heirarchy of Java operators Learn how to use code blocks and comments Learn how to use conditionals Learn how to use looping mechanisms

23

CHAPTER 2. JAVA FUNDAMENTALS

2.1 Java Data Types


Java has eight primitive data types that are available to the developer. Since the primitives are dened to be used inside the virtual machine, the data types are the same for every operating system. This is not true with other languages, such as C / C++, where data type sizes can be dened dierently depending on the platform. Table 2.1 shows a list of of Javas primitives. Type Byte Short Integer Integer Long Integer Floating Point Double Floating Character Boolean Java Type byte short int long oat double char boolean Size 8 Bits 16 Bits 32 Bits 64 Bits 32 Bits 64 Bits 16 Bits 1 Bit Values -128 to 127 -32,768 to 32,767 231 to (231 1) 263 to (263 1) 3.4x1038 to 3.4x1038 1.8x10308 to 1.8x10308 0 to 65,535 (Unicode) true or false

Table 2.1: Java Data Types There are a few notes to be made about the dierent data types. Integers can be represented in decimal, octal or hexidecimal format. Octal numbers are preceeded with a capital O. Hexidecimal numbers start with a 0x and can be any mixed case. Table 2.2 shows simple values represented in each format. Type Decimal Octal Hexidecimal Values 28, 13, 48, 10 O34, O15, O60, 012 0x1c, 0xD, 0X2e, 0XA

Table 2.2: Java Number Representation By default the values specied are of type int. To dene a long data type the decimal value must be followed with a l or L 5L, 20l Floats and double values can be dened in either decimal or scientic notation. 1.414 4.23e+21 Page 24 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA By default, all decimal values are doubles. To specify a oat value a f or F must directly follow the value 1.82f, 19.52F Characters can be given an integer value, but it is more common to assign it an alphabetical character or a unicode character m \u006d Note that the unicode value starts with an escape sequence \u. An escape sequence is a special combination that inserts a special character. The \u escape sequence inserts a unicode character that matches the hexidecimal value provided. Other escape sequences are shown in table 2.3. Sequence \n \r \f \t \b \ \" \\ Character carrage return / line feed carrage return form feed tab bell single quote double quote backslash \

Table 2.3: Java Escape Sequences The nal data type is boolean. It can only hold the value true or false. true and false are keywords in Java and represent the results of a boolean expression.

Page 25

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS

2.2 Java Variables and Conversion


Variables are placeholders or names associated with a piece of data. In Java valid variable names must follow the following rules: Variables can be any set of Unicode characters that begins with an alphabetical letter, underscore( ) or dollar sign($). The variable name can not be a Java keyword. List of valid variables testVariable xtest1 F3Tornado _BestVar Great_Lakes The standard for Java variables is to start a variable with a lowercase letter and use upper case for each word in the variable name. It is also a common practice to use descriptive variable names to describe the data. index phoneTree addressBookEntry Once a legal variable name is determined, it is a simple matter of assigning the variable to a value using the equal sign. Below are a couple of assignment expressions: index = 10 someValue = 6.34f addressBookEntry = "John Doe - 555.1234" addedNumbers = 5 + 8 subtraction = 5.5 - 8.2 An expression is a series of operations that evaluate to a single value. The assignment examples from above are examples of an expression. More valid expressions will be shown later. A statement is a set of expressions that form a complete command and are normally terminated with a semicolon. A Java program is nothing more than a set of statements. Before variables can be assigned, the variable must be declared. In Java when declaring a variable the data type must be associated with the variable. Javas requirement to associate a type with a variable makes it a strongly typed language. This feature can cause a problem when assignment occurs between variable of varying types. Because each variable type has a dierent footprint in memory direct assignment is not always possible. Page 26 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA If a data type is assigned to a more narrow type what happens to the extra information in the wider type? Can a data type be assigned directly to a a wider data type? int index; double subtraction; index = 10; subtraction = 5.5 - 8.2; The process of taking a data type and converting it to a wider type is known as conversion. Conversions can be done with all of Javas primitive data types except the boolean. The chart below shows valid conversion capabilities along with some example of conversion. An invalid conversion will lead to a compiler error. byte byteNumber = 10; short shortNumber = 10; int intNumber = shortNumber; long longNumber = intNumber; float floatNumber = longNumber; Sometimes it is necessary to take a wider data type and assign it to a more narrow data type. The only problem is that data can be lost during this process, causing a compiler error. Below is an example of how data can be lost. The short value of 522 has the following 16 bit equivalent. If we try to convert it to a byte the high part of the number will be truncated. This leaves a value of 10 which is not the same value as 522. short x = 522 byte y = x 00000010 00001010 00001010 (522) (10)

To tell the compiler it is acceptable if data is lost, the cast operator is performed on the number. Casting explicitly tells the compiler that narrowing conversion is acceptable and the developer is aware that data may be lost. Below is a simple example of casting between a double and an int and then between the int and a short. double var1 = 52.32; int var2 = (int)var1; short var3 = (short)var2;

Page 27

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS

2.3 Java Operations (Unary Operators)


There are seven unary operators available to Java. Unary operators are commands that only operate upon a single value. These have the highest precedence when evaluating an expression. Plus or Minus (+ or -) the plus or minus operator tells whether the value supplied is positive or negative. By default values are assumed to be positive x = +8 y = -4 Bitwise Inversion () the bitwise invertor takes all of the bits that make up the value of the variable and reverses their values. Java provides a number of operators for performing bitwise operations. (<< operator shifts a variables bits to the left, >> and >>> operators shift a variables bits to the right. There are bitwise operators which are used to perform conditional operations on integers and booleans. & peforms an AND operation, | an OR operation, and a XOR operation) byte x = 18 byte y = x // bit pattern for x is 00010010 = 18 // bit pattern for y is 11101101 = -19

Complement (!) used only on boolean values to return the opposite value boolean x = true boolean y = !x

// y = false

Casting ( ([type ) )] to convert data from one data type to another int x = 10; byte y = (byte) x; Increment, Decrement (++, ) The increment and decrement are the most confusing of the unary operators. The basic concept is to increment or decrement the variables value; int x = 10 x++ // the value is incremented to 11 x-// the value is decremented to 10 The complexity comes from the fact that there are pre and post incrementers . The preincrementors increment the value before it is evaluated. The post-incrementor increments the value after it is evaluated. The dierence is subtle. The next example shows the dierence. The same rules apply to decrementers. x = 10 y = x++ z = ++x

// increments after evaluation (y = 10, x = 11) // increments before evaluation (z = 12, x = 12)

Page 28

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

2.4 Java Operations (Arithmetic Operators)


After the unary operators, the arithmetic operators are next in precedence. These perform simple mathematical calculations upon variables. There are ve arithmetic operators that are divided into two levels of priority. The higher level operations are preformed before lower level operations. The highest level arithmetic operators are multiplication (*), division (/), and modulus (%). The lower level operations are addition1 (+) and subtraction (-). Below are some simple examples of using the arithmetic operators: x = 5 * 5 y = 4 - 8 z = x + y * 2 // x = 25 // y = -4 // z = 17

In the nal example y * 2 is calcuated before the results are added to x because the multiplication operator has a higher level of presedence. Most are familiar with addition, subtraction, multiplication, and division, but few are familiar with the modulus operator. It works by returning the remainder of a division operator. A simple example would be 17 % 5. If 17 was divided by 5, the results would be 3 with a remainder of 2. The modulus operator would return the remainder portion which would be 2. Below are some examples of the modulus operator: x = 28 % 9 y = 18 % 3 z = 5.2 % .3 // x = 1 // y = 0 // z = .1

NOTE: The right side of a division or modulus operation must not be zero. If an integer zero occurs then a DivideByZeroException will be thrown (More on exceptions later). If division occurs with a zero the results will return either POSITIVE INFINITY or NEGATIVE INFINITY

1 In

the chapter covering Strings, the plus operator can also be used to concatenate strings.

Page 29

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS The only tricky part of working with arithmetic operators is when working with numbers of dierent primitive types, ie when one is an integer and the other is a double. In cases where mixed types are being calculated, Java automatically provides a widening conversion for each number so they are the same type. Bytes and Shorts are always converted to integers for calculation. The resulting type from the operation will be of the widest type used in the operation. byte x = 5; int y = 8; double z = 5.0; short i = x + y short j = x * x long k = x + y double m = x / y double n = z / y // // // // // fail to compile fail to compile k = 13 m = 0 n = .625

The rst calculation will fail to compile because the x and y are converted to integers since y is an integer. Since the resulting type is a short information could be lost so the compiler fails without a casting operation. The second example would fail for the same reason since the byte x would be converted to an integer for the calulation. The third calculation works because the resulting integer from the calculation can easily be converted into a long. Both of the nal two calculation will work, but they will give radically dierent results. In the rst division calculation, both numbers will be converted to integers and integer division will return a value of zero which is converted into a double. In the second, both values are converted into doubles so the resulting value is the double .625.

Page 30

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

2.5 Java Operations (Comparison Operators)


One of Javas more important operators is the comparison operator. It provides the developer with the ability to evaluate the contents of variables and make decisions based on the contents. In Java the comparison operator is used to compare two values and return a boolean value with the results. Table 2.4 shows a list of Java comparison operators. Operation < > == != <= <= instanceof Meaning Checks to see if the rst value is less than the second value Checks to see if the rst value is greater than the second value Checks to see if the rst value is equal to the second value Checks to see if the rst values is not equal to the second value Checks to see if the rst value is less than or equals to the second value Checks to see if the rst value is greater than or equals to the second value Checks to see if the rst object is of the same type as the second. The instanceof operator applies to objects which will be covered in a later module Table 2.4: Java Comparison Operators Examples of using these operators are shown below x < 10 x >= y x == z Sometimes it is important to be able to make a decision based upon the results of multiple comparison. The short circuit operators are used to peform AND and OR operations on two boolean values. The AND operator is && and the OR operator is represented by ||. Table 2.5 shows all the possible results of both operations. Simple usages of the short circuit operator are shown below. In the rst example it checks to see if x is equal to 10 and y is not equal to ve. If both are true then the operation will return true. Otherwise it will return false. The second example adds parenthesis to more explicityly state what operation is being applied to what short circuit operator. Generally, it is a good practice to make code easier for other developers to read. x == 10 && y != 5 (x < 5) || ((y > 3) && (z != 0)) One thing to note about the short circuit operator is how it evaluates both operands. It works from left to right when evaluating. If the left operation causes the evaluation to be known then the right operation is never evaluated. If the rst value of an AND operation is false then regardless of the Page 31 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS Operation && (AND) && (AND) && (AND) && (AND) || (OR) || (OR) || (OR) || (OR) Value 1 false false true true false false true true Value 2 false true false true false true false true Results false false false true false true true true

Table 2.5: Truth tables for AND and OR value of the second operation the AND will always evaluate to false. The two examples below show the importance of understanding how the short circuit operators works. ( x < 5 ) && ( ++y == 3 ) ( x != null ) && ( x.equals("test") ) In the rst example, if x < 5 returns false then ++y == 3 is never evaluated which means that y is not incremented. If the rst value evalutes to true then y is incremented. The second example illustrates the importance of the short circuit operator. If the value of x is null, then the second operator would throw an null pointer execption. So it is important in this instance to be able to not evalaute the second operation. One of the nal comparison operators is the tertiary operator. It is not recomended because it leads to dicult to maintain code. The tertiary operator assigns a value based on the evaluation of a boolean. In the example below if x is true then myvar is assigned the value of 8. If x is not true then myvar is assigned the value of 10. <boolean> ? <value> : <value> myvar = x ? 8 : 10

Page 32

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

2.6 Java Operations (Assignment Operators)


The operators which is evaluated last is the assignment operator. It assigns the value of the operation to a variable. The = sign is used to identify assignment. x = 5 y = 3 + 8 z = z + 4 Java provides a shortcut mechanism for performing simple arithmetic operations upon a variable. This is done by placing the aritihmetic operand before the equal sign. x = 5 x = x + 5 x += 5

// simple arithmetic operation // short cut arithmetic assignment operator

x = x + 5 and x += 5 are identical commands. The second is a short cut for the rst. +=, -=, *=, and /= are all valid arithmetic assignment operators.

Page 33

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS

2.7 Code Blocks and Comments


A block is a special grouping of statements between curly braces. It is used to place multiple statements where a single statement is allowed. Below is an example of a block of code. The example shows three statements inside a single code block. It is important to understand the proper use of curly braces. Whenever a block of code is STARTed with a { it must have an ENDing }. A code block also denes a scope. Variables must be unique within this scope. { int x = 32; int y = 32 + x; int z = y % x; } Comments provide a place to insert textual information into source code. These comments are ignored by the compiler during compilation so they can contain any information the developer wants. This is traditionally used to comment out code that doesnt work or, more importantly, to provide information about the codes logic to make it easier for other developers to understand the source. Java has two mechanisms for placing comments inside of the code. The rst is the single line comment which is represented by two forward slashes //. Anything on the line following the slashes is considered a comment and not parsed by the compiler. The second is the multi-line comment. Multi-line comments start with a /* and end with a */ Anything between these two tokens is not parsed by the compiler. int x = 0; // example of single line comment // int z = 1; /* example of multiline comment int z = 10; */ In the above example only the statement int x = 0; is actually parsed by the compiler. Everything else is ignored because it is a part of the comments.

Page 34

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

2.8 Conditionals
One of the key concepts of procedural programing is the ability to change the ow of the program based on some condition. Javas if/else and case statements allow programmers to make conditional decisions during the ow of the program. The if/else statement is the fundamental method of peforming boolean comparisons in Java2. Below is the denition of the if/else command followed by examples of using the command. if ( <boolean expression> ) <statement> [ else <statement> ] The rst example of using the if/else command is a simple if statement. In this example the value of the variable x is compared with the value 10. If they are equal then expression returns true which means the code in the code block after the if statement is executed. If the expression if false then the code block is skipped over. if ( x == 10 ) { System.out.println("The value of x is 10"); } The next example compares the value of y to see if it matches the value 13. Like the previous example the code block following the if statement is executed if the comparison is true. If the comparison returns false, then the code associated with the else statement is executed. if ( y == 13 ) { System.out.println("The value of y is 13"); } else { System.out.println("The value of y is not 13"); }

2 Boolean

value is normally the result of a comparison operator

Page 35

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS The else statement can be combined with another if statement to create an else if code block. This allows a number of if statements to be combined into a single set of ifs. In the example below the value of z is compared to 13. If it is equal it prints out The value of z is 13. Else, if it is less than 13 it prints The value of z is less than 13. Else it prints The value of z is greater than 13 if ( z == 13 ) { System.out.println("The value of z is 13"); } else if ( z < 13 ) { System.out.println("The value of z is less than 13"); } else { System.out.println("The value of z is greater than 13"); } The case statement is another conditional that works only on integer values. It has the following form switch ( <variable> ) { case <value a>: [ statements ]* case <value b>: [ statements ]* case default: [ statements ]* } In this instance the switch operation is used to evaluate the supplied variable. The value of the variable is then compared against each case statement for equality. If the value of the variable matches the value of the case statement then code continues execution from that point. The default case is executed if no other case statement value matches. int x = 2 int y = 10; switch ( x ) { case 1: y = x + 3; case 2: y = x * 3; case 3: y = x - 3; } The resulting value of y in the statement above would be -1. Why? Since the value of x is two, the second case statement matches. y = x * 3 which would result in a value of 6. But since the point of Page 36 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA execution begins at that point then it will continue executing code. Thus it runs y = x - 3 which sets the value of y = -1. To stop execution once case is encountered, the break command can be used to exit the switch statement. int x = 2 int y = 10; switch ( x ) { case 1: y = x + 3; break; case 2: y = x * 3; break; case 3: y = x - 3; break; } Once y = x * 3 is evaluated the break is encountered and control is taken outside of the switch statement. Therefore the value of y is 6; The case statement also provides a default case which is executed if none of the other case statements match the value provided to the switch. In the example below x is set to 4 which does not match any of the case statements so the default case is executed and y is set to 1. int x = 4 int y = 10; switch ( x ) { case 1: y = x + 3; break; case 2: y = x * 3; break; case 3: y = x - 3; break; case default: y = 1; }

Page 37

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS

2.9 Looping
Another key concept of procedural programing is the ability to easily repeat a set of steps during the ow of the program. This concept is known as looping. Java provides the while, do/while, and for looping constructs to provided dierent mechanisms for repeated execution of code. The while construct is the most basic form of looping available in Java. The denition for while looping is show below.

while ( <boolean expression> ) <statement>

To enter a while loop the boolean expression must evaluate to true. Once inside the loop, the statement is executed repeatedly until the boolean expression evaluates to false. Generaly the statement is dened as a code block. Below is a simple example of a while loop.

int x = 1; while ( x < 5 ) { System.out.println("Hello World"); x += 1; } Output: Hello Hello Hello Hello

World World World World

In this example the while statement checks to see if x < 5. Since x is initially set to 1, the loop is entered and Hello World is printed. x is incremented by 1 and then the while test is applied again. Since x is still less than 5 the code inside the loop is executed again. This continues until x is equal to 5. Once the while statement evalues to false execution continues after the while statement. The do/while loop works the exact same as the while loop with the exception that it will run the code inside the loop before checking the conditional. This guarantees that the code associated with the do/while is executed at least once.

do <statement> while ( <boolean expression> );

Page 38

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Below is a simple example using the do/while loop. In this example Hello World is printed and x is incremented to 9. Since 9 is not less than 5 then the loop exits, illustrating the always executing at least once concept.

int x = 8; do { System.out.println("Hello World"); x += 1; } while ( x < 5 ); Output: Hello World

The for loop is the most complicated looping command. It uses three arguments seperated by semicolons to perform dierent parts of the looping process. The form of the for statement is below

for ( <expression>; <boolean expression>; <expression> ) <statement>

The rst expression in the for statement is executed before loop. It is used for initializing variables. The boolean expression is the same as used in a while statement. It determines if the loop should be evaluated or if it should continue at the next statement. The nal expression is used to peform an end of loop operation before the boolean expression is evaluated again. Common usage of the for loop is show below. The variable x is initialized to zero. It is then compared to see if x is less than ve. Since it is it evaluates the statements associated with the for loop. After it prints Hello World it increments x with the x++ operator. x is once again compared with ve. Since x is one and one is less than ve the loop is evaluated again. This continues until x is equal to ve.

for ( int x = 0; x < 5; x++ ) { System.out.println("Hello World"); } Output: Hello Hello Hello Hello Hello

World World World World World

Page 39

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS Two operations, continue and break, can be used to aect the looping process. continue is used to skip to the end of the looping code block where the looping evaluation takes place. The break command is used to exit the looping process at the point it is issued. An example of using the continue and break commands are shown below. int x = 100; System.out.println("My number is " + x); for ( x = 0; x < 100; x += 10 ) { if ( x <= 30 ) { continue; } else if ( x > 70 ) { break; } System.out.println("Hello World " + x); } System.out.println("My number is " + x); Output: My number is 100 Hello World 40 Hello World 50 Hello World 60 Hello World 70 My number is 80

Page 40

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

2.10 Lab Activity


Part 1. Re-create the HelloWorld application inside Eclipse. 1. Select File and New Project. Create a new Java Project and hit the next button. Give the project a name and hit the nish button. 2. Select File and New Class. Give the class the name HelloWorld and select the checkbox with public static void main(String [ ] args). Once completed, push the Finish button. 3. Enter the HelloWorld code. 4. Select Run and Run As. Select Java Application. It should execute the application and display the results in the console. Part 2. Write a program that counts down from 10. It should have the following output: 10 9 8 7 6 5 4 3 2 1 Countdown Complete! Part 3. Modify the program that counts down from 10 to only show the odd numbers. It should have the following output: 9 7 5 3 1 Countdown Complete! Part 4. Loop from 1 to 200 converting a short to a byte and printing both the short and the byte. Is the output what you expected? Part 5. (Optional) Write a program that prints out the prime numbers between 1 and 1000. A prime number is any integer greater than 1 that is divisible only by 1 and itself. The rst twelve primes are 2,3,5,7,11,13,17,19,23,29,31, and 37. Page 41 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 2. JAVA FUNDAMENTALS Part 6. (Optional) Calculate the area under the curve for the following equation x2 4x + 5 from 0 to 20. The answer is 1966.67.

Page 42

c 2008 n + 1, Inc All Rights Reserved

Chapter 3

Introduction to Classes and Objects


Objectives
Understand what an object is Learn the dierence between classes and objects Learn the basics of attributes and methods Learn two of Javas access modiers Learn how to encapsulate objects

43

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS

3.1 Classes and Objects


Back in the 1970s computer science was still in its infancy. Engineers began to create higher level programing languages to escape assembler programming. These new languages1 allowed developers to easily create computer programs. The main paradigm that developed from this time period was the concept of procedural programming. Basically, the developer would take a set of data dened by data structures and apply a set of algorithms (procedures) to the data to generate results. At this time most tasks design for the computer were generally small and computationally oriented. Cracks in the procedural paradigm began to arise when the complexity and size of programs began to increase exponentially. It became dicult for people to understand programs because of the sheer size of the code. Because of the open nature of the paradigm, one person could changes something in one place of the code and it could eect some other portion of code that the person did not even know was related. This complexity was further complicated when teams of programmers had to work together. Programming became more time consuming and bug ridden. It was apparent that procedural programming could not scale to meet the increasing demands of programmers. Something better was needed. The deciencies in procedural programming led to the creation of the object oriented paradigm. The concept behind object oriented programing was to decompose a problem into more manageable segments rather than supporting one large monolithic application. These segments were broken down as objects that could represent physical or conceptual entities in the real world. It allowed developers the ability to mimic the underlying problem domain using the vocabulary of the problem set. This decomposition provided a means to organize smaller chunks of code into bigger systems that was easier to grasp. Thus the complexity was more manageable when dealing with very large systems. Javas foundations were built around the object oriented programming paradigm. Because Java is an object oriented programming language, it is important to begin with the foundational building block of OO, objects.

1 C,

Pascal, Fortran, etc

Page 44

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

3.1.1 Nature of Objects


When the word object is mentioned what comes to mind? Looking around the classroom one sees all kinds of objects. Things like chairs, desks, computers, monitors, project, students, clocks, and even this book. All of these things could be considered objects. In the programming world, objects are abstract representations of either physical2 or conceptual3 entities. All objects have some state associated with them. For example, a chair would have a color, width, height, and even a load limit. A bank account would have an account number, a balance, a customers name associated with it. These properties that make up the state of the object are called attributes in Java terminology. The current state of an object is based upon the values that the object holds for each of those attributes. Below we see the employee object compromising the state of an individual employee John Doe. employee->name = John Doe employee->employeeId = 35235 employee->jobDescription = President of the Company In addition to the state, the object also has the ability to do things. A chairs height can be raised or lowered. We can deposit or withdraw money from an account. These functions of an object can be captured within the object. This behavior is what dierentiates an object from a traditional data structure. In Java behavior is determined by a pre dened set of operations or methods that are associated with an object. The methods fall into two categories. Methods that manipulate the state of the object and methods that report on the state of the object. The former is called a mutator method and the latter is called an accessor method. Then what are classes? A class is an abstract description of an object. In Java a class is used to design the state and behavior of an object. From the class structure, it is possible to create instances of an object. Think of it this way. A class is the same concept as a blueprint for a house. The houses in the neighborhood are created from the blueprint. Therefore objects (houses) are instances of a class (blueprint).

2 Physical

3 Conceptual

entities would included things like chairs, desks, etc entities would be things like a bank account, time, etc

Page 45

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS An example class can be found in program listing 2. Program Listing 2 SimpleAccount Class class SimpleAccount { int accountNumber; double balance; String accountName; void depositMoney(double amount) { balance += amount; } void withdrawMoney(double amount) { balance -= amount; } }

Page 46

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

3.1.2 Attributes
When creating a class, it is important to be able to describe the physical or conceptual characteristics that dene an object. These characteristics are captured in the objects attributes. Therefore, attributes4 are a set of data types that are used to dene the state of the object. The data types can be either a primitive such as double, int, long, oat or they can even be another object. In the Account class above the balance attribute is dened as the primitive double. While accountName is an object type called String At this point, study the the SimpleAccount class in program listing 2 . When looking at the SimpleAccount class it is easy to identify the three attributes of the account object. They are accountNumber, balance, and accountName. Attributes are made up of two things. First is the name of the variable that is associated with the attribute. Secondly, because Java is a strongly typed language each attribute must be a declared type. In the SimpleAccount example accountNumber is an integer, balance is a double, and the accountName is associated with the String object. Now take a look at how attributes are accessed in the example below. myAccount.accountNumber = 1; myAccount.balance = 4.32; myAccount.accountName = "John Doe"; System.out.println("My account = " + myAccount.accountName); System.out.println("My balance = " + myAccount.balance); Notice that attributes can be accessed by using the dot notation. To the left of the . is the object being accessed. To the right of the . is the attribute associated with the object. The example above should generate the following output. My account = John Doe My balance = 4.32

how attributes follow the same naming convention of variables. The rst word of the variable is lowercase and the rst letter of every word after the rst is capitalized.

4 Note

Page 47

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS

3.1.3 Methods
Object actions are captured by methods. Methods5 are dened by the following structure. [modifier] returnType methodName([paramType param1, paramType param2, ...]) { // body } The rst part of the denition is the optional modier. The modier is used to describe the type of method being used. The most common modiers are the static modier and access modiers. Access modiers are used to determine access to the method. They are covered in much greater depth in section 3.2.1. The static keyword means that the method is associated with the class and not an instance of the class. Think of the static keyword as marking a method as global in scope. All methods must have a name and dene a return type. Method names can vary, but it is generally good practice to use camel case as a naming convention. Example method names are: getAccountBalance(), withdrawMoney(), and setBackgroundColor(). Besides having a name, the method also must return some value to the methods caller. The value can be either a primitive, object, or void type. There are three types that can be returned. The rst is any primitive data type. The getAccountBalance() method is an example of a method that returns a primitive double. getMessage() is a method that returns a String object. What if a programmer doesnt wish to return a value? In this case the void type can be deployed. void tells the caller that no value will be returned from the method. This method would return the accounts balance as a double value. The second type is an object. An example of returning an object might be the following, String getMessage(). Here a String object is being returned to the user. What if a programmer doesnt want to return a value? In this case the void data type can be deployed. Void tells the caller that no value will be returned from the method. In addition, a method can have zero or more parameters used to pass values into the method. These values are used to help perform some action upon the object. These parameters consist of two parts. The rst is the data type of the value being passed into the method. The data type can be either a primitive or an object. Since Java is a strongly typed language this should not come as a surprise. The second portion of the parameter is the variable name. Variable names are used to identify the value inside the method. Some sample method declarations: void anotherTask() int determineUsersAge(String name) void doSomething(int x, float y, double z) String getErrorMessage(boolean isError)
method name, the parameters, and the parameter types are known in Java as the methods signature. Method signatures will become important later when we discuss overloading methods.
5 The

Page 48

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Variable Scope When passing parameters to methods two rules must be considered. The rst is that primitive data types are passed into methods by value. This means that the value is copied and passed into the method. The original variable is not modied. The example below is used to illustrate this problem. What would get printed if this example is run. int addNumbers(int x, int y) { int z = 4; x = x + 3; y = y - 3; z = x + y; System.out.println("inside x = " + x); System.out.println("inside y = " + y); return z; } ... int x = 5; int b = 4; System.out.println("x = " + x); System.out.println("b = " + b); int y = addNumbers(b, x); System.out.println("x = " + x); System.out.println("b = " + b); System.out.println("y = " + y);

Page 49

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS Does the answer match the one below? Lets review what happens. First, the value of x and b are set by the initialization commands x = 5 and b = 4. These values are then printed. Next the method addNumbers is called. The value of b, four, is passed in as the rst parameter and is associated to x. The value of x, ve, is passed in as the second parameter and is associated to local variable y. The next step would be to add three to the methods variable x to bring the total to seven. Three is then subtracted from y to change its total to two. The values are then displayed on the screen. The values of x and y are summed and returned to the local variable y. Since x and b are passed into the method, a copy was made for the internal method. This means the original values never changed. Thus local x and b are retain the original values of 5 and 4 respectively. x = 5 b = 4 inside x = 7 inside y = 2 x = 5 b = 4 y = 9 On the other hand, when objects are passed into methods they are passed by reference. In this case the object is not copied and passed into the method. Instead, a pointer to the object is passed as a parameter. The pointer references the location in memory where the object exists. So the memory location of the object is what is passed into the method. Thus the original object is available for manipulation within the method being called. This subject will be covered in more detail at a later time.

Page 50

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

3.1.4 Dening Classes and Creating Objects


The code in program listing 2 provides an example of a class denition. The class has been dened, but how can the blueprint be turned into an object? The creation of a new object is known as instantiation. It is done with the new command. SimpleAccount account = new SimpleAccount(); The new command takes the class and creates an instance of an object based on the class. In essence, it builds a house from a copy of the blueprint. Once the object is created it can be utilized by the developer. Note that each call to new will create a new object which is dierent from every other object. Just like new houses are all dierent from each other. This means that operations on one object will change the state of that object and not eect any other objects. The example below illustrates this principle. SimpleAccount myAccount = new SimpleAccount(); SimpleAccount yourAccount = new SimpleAccount(); myAccount.balance = 100.10; myAccount.depositMoney(44.23); yourAccount.balance = 200.75; yourAccont.withdrawMoney(100.25); System.out.println("My Balance = " + myAccount.balance); System.out.println("Your Balance = " + yourAccount.balance);

In this example, myAccount and yourAccount are two dierent objects that have the same blueprint. Although they come from the same class they are two dierent entities residing in dierent name spaces. Therefore when money is deposited into myAccount then myAccounts balance attribute is eected. At the same time the yourAccounts balance attribute is unaected. The opposite is true when money is withdrawn from the yourAccount object. The results are shown below. My Balance = 144.33 Your Balance = 100.5 It is important that ALL object variables get instantiated before they are used. An instantiated object variable is given the value null by default. null is a Java keyword given to an uninstantiated object variable. Failure to instantiate an object variable before using it will lead to an application failure.

Page 51

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS

3.2 Encapsulation
If a Java object exposes all of its attributes publicly, then nothing has been gained from the days of procedural programming. Because with publicly accessible attributes, there would be no dierence between a class and a data structure. The power of object oriented programing comes from the ability to hide the internal workings of the class in order to create pluggable black boxes linked together to form large scale applications. To accomplish this goal, it is important to hide an objects attributes. In addition, methods must be publicly available in order to retrieve and modify the attributes of the object. The process of hiding the internal state and only allowing access through methods is known as encapsulation. This section takes a look at how access modiers can be used to create and enforce encapsulation.

Page 52

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

3.2.1 Introduction to Access Modiers


Access modiers control what features of an object are available to other objects. Access modiers can be applied to any of the following: classes, attributes, methods, constructors. There are four modiers available to developers. The most common of these are public and private. When the public keyword is associated with an element of a class, it means that any other object can have access to this feature. It is publicly available. For example, when a class is marked as public, it means that the object can be created as an instance from anywhere in the application. When an attribute is marked public, it means that any object with local scope can access that objects attribute. Same thing is true for methods and constructors. The other common access modier is private. When an element is marked as private then only the object itself can access the resource. Outside objects are forbidden from access to the feature. Classes are generally not marked as private because no one would be able to create an instance of the class. Some methods might be marked as private if they want the functionality to be available only to the object. Attributes are marked as private when it is necessary to deny outside objects the ability to directly access the objects data structure. By marking all attributes as private the data structure of the object is hidden to the outside world. Program Listing 3 is an example of a class using the public and private modiers. Program Listing 3 MoneyAccount Class public class MoneyAccount { private double balance; public void initializeBalance(double amount) { balance = amount; } public void adjustBalance(double amount) { balance = addNumbers(amount, balance); } public void printBalance() { System.out.println("Balance = " + balance); } private double addNumbers(double x, double y) { double results = x + y; return results; } }

Page 53

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS Will the MoneyAccount class shown in program listing 3 compile? What changes if any need to be made to make the code in the MainMoney class work?

public class MoneyMain { public static void main(String [] args) { MoneyAccount myAccount = new MoneyAccount(); myAccount.balance = 55.23; myAccount.adjustBalance(-28.33); myAccount.printBalance(); int testBalance = myAccount.addNumbers(55.23, -28.33); System.out.println("Account Balance should be " + testBalance); } }

There are two problems with the MoneyMain code that would cause the compiler to fail during compilation. The rst problem is the code tries to access the private attribute balance directly. Since balance is marked private, it is only available to myAccount and not to anyone else. The second problem occurs when the code attempts to access the method addNumbers. Again this method is marked private so it is not available outside of the object. program listing 4 corrects the problems from the above MoneyMain. Program Listing 4 Program using MoneyAccount public class MoneyMain { public static void main(String [] args) { MoneyAccount myAccount = new MoneyAccount(); myAccount.initializeBalance(55.23); myAccount.adjustBalance(-28.33); myAccount.printBalance(); double testBalance = 55.23 - 28.33; System.out.println("Account Balance should be " + testBalance); } }

3.2.2 Encapsulation
Encapsulation occurs when all of the member attributes are hidden by the private access modier. To allow access to the internal data provided by the attributes, it is necessary to provide what are known as accessor and mutator methods. Accessors are used to retrieve the state of the object while mutators are used to modify the attributes of the object. Page 54 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The general form for dening accessors and mutators is set forth in the JavaBean6 standard. The standard method is to take an attribute and prepend get to the variable name to dene an accessor method. For a mutator, set is prepended to the variable name. These are known as getter and setter methods. Program listing 5 provides an example of an object that allows JavaBean accessors and mutators methods. Program Listing 5 BankAccount Class public class BankAccount { private String accountName; private double balance; public void setAccountName(String name) { accountName = name; } public String getAccountName() { return accountName; } public void setBalance(double amount) { balance = amount; } public double getBalance() { return balance; } }

Why should the developer be concerned with encapsulation? What benet is derived from using encapsulation. The rst benet is provided by the decoupling of how data is accessed from how it is stored. It should be unimportant for a client object to understand or care how data is stored within the object. The calling object should only be concerned with the behavior provided through methods by the object. This means how the data is stored is irrelevant. What if the objects developer wants to store the attributes in a database or a le instead of using primitives? If a developer hides how the attributes are stored then the objects consumers would not have to be modied if the object changes how it stores its state. The second benet is data protection. By using a mutator the developer has the ability within that method to make sure that the value being set for the attribute makes sense. For example take a Person class which has an age attribute. It wouldnt make sense for someone to set the age to a negative value. By using mutators, the programmer can provide a sanity check before the data is modied.
JavaBean standard is not required for accessors and mutators. Encapsulation only states that the internal state of the object is not directly accessible. Even so, the JavaBean standard is the most common way to provide encapsulation.
6 The

Page 55

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS The bottom line is that all classes should mandate encapsulation. This simply means that all attributes should be marked private. It is an easy rule to follow and will lead to better designed classes and programs. One nal example of a program that utilizes the encapsulated BankAccount class shown in program listing 6. Program Listing 6 Program to use BankAccount public class BankMain { public static void main(String [] args) { BankAccount myAccount = new BankAccount(); myAccount.setAccountName("John Doe"); myAccount.setBalance(2341.23); BankAccount yourAccount = new BankAccount(); yourAccount.setAccountName("Jane Doe"); yourAccount.setBalance(5231.58); printBalance(yourAccount.getAccountName(), yourAccount.getBalance()); printBalance(myAccount.getAccountName(), myAccount.getBalance()); } public static void printBalance(String name, double balance) { System.out.println(name + "s balance is " + balance); } }

Printing out the following. Jane Does balance is 5231.58 John Does balance is 2341.23

Page 56

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

3.3 Lab Activity


Part 1. Calculating house payments Create a mortgage calculator class. It needs to have methods to calculate the monthly payments of the loan given the interest rate, amount of the loan, and the term of the loan. In addition it needs to determine how much of a loan can be obtained given the monthly payment amount, the interest rate, and the term of the loan. The formula for calculating amount of compounded interest is M = P (k/(1 (1 + k)n )) Symbol M P k n Meaning Monthly Payment Amount of Loan Interest rate as a decimal divided by 12 Number of months of the loan Table 3.1: Key for Monthly Payment Formula Note: (1 + k)n can be calculated using function Math.pow((1 + k), -n) Part 2. Printing out a mortgage statement Create a mortgage class. It should have methods that can take in the interest rate, term of the loan and either the monthly payment or the amount of the loan and print the following mortgage statement. Amount of Loan: 100000 Interest Rate: .089 Number of Years: 20 Monthly Payment: 893.3047 The mortgage class should use the mortgage calculator to calculate any missing data. Part 3. Create a class with a static main method to instantiate the mortgage class and print out mortgages for the following scenarios. Scenario A. We know that the mortgage rate is 7.5%, the term for the loan is 30 years, and the amount of the loan is $250,000. What is the monthly payment for the mortgage? Scenario B. We know that we want a mortgage payment no more than $2,000 a month. If the mortgage rate is 7.5% and the term of the loan is 30 years, what is the largest loan we can take out? Page 57 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 3. INTRODUCTION TO CLASSES AND OBJECTS The results should be printed out for each scenario Scenario A Amount of Loan: 250000.0 Interest Rate: .075 Number of Years: 30 Monthly Payments: 1748.036371381941 Scenario B Amount of Loan: 296035.25463731715 Interest Rate: .075 Number of Years: 30 Monthly Payment: 2000.0

Page 58

c 2008 n + 1, Inc All Rights Reserved

Chapter 4

Strings and Arrays


Objectives
Understanding what a String is Learn to test Strings for equality Learn how to use the various String methods Learn how to convert Strings to primitive data types. Understand how to create arrays Understand how to access and modify arrays Learn how to use the Strings split method Learn how to use command line parameters

59

CHAPTER 4. STRINGS AND ARRAYS

4.1 Strings
A String is an object whose state is represented by a series of Unicode characters. Because most business applications spend a majority of their time manipulating text, Strings are the most used objects in Java. It is important to understand how they are created and manipulated. The String class is used to encapsulate character based data. Like the char data type, Strings are based upon the Unicode standard for character representation.

Page 60

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.1.1 String Basics


Creating a String in Java is the same as creating any other object. In this case you pass the String literal you wish to create to the String at creation time. String literals are any set of characters which are surrounded by double quotes. String myString = new String("This is a test"); Since String objects are so heavily used in Java, the creators of the language allow for a shortcut in the creation process. They allow the developer to assign a String object to a string literal directly as shown below. String myString = "This is another test"; What makes String dierent from most objects in Java is that they are immutable. Once a String is created its value cant be modied. The Java API conrms that none of the Strings methods manipulate the value of the String. In fact all of the String methods are operations upon the internal string value and are returned to the user as a new String object. The immutability of Strings allows the Java runtime engine the opportunity to pool String literals. Multiple String objects can point to the same string literal without duplication of memory allocation. An area where Strings are unique is found in their ability to perform concatenation by overloading the + operator. Operator overload occurs when a particular operation has multiple meanings. In this case the + operator is used for adding numbers and concatenating Strings. It is the only place in Java where operator overloading is allowed. String myString = "String A" + " String B"; String anotherString = myString + " this is another test"; String myString += " more stuff"; Notice that the += operator provides concatenation as well.

Page 61

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS

4.1.2 Testing String Equality


When a primitive is created it can hold one value. Since all primitives hold exactly one piece of information comparison with the == operator is easy to do. Objects on the other hand are more dynamic in nature. Since they can represent multiple data values within a single object the simple == equality test will not work. Which data values would be compared when using the == operator? In addition, the variable associated with an object holds a reference to that objects location in memory. Therefore comparing objects with the == operator will only compare the memory addresses of the objects. It is possible to have two strings that are equal that do not share the same memory location. Therefore the following comparison code block does not work as expected. String myString = new String("This is a test"); String yourString = new String("This is a test"); if ( myString == yourString ) { System.out.println("These two strings are equal"); } else { System.out.println("These two strings are not equal"); } Because myString and yourString point to two dierent locations in memory, they are not equal. Typing in and running the above code will conrm this fact. So how does one test for equality? The String class provides an equals method that performs the equality test. public boolean equals(String stringToCompare) Therefore, the code from the example above could be rewritten to use the equals method for testing equality. String myString = new String("This is a test"); String yourString = new String("This is a test"); if ( myString.equals(yourString) ) { System.out.println("These two strings are equal"); } else { System.out.println("These two strings are not equal"); } This time the results would be as expected.
Java pools String literals, it is possible for two strings to be equivalent if both are literals. For example if String x = Testing; and String y = Testing; then it is true to say that x == y.
1 Since

Page 62

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.1.3 String Methods


The String class has a number of useful methods for manipulating String values. But since Strings are immutable, the methods return a new String with the manipulated value rather than changing the internal objects state. Some of the useful methods for String manipulation are shown in table 4.1. Method int length() String toUpperCase() String toLowerCase() String trim() boolean equalsIgnoreCase(String another) Description Returns the length of this string. Returns the current String with the characters converted to their upper case. Returns the current String with the characters converted to their lower case. Returns the current String without any leading or trailing white space. Compares the current String with the value passed into the method using case insensitivity. Returns a String which is a substring of the current String. The substring begins at the specied beginning index and continues to the end of the String Returns a String which is a substring of the current String. The substring begins at the specied beginning index and ends at the character before the end index. Returns the index within the string of the rst occurrence of the string or -1 if not found. Returns the index within the string of the last occurrence of the string or -1 if not found. Returns a string where the old char is replaced by the new char. Used to compare two strings ignoring case. If a negative value is returned then another comes after the string alphabetically. A zero means the strings are identical. A positive value means another comes before the string alphabetically.

String substring(int beginIndex)

String substring(int beginIndex, int endIndex)

int indexOf(String str)

int lastIndexOf(String str)

String replace(char oldChar, char newChar) int compareTo(String another)

Table 4.1: Common String Methods Page 63 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS Most of these methods are used to manipulate the String into a more desirable fashion. Below is an example of using the String methods to clean up a name. public String cleanName(String someName) { // first strip off any leading or trailing spaces String name = someName.trim(); /* * We want to make sure the name begins with a capital and the * rest of the characters are lower case */ // convert to lower case name = name.toLowerCase(); // grab the first character from the string String firstCharacter = results.substring(0,1); String restOfName = name.substring(1); // reconstruct name name = firstCharacter.toUpperCase() + restOfName; return name; } In this example, the code takes a name passed into it and starts by trimming o any leading or trailing white space with the trim() method. Next, the code should convert the name to lowercase with the exception of the rst letter which must be capitalized. To perform this task, the rst character is pealed o as a substring and the rest of the string is retrieved as a second call to substring. The code then runs an upperCase on the rst character and combines it with the rest of the name. The results shown in table 4.2 would occur if the cleanName method is called for the dened inputs. Method johnson JOHNSON sMITH John Doe Description Johnson Johnson Smith John doe

Table 4.2: Results of the cleanName Method

Page 64

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.1.4 Converting Strings to Primitives


Another common practice in Java programming is converting String objects into primitive data types. Java has an easy method to make these conversions. Each primitive data type has a wrapper class2 associated with it. These wrapper classes provide us a means of converting Strings to the appropriate primitive type. Each class has a parseXXX() method where XXX is the destination primitive. Below is an example of converting String values into an integer and a double. String value1 = "269"; String value2 = "269.52"; int x = Integer.parseInt(value1); double y = Double.parseDouble(value2); Table 4.3 shows each of the primitive types, their equivalent wrapper class and their conversion method. Primitive short int long oat double Wrapper Class Short Integer Long Float Double Conversion Method parseShort(String shortValue) parseInt(String intValue) parseLong(String longValue) parseFloat(String oatValue) parseDouble(String doubleValue)

Table 4.3: Wrapper Classes

2 Wrapper

classes are discussed in greater detail within the Utility Classes module.

Page 65

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS

4.2 Array Fundamentals


Arrays are one of the more peculiar aspects of the Java language. They are objects that have their own unique nomenclature. They are created like any other object, but accessing member data is done through unique operators. Arrays are a simple way to group objects of the same data type. This section will cover the creation and manipulation of arrays. Then it will look at two applications of arrays, the Strings split method and command line parameters.

Page 66

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.2.1 Array Basics


Arrays provide a mechanism by which developers can group entities of the same data type. Thus all of the entities stored in the data type must be of the same primitive or object type. Arrays provide storage and access to the data using a special array only index mechanism. In addition, the size of an array must be predetermined before it can be used. The size determines how many entities it can store. To begin with, the declaration of an array is dierent from other objects. It uses the [ ] characters to associate an array with a specic data type. int [ ] series; String [ ] stringArray; float [ ] [ ] twoDimensions; In this example the variable seriess type is show as an int followed by the braces ([ ]). This means that series is dened as an array of integers. the stringArray variables type is a String object. Again the braces make it an array of String objects. The twoDimensions variable is an array of oat arrays. An array of arrays provides the programmer with a mechanism to provide two dimensional memory space as shown in gure 4.1.

Figure 4.1: Java Arrays Arrays, like other objects, must use the new operator to create an instance of the array. At construction, the size of the array must be declared. Unlike other objects, arrays have their own unique means of initialization. The new keyword is still used in the creation process, but the braces are used to determine the size of the array. It is important to remember that once the size of the array is dened, it can not be be changed later. The example below shows the series array being initialized to hold six elements. It can not be modied at a later time to hold more or less than six elements. By default, elements in array are Page 67 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS set to their default values for the particular data type. All primitive except booleans are set to zero while booleans are set to false. Any object arrays elements are initialized to be null. int [ ] series; series = new series[6]; Arrays, much like Strings, have an alternate way of being initialized. It is possible to dene the initial values an array will hold at the time of creation. This is done by using a list of entities separated by commas inside of curly braces. Below is an example of creating a predened array. short [ ] list = { 3, 2, 1 }; In this example the short array list is created with a size of three holding the values 3, 2, and 1. To access the elements within the array, the index of the element that is to be accessed must come between the same brackets used for initialization. The indexing of the array begins with the number zero. short [ ] list = { 3, 2, 1 }; System.out.println("value = " + list[1]); In the example above, what is the output? The code snippet should print out value = 2. Remember that an array is a zero based index system. Therefore an index of 1 represents the second element in the array and not the rst. Since arrays are objects, it is possible for them to have methods and attributes. The creators of Java did not provide any methods but they did provide a length attribute to determine the number of elements in the array. short [ ] list = { 3, 2, 1, 8}; System.out.println("size = " + list.length); In this example size = 4.

Page 68

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.2.2 Strings split method

One of the more useful methods available for String data types is the split method. Its signature is String [ ] split(String tokenizer). Split takes a token as an argument and splits the String into a series of separate Strings based on the tokenizing character3 . The resulting set of Strings are returned as a String array. Below is an example of using the split method to break up a comma separated line. String line = "John,Doe,100 East Main St,Somewhere,KY,32503"; String [ ] parts = line.split(","); for ( int x = 0; x < parts.length; x++ ) { System.out.println("Item " + x + ": " + parts[x]); } The results from running the application would be the following Item Item Item Item Item Item 1: 2: 3: 4: 5: 6: John Doe 100 East Main St Somewhere KY 32503

split method does not actually take a tokenizer character. It takes a regular expression as an argument. But since regular expressions is beyond the scope of this course it is safe to assume that most single character tokenizers will work.

3 The

Page 69

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS

4.2.3 Command Line Arguments


At this point, one may have noticed that a String [ ] is passed into the static void main method that programs execute. What is in this string array? The string array holds any command line parameters that are passed into the Java application. Command line parameters are a set of Strings that follow the class name that are separated by spaces. In the example below Java class Tests main method is called and the command line parameters one, two, and three are placed into the String array as separate elements. $> java Test one two three It would be easy to print out the results of this call. public static void main(String[] args) { System.out.println(args[0]); System.out.println(args[1]); System.out.println(args[2]); } Command line parameters are an excellent way to pass information to an application. Initialization or system information are commonly passed to applications through command line.

Page 70

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

4.3 Lab Activity


Part 1. Given the following string: String s = I wish it were Monday 1. Use the length method to print the length of the string 2. Use the substring method to print wish it were 3. Use the replace function to replace Monday with Friday and print the new value. Part 2. Given the following string: String s = oNe,tWo,tHree ,foUr,Ve,sIx,Seven 1. Using String methods, reverse the order to read seven,six,ve,four,three,two,one 2. Using String methods modify the string to read one,TWO,three,FOUR,ve,SIX,seven Part 3. Write a Celsius/Fahrenheit conversion program. It should take two command line parameters. The rst argument is what we are converting to. The second argument is the value that we are converting. $> java Convert celsius 32 Fahrenheit of 32.0 is converted to a Celsius of 0.0. $> java Convert fahrenheit 0 Celsius of 0.0 is converted to a Fahrenheit of 32.0. The calculation for Celsius to Fahrenheit is c = 5/9( f 32) and Fahrenheit to Celsius formula is f = (9/5)c + 32 Part 4. (optional) Given the following array declaration int [] x = { 24, 18, 12, 29, 4, 15, 2, 9, 18, 23, 22, 7 }; Write a program to order the array and print the ordered array to the screen.

Page 71

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 4. STRINGS AND ARRAYS

Page 72

c 2008 n + 1, Inc All Rights Reserved

Chapter 5

Methods
Objectives
Understand why methods can be overloaded Learn how to overload methods Understand the dierence between primitives being passed by value and objects being passed by reference. Understand how constructors work Learn how to create a basic constructor Learn how to overload the constructor Understand how to use the this keyword

73

CHAPTER 5. METHODS

5.1 Methods and Objects


Methods provide a means for objects to interact with other objects. Taken together the methods of an object make up the behavior of the object. This section takes a look at two important concepts. First it is important to revisit the method signature and how it can be used to create method overloading. Secondly, it is important to understand how data is passed into and out of methods.

Page 74

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

5.1.1 Overloading Methods


The basic format for a method in Java is shown below. [modifier] returnType methodName([paramType param1, paramType param2, ...]) { // body } The Java language has a concept called the methods signature. The signature is what uniquely identies which method is invoked when making a call upon object. The signature consists of various elements of the method. Obviously, the method name is one of those elements. Less obvious is the class name. But it makes sense that the class is an important part when determining which method is being called. Most people would think those two elements would be enough. But Java goes one step further. Java also uses the order, type, and number of parameters passed into the method to help determine the uniqueness of a method and thus the methods signature. This leads to an interesting eect. It is possible and valid to have two methods with the same name, but dierent parameter lists. This is known as overloading a method. Method overloading allows the coders to group various methods which accomplish the same task under a common method name. It is a convenience aorded developers who wish to simplify coding and increase code readability. Without overloading, methods would have longer less legible names as shown below. double double double double double calcAreaByCoordinates(Point p1, Point p2, Point p3) calcAreaByLengthsInteger(int length1, int length2, int length3) calcAreaByLengthsLong(long length1, long length2, long length3) calcAreaByLengthsFloat(float length1, float length2, float length3) calcAreaByLengthsDouble(double length1, double length2, double length3)

With overloading, it is possible to rework the previous method names as shown below. double double double double double calculateArea(Point p1, Point p2, Point p3) calculateArea(int length1, int length2, int length3) calculateArea(long length1, long length2, long length3) calculateArea(float length1, float length2, float length3) calculateArea(double length1, double length2, double length3)

Which is easier to read?

Page 75

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS

5.1.2 Method Parameters


Parameters to a method in Java can be any data type. But the way it treats objects and primitive data types is vastly dierent. This section takes a look at the dierences between the two forms.

Primitives By Value When a primitive data type is passed to a method, the stack creates a copy of the primitives value and passes the new value into the method. Therefore any changes made to the primitive value inside of the method does not eect the value of the original variable. It is easier to understand by taking a look at the code example in Program listing 7. Program Listing 7 Passing Primitive Data to a Method public class PassByPrimitive { public static void main(String [] args) { int myNumber = 5; System.out.println("myNumber = " + myNumber); addNumber(myNumber, 3); System.out.println("myNumber = " + myNumber); } public static void addNumber(int x, int y) { x += y; System.out.println("x = " + x); } }

If this code is executed what result should be expected? var = 5 x = 8 var = 8 or var = 5 x = 8 var = 5 In the PassByPrimitive class shown above the variable myNumber is initially assigned the value of 5. When the variable is passed to the method addNumber a copy of the value is made on the stack and is associated with the variable x. Inside the method addNumber the value of x is increased by 3 and displayed to the user. Once the method is nished the local variable x is removed from the stack Page 76 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA and its value of 8 is removed from memory. Since the value held in myNumber was copied to the stack, the original value was never modied. Thus when we return from the method call, myNumber continues to hold the value 5. So in the example above the second result set is expected.

Objects By Reference Objects, on the other hand, are not copied by the stack when passed to a method. Instead a reference to the memory location of the object is copied to the stack. Think of it this way. Picture an object with methods and attributes. That object is stored in some large blob of memory on the machine. Rather than wasting time and resources copying all of that information about the object into a new object on the stack, it passes a reference or a pointer to the location of that blob in memory. As a direct result, methods have access to the original object that is passed into the method. Program listing 8 is helpful for illustrating the point.

Page 77

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS Program Listing 8 Passing an Object by Reference public class Person { private String name; private int age; public void setName(String personName) { name = personName; } public void setAge(int personAge) { age = personAge; } public String getName() { return name; } public int getAge() { return age; } } public class PassByReference { public static void main(String [] args) { Person person = new Person(); person.setName("Beth Smith"); person.setAge(23); System.out.println(person.getName() + " is " + person.getAge() + " years old"); changeAge(person, 3); System.out.println(person.getName() + " is " + person.getAge() + " years old"); } public static void changeAge(Person per, int years) { int age = per.getAge(); age += years; per.setAge(age); System.out.println("age = " + per.getAge()); } }

In this example an object is created called Person. The Person object has two attributes, name and age, which make up its internal state. It also contains a set of methods for getting and setting those values. In this particular case, the Person object person is initialized with the name Beth Smith and an age of 23. In reality the person variable holds the memory location of the object in memory. Therefore when the person variable is passed to the method changeAge what is really being passed Page 78 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA is the memory location of that object. This is known as passing an object by reference. In this instance, the variable per holds the same memory location as the person variable. The method can now make changes to the per object and those changes will show up in the person object because they are pointing to the exact same location in memory. It is in eect the same object. Running the code ends up with the following output. Beth Smith is 23 years old age = 26 Beth Smith is 26 years old Passing by reference is an important concept!

Page 79

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS

5.2 Constructors
One of the tedious activities when programing can be the initialization of an objects initial state. Java provides a special method known as a constructor that can be used to simplify and speed up the process. The constructor is a special type of method which is called when an object is being created and is typically used to congure the initial state of an object.

Page 80

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

5.2.1 Constructor Basics


Reviewing the Person class in the passing by reference example8, it seems a tedious process initializing the state of the Person object. Person person = new Person(); person.setName("Beth Smith"); person.setAge(23); In this code snippet, the Person object is created with the new statement and then each of the attributes are set one at a time. Constructors are a special type of method used to initialize the state of a Java object streamlining the process. It diers from other methods in that it must follow a particular naming convention. A constructor method must have the same name as the class, can have any number of parameters, and must not specify a return type. In addition they are only available for execution once. That occurs when the object is being created or constructed. It is impossible to make a future call to the constructor after the object has been created.

Page 81

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS Program listing 9 is an example of a using a constructor for the People object. Program Listing 9 Simple Constructor Example public class Person { private String name; private int age; /* Constructor */ public Person(String personsName, int personsAge) { name = personsName; age = personsAge; } public void setName(String personsName) { name = personsName; } public void setAge(int personsAge) { age = personsAge; } public String getName() { return name; } public int getAge() { return age; } }

Notice that the constructor has the same name as the class and no return type. But more importantly, note how we can call the constructor to initialize the state of the Person object in one step. Person person = new Person("Beth Smith", 23); In this example the creation of the object replaces the default Person person = new Person() with a new construction step that includes the initial values we wish to associate with the object. Also note that the parameters passed in at creation match the parameter list of the previous dened constructor.

Page 82

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

5.2.2 Default Constructors


The new statement always makes a call to a constructor. Therefore, all Java classes must have at least one constructor. One may have noticed that most of the previous examples never dened a constructor. If all Java classes must have a constructor, what about all of the classes where a constructor was never explicitly dened? If a class does not explicitly dene a constructor, a zero parameter default constructor is associated with the class. The default constructor is an empty method that performs no actions. In the pass by reference example in program listing 8 no constructor was explicitly dened for the Person object. What happens in the following statement? Person person = new Person(); Since no constructor was coded, the Person object uses the no parameter default constructor for the object. There is an important point to be made about explicitly creating constructor methods. If a constructor method is dened then the default constructor method is no longer available to the new operation. Therefore the code shown in program listing 10 will not compile.

Page 83

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS Program Listing 10 Invalid Constructor public class Person { private String name; private int age; public Person(String personsName, int personsAge) { name = personsName; age = personsAge; } public void setName(String personsName) { name = personsName; } public void setAge(int personsAge) { age = personsAge; } public String getName() { return name; } public int getAge() { return age; } } public class Main public static Person p1 Person p2 } } { void main(String [] args) { = new Person("Beth", 22); = new Person();

The following line causes the problem. Why? Person p2 = new Person(); Since the Person class dened a constructor then the new statement above does not match the parameter list of the user dened constructor. Since it doesnt match a known constructor the compilation fails. The next section takes a look at creating multiple constructors for an object.

Page 84

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

5.2.3 Overloading A Constructor


In the Overloading Methods section, it was shown that one could have multiple methods with the same name as long as the number of parameters and their data types were dierent. Although the constructor is a special method, it is still a method. Therefore it is possible to overload a constructor. Program listing 11 is an example of a class with an overloaded constructor. Program Listing 11 Overloaded Constructor public class Account { private String number; private double balance; public Account() { number = new String(""); balance = 0.0; } public Account(String accountNumber) { number = accountNumber; balance = 0.0; } public Account(String accountNumber, double accountBalance) { number = accountNumber; balance = accountBalance; } public void setNumber(String accountNumber) { number = accountNumber; } public void setBalance(double accountBalance) { balance = accountBalance; } public String getNumber() { return number; } public double getBalance() { return balance; } } In the overloaded constructor example1 , the Account constructor is overloaded with three dierent
1 Notice

the use of the new statement to initialize the String object in this empty constructor. If this initialization of the

Page 85

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS sets of parameters. The rst of which is an empty constructor that takes no arguments and sets the state of the object to reasonable default settings. The second constructor is used to initialize the account number value while setting the balance to a reasonable default. The nal constructor initializes both the account number and the balance.

object did not occur, then the getNumber() method would return a null value which could potentially lead to a dreaded NullPointerException. One of the primary purposes of the constructor is to make sure any objects that make up the classes state are properly instantiated before they are used.

Page 86

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA this Variable Java reserves the special variable this to refer to the current object. this allows a developer to explicitly state that they are accessing either a member variable or invoking a member method. Program Listing 12 provides an example of using the this keyword to set an objects member variables. Program Listing 12 Example of the this keyword public class Account { private String number; private double balance; public Account() { this.number = ""; this.balance = 0.0; } public Account(String accountNumber) { this.number = accountNumber; this.balance = 0.0; } public Account(String number, double balance) { this.number = number; this.balance = balance; } public void setNumber(String accountNumber) { this.number = accountNumber; } public void setBalance(double accountBalance) { this.balance = accountBalance; } public String getNumber() { return this.number; } public double getBalance() { return this.balance; } }

Notice that the third constructor uses parameter names that match the names of the classs attributes or member variables. In this example the this variable is used to dierentiate between the member variable and the local variable with the same name. Page 87 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS A downside to the previous example is the duplication of code within the various constructors. Duplication of code can lead to inadvertent injection of bugs. It happens when a coder changes the code in one place but fails to update the code that was duplicated in other locations. To alleviate the problem of duplication, this keyword can be used to make calls to other constructors. The nal example of this module, Program listing 13 demonstrates how to make calls to the other constructors. Program Listing 13 Example of this with Constructors public class Account { private String number; private double balance; public Account() { this("", 0.0); } public Account(String accountNumber) { this(accountNumber, 0.0); } public Account(String number, double balance) { this.number = number; this.balance = balance; } public void setNumber(String accountNumber) { this.number = accountNumber; } public void setBalance(double accountBalance) { this.balance = accountBalance; } public String getNumber() { return this.number; } public double getBalance() { return this.balance; } }

Now there is only one constructor that holds the business logic and the other two constructors invoke it for the initialization. Employing this tactic removes the duplicate code blocks and centralizes the logic with the constructor that has the most parameters.

Page 88

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

5.3 Lab Activity


Part 1. Create a Date class to represent a date and a year. It should store the day, month, and year. Each part of the day should have an accessor and mutator method. The month entity should have an overloaded mutator method. One that takes an integer value and the second that takes the String representation of the month. public void setMonth(int month) { ... } public void setMonth(String month) { ... } The Date class should also provide two constructors. public Date(String month, int day, int year) { ... } public Date(int month, int day, int year) { ... } Finally, create methods to return the date in the following formats. 1/13/2006 January 13, 2006 Part 2. Create an Event class. It should store the name of the event, the location of the event and the date of the event. The date of the event should be maintained by the Date class created in part 1. Part 3. Create a Planner class that can hold up to 10 events. Create a method to add events to the planner. Also provide a method for printing out all of the events in the planner. The output should look like the following. My Event @ Some Place (2/4/2007) Your Event @ Another Place (3/24/2007) Page 89 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 5. METHODS Lastly code a method that will print out an invitation for a selected event. The output should look like the following. You are cordially invited to attend My Event at Some Place on February 4, 2007 Part 4. Create a class with a main method. It should construct a Planner class and add 5 events to the planner. After adding the events have the planner print out a list of all the events. Then print out an invitation to the 3rd event. Part 5. (Optional) Modify the Date class to make sure that the day and month values passed in are valid values for those elds. Part 6. (Optional) Using the Planner class create an InvitaionMaker class. Use the command line to pass in the name, location and date for the event. The data should be comma separated. Have the program print an invitation for the event.

Page 90

c 2008 n + 1, Inc All Rights Reserved

Chapter 6

Inheritance
Objectives
Understand how inheritance works in Java Learn how to use the extends keyword. Understand what the is the super variable. Learn how to use the super variable. Understand how constructors are eected by inheritance Understand how packages work. Learn how to use the package identier. Understand how to import objects from packages. Understand how to use access modiers Understand how to use static variables and methods Understand how to use the nal modier

91

CHAPTER 6. INHERITANCE

6.1 Java Inheritance


In the dictionary, the word inherit means to receive an ancestors property by the laws of inheritance upon the ancestors death. The classic denition is what comes to most peoples mind rst. One of the alternate denitions listed is to have certain characteristics by heredity. The latter denition ts much closer into the programming meaning of the word inheritance. When a person is born they have the characteristics of both of their parents. In the case of the ctional character Harry Potter, he inherited his fathers looks, but had his mothers eyes. He had attributes from both of his parents. In the programing world acquiring attributes from more than one parent object is known as multiple inheritance. The degenerate case for inheritance occurs when a child object inherits traits from only one parent. This is known as single inheritance. Java, being an object oriented language, provides support for inheritance. But Javas support for inheritance in limited to the degenerate case of single inheritance. The limitation turns out to be useful because it keeps developers from coding a tangled inheritance tree that is dicult to understand and maintain.

Page 92

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.1.1 Inheritance and Java


The parent class in an inheritance relationship can be any object. The Account class shown in program listing 14 is an example of a base class. It has two attributes, number and balance, along with a simple method to print out the account number and the balance. Program Listing 14 Base Account Class public class Account { public String number; public double balance; public void print() { System.out.println("Account Num = " + number); System.out.println("Account Balance = " + balance); } }

If the task was to create a SavingsAccount class, what attributes would the class have? It would need an account number, a balance, and an interest rate. Notice that the Account class has two of those three attributes. Rather than starting from scratch, the Account class can be used as the foundation for the creation of the SavingsAccount. Building on the Accounts foundation is done through inheritance. The extends keyword is used in Java to show that one class inherits the functionality of another. Therefore, the SavingsAccount extends the Account class. Program Listing 15 Derived SavingsAccount Class public class SavingsAccount extends Account { public float interestRate; public void calculateInterest() { balance *= (1 + interestRate); } }

In program listing 15 the SavingsAccount class extends or inherits the functionality of the Account class. Once the extends keyword is deployed the SavingsAccount immediately gains all of the functionality of the parent class. The rest of the classs denition provides additional functionality. It is the added capabilities that transform the SavingsAccount from an Account to a SavingsAccount. Program listing 16 provides an example of using the new SavingsAccount class.

Page 93

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE Program Listing 16 Using SavingsAccount Class public class Main { public static void main(String[] args) { SavingsAccount myAccount = new SavingsAccount(); myAccount.number = "ACME1234"; myAccount.balance = 351.23; myAccount.interestRate = .05f; myAccount.print(); myAccount.calculateInterest(); myAccount.print(); } }

Running the Main class leads to the following results Account Account Account Account Num = ACME1234 Balance = 351.23 Num = ACME1234 Balance = 368.7914832520485

Notice that the SavingsAccount class has all of the functionality dened in the SavingsAccount class plus all of the additional functionality of the Account class.

Page 94

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.1.2 Overriding methods


The only problem with the SavingsAccount class is the output from the print() method. The method only prints information pertaining to the account. The output shows only the account number and the account balance. Is there any way to modify the print method to add the interest rate to the output? Java provides a mechanism to override the parent classs implementation. It involves adding to the child class an implementation of the parents method with the same signature. In doing so, the child class will use its implementation rather than the parents. Program listing 17 provides an example of overriding the Accounts print() method in the SavingsAccount Program Listing 17 Overriding Account Class public class SavingsAccount extends Account { public float interestRate; public void calculateInterest() { balance *= (1 + interestRate); } public void print() { System.out.println("Savings Account Num = " + number); System.out.println("Savings Account Balance = " + balance); System.out.println("Savings Account Rate = " + interestRate); } }

Now when the Main class is run, the print() method invoked is the one that was re-written in the SavingsAccount class. Savings Savings Savings Savings Savings Savings Account Account Account Account Account Account Num = ACME-1234 Balance = 351.23 Rate = 0.05 Num = ACME-1234 Balance = 368.7914832520485 Rate = 0.05

This process is known as method overriding. It occurs when the child class provides an alternate implementation of a parent classs method.

Page 95

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.1.3 Using super


The only problem with the SavingsAccounts print() method is that it introduces code duplication. When inspecting the methods from both classes, the lines that print the account number and account balance are duplicated. In this instance, the duplicated code is trivial, but the problem is real. Wouldnt it be nice if the parent classs implementation was reusable? The super variable allows us access to a parent classs implementation. It functions in a similar manner to the this variable with the exception of accessing the parents classes implementation instead of its own. Armed with the super variable, the SavingsAccount class can be rewritten to incorporate the parents implementation within the childs print() method. Program listing 18 provides an example of how to accomplish this task. Program Listing 18 Using super public class SavingsAccount extends Account { public float interestRate; public void calculateInterest() { balance *= (1 + interestRate); } public void print() { super.print(); System.out.println("Account Interest Rate = " + interestRate); } }

The example does two things. First, it calls the parent classs implementation of the print() method to print out the account number and the balance. Secondly it adds to the output the SavingsAccount specic data, interest rate. The results are shown below. Account Account Account Account Account Account Num = ACME1234 Balance = 351.23 Interest Rate = 0.05 Num = ACME1234 Balance = 368.7914832520485 Interest Rate = 0.05

The super variable can be used to access any methods or attributes of the parent class that are accessible by the child. This capability allows the developer to reuse the parents code without having to rely on code duplication.

Page 96

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.1.4 Constructors and Inheritance


What happens if the base or parent class has a dened constructor? To answer this question it is important to understand what happens when an object extends another object at construction time. When the derived or child class is constructed, the parents default or no argument constructor is called to initialize the parents state. Once the parents state is set, the childs constructor is executed. The next obvious question is what happens if the parents class doesnt have a default or empty argument constructor? Program listing 19 provides an example of the Account class with an overloaded constructor. Program Listing 19 Account Constructor Example public class Account { public String number; public double balance; public Account(String accountNumber, double balance) { this.number = accountNumber; this.balance = balance; } public void print() { System.out.println("Account Num = " + number); System.out.println("Account Balance = " + balance); } }

If an attempt is made to recompile the SavingsAccount class, the compilation will fail. Why? Because it cant nd the default or empty argument constructor to call at object creation. The only constructor for the Account class is the two argument method.

Page 97

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE Once again the super variable can be used to nd relief. It can be utilized in the rst statement of the childs constructor to call one of the parents constructors. The SavingsAccount class shown in program listing 20 can be rewritten to use super. Program Listing 20 Account Constructor Example public class SavingsAccount extends Account { public float interestRate; public SavingsAccount() { super("ACMEXXXX", 0.0); this.interestRate = 0.0f; } public void calculateInterest() { balance *= (1 + interestRate); } public void print() { System.out.println("Savings Account Num = " + number); System.out.println("Savings Account Balance = " + balance); System.out.println("Savings Account Rate = " + interestRate); } }

The super(...) method call at the beginning of the SavingsAccount constructor determined what parent constructor is called to perform proper initialization.

Page 98

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.2 Packages
The Java language forces developers to create one class per .java le. In smaller projects that only require a hand full of classes this restriction is not dicult to manage. Once the number of classes grow beyond a couple of dozen, two problems occur. The rst is managing the sheer number of les in a single directory. The second is the growing potential for naming conicts. While working on a project, it might make sense to have two classes with the same name. It would prove impossible if all of the source les are in the same directory. Java created a concept called packaging for organizing source les into a meaningful and manageable structure. Packages are the logical grouping of classes into a hierarchical structure. The hierarchy is maintained by the local le system.

Page 99

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.2.1 Package Basics


Packages levels are separated by a .. Where each . represents a new level in the organizational hierarchy. Each level is a subdirectory on the le system. Table 6.1 shows examples of mappings between package names and directory structure. Package bank bank.account bank.security bank.security.atm bank.security.teller bank.security.web Directory Structure ./bank ./bank/account ./bank/security ./bank/security/atm ./bank/security/teller ./bank/security/web

Table 6.1: Mappings of Package Name to Directory Structure While packages allow a person to organize a project into logical groupings there is still the chance for naming conicts. What if two dierent banks were writing software and they used the same naming convention show above? When the companies merged and attempted to combine software they could have a problem with naming conicts. To allow various organizations to have unique package names a convention was created to use an organizations domain name as part of the package name. If a companys domain name was nplus1.net the package name should begin with the domain name reversed. Therefore a package of security.web would become net.nplus1.security.web.

Page 100

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.2.2 package Keyword


When a source le is placed into a packages directory, a note must be made within the class to inform the class to which package it belongs. The package keyword is used to make this notation and must be on the rst line of the source le. Program listing 21 provides an example of the Account class being added to the net.nplus1.account package. Program Listing 21 Package Example package net.nplus1.account; public class Account { public String number; public double balance; public Account(String accountNumber, double balance) { this.number = accountNumber; this.balance = balance; } public void print() { System.out.println("Account Num = " + number); System.out.println("Account Balance = " + balance); } }

Of course, the Account.java le must be located in the ./net/nplus1/account/ directory for compilation.

Page 101

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.2.3 import
Packages are discrete entities. Classes assigned to a particular package can directly access other classes that reside in the same package, but not those outside of the package. It would defeat the purpose of packages if classes could only interact with other classes in the same package. Java provides the import statement as a means for giving visibility for a packages class to classes outside the package. When using the import statement the developer must explicitly state what class is desired and from what package the class resides. import net.nplus1.account.Account; In this example the user wants the Account class from the net.nplus1.account package to be available. Java allows as many import statements as necessary to provide access to all needed classes. import statements must be placed after the package statement but before the denition of the class. The Main class is reworked in program listing 22 to put it in a package and import the SavingsAccount class from the net.nplus1.account package. Program Listing 22 Importing Classes from Package package net.nplus1.main; import net.nplus1.account.Account; import net.nplus1.account.SavingsAccount; public class Main { public static void main(String[] args) { SavingsAccount myAccount = new SavingsAccount(); myAccount.number = "ACME1234"; myAccount.balance = 351.23; myAccount.interestRate = .05f; myAccount.print(); myAccount.calculateInterest(); myAccount.print(); Account yourAccount = new Account("ACME4321", 100.2); yourAccount.print(); } }

Page 102

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The * wild card 1 can be used to import all of the classes in a particular package. This allows a user to import multiple classes in one statement. The two import statements shown in program listing 22 could be replaced with the single import. import net.nplus1.account.*;

1 It is generally considered bad practice to use wild card import statements. The use of wild cards make it dicult to know what foreign classes are being used. It is preferred to explicitly state which classes are being used in a source le, making it is easier to track down what classes are being utilized.

Page 103

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.3 Modiers
Modiers provide a mechanism to associate special characteristics to classes, methods, and attributes.

Page 104

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.3.1 Access Modiers


Access modiers control what features of an object are available to other objects. Access modiers can be applied to any of the following: classes, attributes, methods, and constructors. There are four modiers available to developers. public, private, protected, and default. The default access modier is applied to any attribute, method or class that doesnt have an access modier. Default is the absence of an access modier. Table 6.2 shows the accessibility that each modier provides. Modier public protected Access public is the most generous access. Any object can access a resource which is marked as public. Only objects within the same package can access a resource which is marked as protected. In addition any child can access a parents protected resources regardless of what package in which the parent resides. default private Only objects within the same package can access a resource which is marked as default. Only the current object has access to any resources which are marked as private. Table 6.2: Access Modiers How are access modiers eected by inheritance? A child class always has access to any of a parents resources that are marked as public. Private resources on the other hand are not available to child classes. The protected2 and default access modiers are almost identical in that they provide access to any object within the same package as the resource. The only dierence is that the protected resource is available to any any child class regardless of package.

2 Protected access is rarely used because it breaks an objects encapsulation inside a package. Many will use protected to pass access of an attribute to a child class. This should be avoided. If the child needs access to a parents resource it should be done through a public accessor method. Default access should never be used.

Page 105

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE One question that often comes up is how to handle encapsulation when dealing with inheritance. If an attribute is marked as private, how can it be accessed by the child? The resources should be made available through public accessor and mutator methods (getter and setter methods). Listing 23 and 24 provides an example with the Account and SavingsAccount objects using encapsulation. Program Listing 23 Account Encapsulation Example package net.nplus1.account; public class Account { private String number; private double balance; public Account(String accountNumber, double balance) { this.number = accountNumber; this.balance = balance; } public void print() { System.out.println("Account Num = " + number); System.out.println("Account Balance = " + balance); } public void setNumber(String accountNumber) { number = accountNumber; } public void setBalance(double balance) { this.balance = balance; } public String getNumber() { return number; } public double getBalance() { return balance; } }

Page 106

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program Listing 24 SavingsAccount Encapsulation Example package net.nplus1.account; public class SavingsAccount extends Account { public float interestRate; public SavingsAccount() { super("ACMEXXXX", 0.0); this.interestRate = 0.0f; } public void calculateInterest() { double balance = this.getBalance(); balance *= (1 + interestRate); this.setBalance(balance); } public void print() { String number = this.getNumber(); double balance = this.getBalance(); System.out.println("Savings Account Num = " + number); System.out.println("Savings Account Balance = " + balance); System.out.println("Savings Account Rate = " + interestRate); } }

Remember that public and private should be the most often used access modiers. protected and default should only be used in special cases.

Page 107

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.3.2 Static Modier


The static modier is the most dicult of the modiers for beginners to understand. The static modier means that the resource which is marked static is associated with the class and not an instance of the class. A good way to think of this is that the class is a blueprint for the object and is used to create multiple instances of the same object. Methods and attributes with the static modier are associated with the single blueprint used in the construction of various objects. While resources without the static modier are associated with each instance of the class. There is only one instance of a static variable or static method. Static methods and variables are associated with the class and are referenced by using the class name. Take the SimpleInterestAccount class shown in Listing 25. Program Listing 25 Static Example public class SimpleInterestAccount { public String accountNumber; public double balance; public static double interestRate; public void printAccountInfo() { System.out.println("Account Number = " + accountNumber); System.out.println("Account Balance = " + balance); } } In this case, SimpleInterestAccount has two attributes, accountNumber and balance. Each instance of the SimpleInterestAccount will have these two attributes. They are set as previous examples of object attributes. SimpleInterestAccount account1 = new SimpleInterestAccount(); SimpleInterestAccount account2 = new SimpleInterestAccount(); account1.accountNumber = "ACME123"; account1.balance = 100.42; account2.accountNumber = "ACME321"; account2.balance = 432.69; In this case two instances of the SimpleInterestAccount is created and the attributes are set on both of them. What about the interestRate variable? The interestRate variable is associated with the SimpleInterestAccount class and not an instance of the class. It is accessed by the class and not an instance. The following snippet would fail to compile because the developer is trying to access the static variable in a non-static fashion. Page 108 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA account1.interestRate = .08; // this would not compile

To set the interestRate, the following would have to be used. SimpleInterestAccount.interestRate = .08; Notice that by using the class name to access the static variable, the developer now has created a global variable associated with the SimpleInterestAccount class. Since the interest rate will be the same for every simple account then this is a perfect use for a static variable.

Page 109

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE Now the SimpleInterestAccount class shown in program listing 26 can be modied to make use of the static variable. Program Listing 26 Using Static Variables in Methods public class SimpleInterestAccount { public String accountNumber; public double balance; public static double interestRate; public void printAccountInfo() { System.out.println("Account Number = " + accountNumber); System.out.println("Account Balance = " + balance); } public void updateBalance() { balance *= (1 + SimpleInterestAccount.interestRate); } }

Page 110

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Static methods behave in a similar fashion to static attributes. They are global methods associated with the class and not an instance of the class. It is important to note that static methods have direct access to static attributes. Thus static methods as shown in program listing 27 could be used to set the interestRate on the SimpleInterestAccount class. Program Listing 27 Using Static Method to Set Static Variable public class SimpleInterestAccount { public String accountNumber; public double balance; public static double interestRate; public void printAccountInfo() { System.out.println("Account Number = " + accountNumber); System.out.println("Account Balance = " + balance); } public void updateBalance() { balance *= (1 + SimpleInterestAccount.interestRate); } public static void setInterestRate(double rate) { interestRate = rate; } }

Page 111

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE Program listing 28 shows a nal example of a class that uses the SimpleInterestAccount. Program Listing 28 Example Using Static Modiers public class Main { public static void main(String [] args) { SimpleInterestAccount accountOne = new SimpleInterestAccount(); SimpleInterestAccount accountTwo = new SimpleInterestAccount(); SimpleInterestRate.setInterestRate(.11); accountOne.accountNumber = "ACME5421"; accountOne.balance = 100.1; accountTwo.accountNumber = "ACME1245"; accountTwo.balance = 200.5; accountOne.updateBalance(); accountTwo.updateBalance(); accountOne.printAccountInfo(); accountTwo.printAccountInfo(); } }

When run the following results are printed. Account Account Account Account Number = ACME5421 Balance = 111.111 Number = ACME1245 Balance = 222.555

It is worth noting that main is a static method associated with the class. When the virtual machine is loaded Java attempts to invoke the classes static method main(String [] args). Thus the static main method is the starting point for all applications.

Page 112

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

6.3.3 Final Modier


The nal modier is used to specify that the variable can not be changed from its initial value. Any attempt to modify a nal variable will result in a compiler error. nal is usually attached to constant values. Program listing 29 shows the use of the nal modier. Program Listing 29 Example Using Final Modier public class Constants { public final static double PI = 3.1459; public final static String APP_NAME="My Favorite Application"; } public class Main { public static void main(String [] args) { System.out.println("App Name = " + Constants.APP_NAME); System.out.println("PI = " + Constants.PI); Constants.PI = 3.14; /* this will cause a compiler error because PI can not be modified since it is marked as final */ } }

Final can be applied to methods as well. Any method marked as nal can not be overridden by the child implementation. public class Account() { public final void printAccountInfo() { ... } } public class SavingsAccount extends Account { /* This method will throw a compiler exception because it can not be overridden since it has been marked as final */ public void printAccountInfo() { .... } }

Page 113

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 6. INHERITANCE

6.4 Lab Activity


Part 1. Create a Shape class that has one attribute that holds the number of sides and name of the shape. Make sure that all attributes in this lab have the appropriate getter and setter methods. The Shape should have a method that prints the area of the shape. For this generic class the method should say how many sides the shape has and that the area is indeterminate. Write a main that creates a Shape class and sets the number of sides to 9. Have the shape print out the number of sides and the area. Output should look like the following: The shape 9 sides with an indeterminate area. (Hint: Set information about shape in a default constructor) Part 2. Create a Circle class that derives from the Shape class. It should have the attribute radius and a nal static attribute PI (). For this exercise PI should be equal to 3.14159. The formula for calculating area is area = r2 where r = radius Write a main that creates a Circle with a radius of 4.6 and prints out the area for the circle. The answer should look like the following: The circle has 0 sides with an area of 66.476 Part 3. Create a Rectangle class that derives from the Shape class. It should have two attributes to represent the width and height. It should have a single constructor that takes the width and height of the rectangle as arguments. Write a main that creates a Rectangle with a width of 11.1 and a height of 4.5. Print out the area of the rectangle. Part 4. Extend the Rectangle class by creating a Square class. Use a constructor that takes the length of the squares side as an argument. Write a main that creates a Square with a length of 9 print out the area of the square. What happens if the square class sets the height = 10 and the width = 5? What is the area outputed? If the value is 50 then the answer is wrong because a square can not be 5 x 10. Fix the Square class to handle this problem. Page 114 c 2008 n + 1, Inc All Rights Reserved

Chapter 7

Interfaces and Abstract Classes


Objectives
Understand how to use an interface Learn how to apply polymorphism Understand what is an abstract class Learn how to use abstract classes

115

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES

7.1 Interfaces
Object Oriented1 development provides a powerful set of tools for create complex software. The tools consist of encapsulation, inheritance, data abstraction, and polymorphism. The focus of this module will be on the polymorphic aspects of OOP. Originally when the OO paradigm was introduced, it was thought to be a savior for development. It was believed that developers could reuse code from project to project. Unfortunately it didnt work out that way. While some utility objects could be used in multiple applications, most code could not because the problem domains were too dierent between projects. As time progressed, it became apparent that the true benet of OO was not reusability of code, but the exibility of design. It allows developers to solve dicult problems in elegant ways that reduces impact on the entire system. The backbone of the exible design is polymorphism. The term polymorphism derives from two words poly and morph. Poly means many and morph means to change shape. Therefore the word polymorphism means something that has the ability to change into many dierent shapes. When the word is applied to programming the something is an object, and the dierent shapes become dierent data types. Polymorphism is the ability for an object to assume a dierent data type depending on the situation. Interfaces provide a mechanism for implementing polymorphic behavior.

1 Object

Oriented Programming is known as OOP. OO is a short hand term for Object Oriented

Page 116

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

7.1.1 Conversion and Casting


In a previous module, the concepts of conversion and casting were introduced with regards to primitives. Primitive data types can be converted from one type to another. When going from a smaller data type to a larger data type conversion is done automatically. For example, if one had a short which is two bytes and wished to assign it to an integer which is four bytes, it would be done automatically through conversion. short x = 5; int y = x; But, if one had a larger data type and was converting it to a smaller data type then the developer has to force the conversion with a cast. For example, if one had the same four byte integer and wanted to pare it down into a two byte short then their is a potential for lost data. Therefore the developer must force the conversion to take place through the use of the casting operator. int x = 5; short y = (short)x; The same general concept can be applied to inheritance. The SavingsAccount class can also be treated as an Account class. Why? Because the SavingsAccount class extends the Account class, it has all of the functionality of an Account class. Therefore it is possible to assign a SavingsAccount type to an Account type. The object can be both a SavingsAccount type and an Account type. SavingsAccount x = new SavingsAccount(); Account y = x; This represents the simplest form of polymorphic behavior. The opposite of this condition is not true. Not all Accounts are SavingsAccounts. The Account class might be just an Account. In which case the conversion wouldnt make any sense because the Account object created has none of the attributes and methods associated with a SavingsAccount. Account x = new Account(); SavingsAccount y = x; // this will not compile What if another class, LoanAccount, extended the Account class. It would be silly to assign the LoanAccount class to the SavingsAccount variable. LoanAccount x = new LoanAccount(); SavingsAccount y = x; // this will not compile In Java, each dened class is really introducing a new data type. Thus the Account class is creating a new data type of Account. Inheritance provides a mechanism to extend the functionality of a Page 117 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES data type (parent class) into a new data type (child class). Thus it is possible to treat a child object the same as a parent object. In addition if a conversion is made to the parent type it is possible to convert back to the original child type using the casting operator2 . SavingsAccount x = new SavingsAccount(); Account y = x; SavingsAccount z = (SavingsAccount)y; Here Account y is a converted SavingsAccount. Therefore it is possible to cast the Account object back into its original type.

2 Attempting to

cast an object to a type which it is not will lead to a runtime ClassCastException.

Page 118

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

7.1.2 Interface Basics


One of the problems with inheritance is the tight coupling of parent and child class. Any changes that are made to the parent class eect all children classes. The problem is exacerbated if a second level of inheritance is deployed 3 Any changes to the grandparent class eects all of its children classes along with all of the grandchildren classes. The amount of code eected can become staggering. Interfaces on the other hand provide a polymorphic mechanism that does not carry the same baggage as inheritance. An interface is nothing more than a group of method denitions. What makes an interface useful is that those methods become the denition for a programmable type. When a class is marked to implement an interface it agrees to provide an implementation for those methods dened by the interface. In doing so the object takes on the characteristics of the interface and can be treated as the interface. In addition to adding polymorphic behavior to an object, interfaces are more exible than inheritance. A child class can only extend a single parent class, but can implement multiple interfaces. The ability to implement multiple interfaces provides opportunities more dynamic type castings. Interfaces are dened in a manner that is similar to a class. It is dened in its own le which must match the name of the interface. In addition an interface is composed of a set of abstract methods that have no implementation. The Interest Account interface shown in listing 30 provides an example of a simple interface. Program Listing 30 InterestAccount Interface public interface InterestAccount { void calculateNewBalance( ); void setInterestRate(double rate); double getInterestRate(); } The rst thing to note about the InterestAccount is that it replaces the class keyword with the new keyword interface. This tells the compiler that le is an interface rather than a class. The next thing to note is that there are no attributes associated with an interface. Finally, it is important to understand that the interface only denes methods signatures and not implementations. In the case of the InterestAccount, the interface denes three methods, calculateNewBalance, setInterestRate, and getInterestRate, but provides no implementation details. Since an interface does not have any attributes and does not provide any implementations, it can not be directly instantiated. The following code would not compile. InterestAccount iAccount = new InterestAccount(); This makes sense because there is no attributes to measure state nor any methods to call. If an interface can not be instantiated, how is it used?
is good practice to not allow multiple levels of inheritance. In fact a second level of inheritance should never be used unless the need is great.
3 It

Page 119

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES To employ an interface, a class must declare that it will implement the interface. Java provides the keyword implements to assign an interface to a class. implements is placed after the class name. If the class extends another class then implements trails the extends statement. It is then up to the class to provide the implementations for the methods dened in the interface. Program listing 31 builds o the SavingsAccount class from listing 23 to show how a class can implement an interface. Program Listing 31 SavingsAccount Implementing InterestAccount public class SavingsAccount extends Account implements InterestAccount { float interestRate; /* overriding the constructor */ public SavingsAccount() { super(0, 0f); this.interestRate = 0f; } /* overriding childs implementation of the print method public void print() { super.print(); System.out.println("Account Interest = " + interestRate); } /* Next three methods fulfill the implements contract by providing an implementation of the InterestAccount interface */ public void calculateNewBalance() { balance *= (1 + interestRate); } public void setInterestRate(double rate) { this.interestRate = rate; } public double getInterestRate() { return this.interestRate; } }

Why use an interface? Because it allows a class to be treated as the interface. Look at the following example. SavingsAccount savings = new SavingsAccount(); InterestAccount account = savings; In this case the SavingsAccount class is instantiated and associated with the variable savings. Next Page 120 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA an InterestAccount type is created with the name account and is associated with the SavingsAccount object referenced in the savings variable. This is possible because the savings object has implemented all of the methods associated with the InterestAccount interface. Therefore, it is possible to make calls on the account interface type because the implementation is provided by the SavingsAccount object. SavingsAccount savings = new SavingsAccount(); InterestAccount account = savings; account.setIntererestRate(.05); account.calculateNewBalance(); What cant be done is to make calls on the InterestAccount that are not part of the interface. Only the methods associated with the interface are available and not the underlying class. Thus the following will give a compiler error. SavingsAccount savings = new SavingsAccount(); InterestAccount account = savings; account.setIntererestRate(.05); account.calculateNewBalance(); /* next line throws a compiler error because print() is not defined in the InterestAccount interface */ account.print(); Since objects can be assigned based on the interface type, it is possible to pass objects to methods based on their interface types as well. An object can be passed to a method by interface type and the called method only has access to the methods dened by the interface. Program listing 32 shows an example of passing by the interface. The results of the calculation are shown below. Account Account Account Account Account Account Number = ACME4321 Balance = 107.0 Interest = 0.06 Number = ACME1234 Balance = 214.0 Interest = 0.07

Two things to note when looking at program listing 32. When performing the assignment of the interface account1 to the savings1 object, account1 is assigned the memory location of the Page 121 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES Program Listing 32 InterestAccount Interface public class Main { public static void main(String [] args) { SavingsAccount savings1 = new SavingsAccount(); SavingsAccount savings2 = new SavingsAccount(); savings1.setNumber("ACME4321"); savings1.setBalance(100.0); savings2.setNumber("ACME1234"); savings2.setBalance(200.0); // associating to account interface and passing InterestAccount account1 = savings1; adjustBalance(.06, account1); // doing the conversion when passing adjustBalance(.07, savings2); savings1.print(); savings2.print(); } public static void adjustBalance(double rate, InterestAccount account) { account.setInterestRate(rate); account.calculateNewBalance(); } }

savings1 variable. In eect, they reference the same object, but are represented as two dierent types. Secondly, in the call to adjustBalance the savings2 variable is passed directly to the method. The conversion is done implicitly and not explicitly as the previous call.

Page 122

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

7.1.3 Polymorphism and Interfaces


The biggest problem developers have trying to meet project deadlines is the ever moving requirement specication. Every developer has been faced with the problem of always changing requirements. Most developers can tell tales of the diculty involved in hitting a moving target on schedule. To be able to handle the volatility of the requirements, developers must look to exible solutions that are malleable enough to meet the changing requirements. Interfaces are a tool that applied correctly can lead to a more pliant solution. This section takes a simple requirements document and steps through the process of creating a exible solution that can withstand future changes to the requirements.

Calculator Requirements The goal is to write a simple command line calculator that can add or subtract two numbers based on the user input. It should provide the following output: $> java Calc 5 + 3 5 + 3 = 8 $> java Calc 5 - 3 5 - 3 = 2

For this project, assume that the data on the command line will be entered correctly.

First Pass Design The rst instinct is to think of a quick solution to the problem. The solution would probably include a simple command line parser that takes the data and breaks it down into operators and an operation. Next a simple if/else if block can be used to determine the operation and provide the proper calculation. But what if the design changes? What if we add additional operation types like multiplication? We would have to add more if-else blocks for each operation which would get bulky quickly. The problem gets worse if the requirements require multiple operations. $> java Calc 5 + 3 - 2 * 4 5 + 3 - 2 * 4 = 24

Rewriting the program from listing 33 would be ugly and become convoluted quickly. Page 123 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES Program Listing 33 First Solution public class Calc { public static void main(String [] args) { int x = Integer.parseInt(args[0]); int y = Integer.parseInt(args[2]); int results = 0; String operation = args[1]; if ( operation.equals("+") ) { results = x + y; } else if ( operation.equals("-") ) { results = x - y; } for (int i = 0; i < args.length; i++) { System.out.print(args[i] + " " ); } System.out.println("= " + results); } }

Second Pass Design Looking at the requirements again, what is the real problem that is trying to be solved? Take a moment to consider this question. The answer can be found in the early stages of analysis in the rst design: break it down into operators and operations. The best design would center on around nding ways to create operators and perform operations.

The Operations The rst step is to abstract the operation by representing it as an interface. Program listing 34 shows what that interface might look like. Program Listing 34 Operation Interface public interface Operation { public int calculate(int x, int y); }

Page 124

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA At this point each operation in the requirements can be represented as a class that implements the Operation interface. Program listing 35 shows the implementation details for adding and subtracting numbers. Program Listing 35 Operation Implementations public class Add implements Operation { public int calculate(int x, int y) { return x + y; } } public class Sub implements Operation { public int calculate(int x, int y) { return x - y; } }

Page 125

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES The Factory At this point it is important to provide a mechanism for creating operations. In this case, we are going to isolate the creation process into a stand alone factory class and return the results as an Operation. Program Listing 36 Operation Factory public class OperationFactory { public Operation createOperation(String operation) { Operation op = null; if ( operation.equals("+") ) { op = new Add(); } else if ( operation.equals("-") ) { op = new Sub(); } return op; } }

The solution to the factory is shown in program listing 36. It instantiates the appropriate operation based on user input, and associates it with the Operation interface variable op. The operation is then returned by the interface and not the actual type such as Add. This will allow us to create a calculating machine that can handle any Operation without being concerned with the details of any particular operation.

Page 126

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program Listing 37 Operation Calculator public class OperationCalculator { private OperationFactory factory; public OperationCalculator() { factory = new OperationFactory(); } public int calculate(String operation, int x , int y)) { Operation op = factory.createOperation(operation); int results = op.calculate(x, y); return results; } }

The OperationCalculator class in program listing 37 provides an implementation of the calculator. What makes the calculator nice is that it takes the data an performs the operation without concerning itself with what type of operation is being run.

Page 127

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES The Parser The nal step in creating the application is to create a parser for handling user input, running the calculator, and displaying the output. The previous example can be modied to perform this role as shown in program listing 38. Program Listing 38 Second Solution public class Calc { public static void main(String [] args) { int x = Integer.parseInt(args[0]); int y = Integer.parseInt(args[2]); String operation = args[1]; OperationCalculator calc = new OperationCalculator(); int results = calc.calculate(operation, x ,y); for (int i = 0; i < args.length; i++) { System.out.print(args[i] + " " ); } System.out.println("= " + results); } }

Page 128

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Handling Change What about change? Adding a new operation is trivial process. Lets take for example multiplication. All that is necessary is to crate a new Multiplication class that implements the Operation interface and update the factory to instantiate the operation. The results are shown in program listing 39 Program Listing 39 Handling Change public class Multiplication implements Operation { public int calculate(int x, int y) { return x * y; } } public class OperationFactory { public Operation createOperation(String operation) { Operation op = null; if ( operation.equals("+") ) { op = new Add(); } else if ( operation.equals("-") ) { op = new Sub(); } else if ( operation.equals("*") ) { op = new Multiplication(); } return op; } }

What is nice about this change process is that each operation is isolated and decoupled from one another. A change in one operation will not eect any of the other operations. Most developers can tell a story of an instance where they made a change to some code and it had an adverse eect on some code they never knew was related. In this instance a change to multiplication will not eect addition or subtraction and vice versa. Nor will it eect the way that calculations are preformed. Therefore adding new operations to the code base has very little impact on the application.

Page 129

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES What if we want to add multiple operations? This can be done in the parser without fear of eecting any other code in the system. In fact the decoupling of code, leads to a rather elegant solution which is shown in program listing 40. Program Listing 40 Multiple Operation Parser public class Calc { public static void main(String [] args) { int x = Integer.parseInt(args[0]); OperationCalculator calc = new OperationCalculator(); for ( int j = 1; j < args.length; j += 2) { String operation = args[j]; int y = Integer.parseInt(args[j + 1]); int x = calc.calculate(operation, x ,y); } results = x; for (int i = 0; i < args.length; i++) { System.out.print(args[i] + " " ); } System.out.println("= " + results); } }

Page 130

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Design Patterns Flexibility of design is one of the most compelling reasons to use object oriented programming. It is the reusability of good design ideas that make OO so protable. Reusable design ideas can be cataloged as design patterns. Design Patterns: Elements of Reusable Object-Oriented Software4 is a great book that introduces some basic design patterns. The calculator example in this module uses two of the patterns from the book. The factory pattern was used to create the Factory class and the command pattern was used to model operations as a common interface.

4 Design

Patterns: Elements of Reusable Object-Oriented Software (ISBN 0-201-63361-2)

Page 131

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES

7.2 Abstract Classes


Abstract classes are a partial implementation of a class. An object has a dened set of methods while an interface is a set of abstract methods. The abstract class lies some where in between. By denition an Abstract class is a class with at least one method which has not been implemented. That method must be marked as an abstract method using the abstract modier. Any class with an abstract method must be marked with the abstract modier as well. Listing 41 shows an example of an abstract class. Program Listing 41 Simple Abstract Class public abstract class BaseLoan { private String name; private String type; public String getName() { return this.name; } public String getType() { return this.type; } public void setName(String name) { this.name = name; } public void setType(String type) { this.type = type; } public abstract double calculateRate(); }

In the BaseLoan example the class has private attributes and some methods dened. But notice that the calculateRate method is marked as abstract and has no implementation. A method without an implementation is known as an abstract method and must be marked for compilation. The class is also marked abstract because it contains an abstract method. Since not all of the methods are dened it is similar to an interface in that it can not be instantiated directly. BaseLoan loan = new BaseLoan() // will not compile

Therefore to use the abstract class it must be extended through inheritance. Program listing 42 provides an example of a class that extends the abstract class and provides an implementation for the abstract method. Program Listing 42 Simple Abstract Class public class HighRiskLoan extends BaseLoan { public double calculateRate() { return .12; } }

It is important to note that if the derived class does not implement all of the parent classs abstract methods it too must be marked as abstract because there are methods that still havent been Page 132 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA implemented.

Page 133

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES

7.2.1 Abstract Classes and Interfaces


Abstract classes can be useful when working with interfaces. Examining the interface in program listing 43, it can be discerned that the interface is used for form processing on the web. The interface provides a mechanism for initializing the form, processing the data and handling error messages. Program Listing 43 Web Form Interface public interface WebForm { public void addErrorMessae(String message); public String [] getErrorMessages(); public int getNumberMessages(); public boolean isError(); public void initializeWebForm(); public void processWebData(WebData data); }

Page 134

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA When looking at this interface it is obvious that the error handling routines are going to be the same for every class implementing the WebForm interface. The only thing that will be dierent is the form initialization and the processing of web data. Therefore the common functionality can be placed into an abstract class so it can be shared without providing all the functionality of the interface. The AbstractWebForm is shown in program listing 44. Program Listing 44 Abstract Web Form Class public abstract class AbstractWebForm implements WebForm { private int index; private String [] errorMessage; public AbstractWebForm() { errorMessages = = new String[10]; index = 0; } public void addErrorMessae(String message) { errorMeessages[index] = message; } public String [] getErrorMessages() { return errorMessages; } public int getNumberMessages() { return index; } public boolean isError() { boolean error = false; if ( index > 0 ) { error = true; } } public abstract void initializeWebForm(); public abstract void processWebData(WebData data); }

Page 135

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES Now, instead of providing error handling for every class that implements the WebForm interface, each class can extend the AbstractWebForm to pick up default implementations of the error handling. In the case shown in program listing 45, the PersonalWebForm extends the AbstractWebForm and implements the abstract methods to fulll the contract of the WebForm interface. In this case, the PersonalWebForm only needs to implement the two abstract methods along with any other methods necessary to manage the form data. Now the PersonalWebForm can be treated as either a WebForm or an AbstractWebForm polymorphicaly. Program Listing 45 Abstract Web Form Class public class PersonalWebForm extends AbstractWebForm { private String firstName; private String lastName; private int age; public void initializeWebForm() { firstName = ""; lastName = ""; age = 1; } public abstract void processWebData(WebData data) { firstName = data.getString("firstName"); if ( firstName == null ) { this.addErrorMessage("Must supply a first name"); } lastName = data.getString("lastName"); if ( lastName == null ) { this.addErrorMessage("Must supply a last name"); } age = data.getInt("age"); if ( age < 1 ) { this.addErrorMessage("Must supply a valid age"); } } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } }

Page 136

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

7.3 Lab Activity


Part 1. You are given the following interfaces for a calculator and accounts. public interface AccountInformation { public void setFirstName(String name); public void setLastName(String name); public void setInitialBalance(double balance); public void setInterestRate(double rate); public String getFirstName(); public String getLastName(); public double getInitialBalance(); public double getInterestRate(); } public interface InterestCalculator { public double calculateFutureValue(int yearsInvested); } The goal is to create three concrete classes that implement both the AccountInformation and InterestCalculator interface to perform the following functions. Calculates interest on a yearly basis (YearlyInterestCalculator) Calculates interest monthly (MonthlyInterestCalculator) Calculates interest continously (ContinousInterestCalculator) Calculations for Interest Yearly: Monthly: Continous: Where C r t n P Initial balance we are calculating from Interest rate for the calculation Number of years invested Number of times per year interest in compounded Interest value P = C * Math.pow(1 + r,t); P = C * Math.pow(1 + (r/n),(n * t)); P = C * Math.pow(Math.E,(r*t));

Since we are programming to the interface the following main method will generate results shown below. Page 137 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES public class InterestCalc { public static void main(String [] args) { YearlyInterestCalculator year = new YearlyInterestCalculator(); MonthlyInterestCalculator month = new MonthlyInterestCalculator(); ContinousInterestCalculator cont = new ContinousInterestCalculator(); year.setFirstName("John"); year.setLastName("Doe"); year.setInitialBalance(5000.0); year.setInterestRate(.06); month.setFirstName("Jane"); month.setLastName("Doe"); month.setInitialBalance(5000.0); month.setInterestRate(.06); cont.setFirstName("Timmy"); cont.setLastName("Smith"); cont.setInitialBalance(5000.0); cont.setInterestRate(.06); outputAccountData(year); outputValueAfterYears(year, 7); outputAccountData(month); outputValueAfterYears(month, 7); outputAccountData(cont); outputValueAfterYears(cont, 7); } public static void outputAccountData(AccountInformation account) { System.out.println("Hello " + account.getFirstName() + " " + account.getLastName()); System.out.println("Your initial value is " + account.getInitialBalance()); System.out.println("Your interest rate is " + account.getInterestRate()); } public static void outputValueAfterYears( InterestCalculator calc, int numberYears) { System.out.println("After " + numberYears + " years your money will be worth " + calc.calculateFutureValue(numberYears)); System.out.println(""); } } Results: Page 138 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Hello John Doe Your initial value is 5000.0 Your interest rate is .06 After 7 years your money will be worth 7518.151294956803 Hello Jane Doe Your initial value is 5000.0 Your interest rate is .06 After 7 years your money will be worth 7601.848180410411 Hello Timmy Smith Your initial value is 5000.0 Your interest rate is .06 After 7 years your money will be worth 7609.807778093168

Page 139

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 7. INTERFACES AND ABSTRACT CLASSES

Page 140

c 2008 n + 1, Inc All Rights Reserved

Chapter 8

Utility Classes
Introduction Objectives
Understand the Object class Understand how all objects can be stored Learn how to use the wrapper classes Learn how autoboxing works with wrapper classes Learn some of the math functions available Understand how to use the Runtime and System classes Understand how garbage collection works Learn how to collect user input Understand how the Date and Calendar classes work Learn how to format data for output

141

CHAPTER 8. UTILITY CLASSES

8.1 java.lang Package


The String object has been used throughout this courseware. Where does the String class come from? Looking at Javas API, the String class can be found in the java.lang package. If the String is part of a package why is the import statement is unnecessary for its use. Java automatically includes the java.lang package in the virtual machines CLASSPATH. The java.lang package contains a number of classes, such as the String class, that are important to the core language. Since java.lang package is part of the CLASSPATH, any class residing in it does not have to be imported.

Page 142

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.1.1 Object class


The Object class is the base or parent class for all Java class. Every class created inherits either directly or indirectly from this class. Every class has access to the functionality dened in the Object class. When a class is declared and it doesnt extend another class then the Object class gets extended implicitly and not explicitly. public class Account Therefore a simple class declaration shown above is really a shortcut for the following declaration. public class Account extends Object And any class that extends Account also retains the features of the Object class. In this case the SavingsAccount object extends the Account class which in turn extends the Object class. public class SavingsAccount extends Account Since all classes inherit features from the Object class, what are the features of the Object class. Table 8.1 provides a list of useful methods that can be found in the Object class. Method boolean equals(Object object) String toString() wait(), notify(), notifyAll() Description Determines if two objects are equal. returns a string representation of the object. All three of these methods are used for multi-threading. Table 8.1: Object methods When looking at the Object class, two of the methods from the table are commonly overridden to provide better implementations. The equals(...) method by default checks the memory location of the two objects to see if they are the same object. Many times this method is overridden to provide a deeper equality check. The String class overrides the equals(...) method to test the equality of Strings.

Page 143

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES The toString() method is another common method to override. By default it prints memory information about the object. It is generally overridden to provide information about the internal state of the object. Making it an ideal candidate for logging / debugging. This method is also called whenever a string value is needed such as in String concatenation with the + symbol. Program listing 46 provides an example of overriding the toString() method. Program Listing 46 Overriding toString method class Account{ private int accountNumber; private double balance; public Account(int number, double balance) { accountNumber = number; this.balance = balance; } public String toString() { String output = "Account (" + accountNumber + ") "; output += "has a balance of " + balance; return output; } public static void main(String [] args) { Account account = new Account(1234, 452.22); System.out.println("Account Info: " + account); } }

Page 144

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.1.2 Wrapper Classes


There are times when it is useful to treat primitive data types as objects. java.lang provides a set of wrapper classes which can be use to retain a primitive value as an object. They are called wrapper classes because they provide a simple immutable holder for a primitive value. Once the class is created the primitive value can not be modied. Each primitive data type has an associated wrapper class. Below is an example of creating a wrapper class and then retrieving back the stored value. Integer x = new Integer(5); Double y = new Double(5.234); Boolean z = new Boolean(false); int j = x.intValue(); double k = y.doubleValue(); boolean i = z.booleanValue(); Why would anyone ever need to convert a primitive into an object? The occurrence is frequent in Java when one wishes to create a generic storage class. Think of a generic store as a class that can hold any object. This task can be done accomplished by taking advantage of the fact that the base object for all objects it the Object class. Program listing 47 provides an example of a simple object used to store an Object. Program Listing 47 Generic Object Storage class Storage{ private Object data; public void storeObject(Object data) { this.data = data; } public Object retrieveObject() { return data; } }

Since all objects derive from the base Object class, any object created can be converted to its base Object class. In the case below the Account class is converted to an Object and stored inside the Storage class. Storage store = new Storage(); Account account = new Account(); store.storeObject(account); Page 145 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES To retrieve the data, it is a simple process of returning the Object and converting it back to its original type. Since the conversion is going from generic to more specic a simple cast is necessary. Account myAccount = (Account)store.retrieveObject(); What does this have to do with the wrapper classes? Since primitives are not objects they can not be stored inside the Storage object. But, the wrapper classes are objects and thus can be stored inside the Storage object, allowing primitives to be stored using their wrapper classes. Integer x = new Integer(269); Storage store = new Storage(); store.storeObject(x); Integer y = (Integer)store.retrieveObject(); int z = y.intValue(); The collection classes which will be studied later use the Object as the means for storing data in a method that is similar to the one shown in program listing 47. Therefore if a developer wants to store a primitive value inside of a collection, it is important to understand how the wrapper classes operate.

Page 146

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Autoboxing One of the problems with Java before version 5 was the tediousness of converting primitives to their wrapper classes and back to primitives. In the following example it takes a line of code to covert to a wrapper class and then a line of code to convert back. int j = 269; Integer x = new Integer(j); int y = x.intValue(); Java 5 added a feature called autoboxing which will auto-magically perform this conversion. int j = 269; Integer x = j; int y = x; Reducing the amount of clumsy tediousness that occurs when programming with primitives and their wrappers classes. See how it simplies working with the storage object. int x = 269; Storage store = new Storage(); store.storeObject(x); int y = (Integer)store.retrieveObject(); In this case when storeObject(x) is called the primitive value is converted into an Integer and stored. When being retrieved, the Integer object is converted back to its original primitive value.

Page 147

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES

8.1.3 Math Class


The Math class in java.lang provides a number of methods and constants that can be used in mathematical calculations. Table 8.2 lists some of the mathematical methods that are available. PI and E are constants that are provided by the Math class as well. Method abs(double a) acos(double a) asin(double a) atan(double a) cos(double a) cosh(double x) hypot(double x, double y) log(double a) log10(double a) max(double a, double b) min(double a, double b) pow(double a, double b) random() round(double a) sin(double a) sinh(double x) sqrt(double a) tan(double a) tanh(double x) toDegrees(double angrad) toRadians(double angdeg) Description Calculates the absolute value. Calculates the arc cosine of an angle in radians. Calculates the arc sine of an angle in radians. Calculates the arc tangent of an angle in radians. Calculates the cosine of an angle in radians. Calculates the hyperbolic cosine. Calculates square root of (x squared + y squared) Calculates the natural logarithm (base e) Calculates the logarithm (base 10) Determines the greater of two value. Determines the smaller of two values. Calculates the value of the rst to the power of the second value. Determines a psuedo-random number between 0.0 and 1.0 Determines the closest whole number. Calculates the sine of an angle in radians. Calculates the hyperbolic sine of a value. Calculates the square root of the value. Calculates the tangent of an angle in radians. Calculates the hyperbolic tangent of a value. Converts an angle measured in radians to degrees. Converts an angle measured in degrees to radians Table 8.2: Math Class Methods All methods and attributes of the Math class have static nal modiers. Thus the Math class does not have to be instantiated to use. In addition the constants and methods can not be overridden or modied. double x = Math.pow(radius, 2) * Math.PI; double y = Math.sin(90);

Page 148

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.1.4 System and Runtime Classes


A single instance of the Runtime object is available to all applications. It provides a developer with an interface to the virtual machines operating system environment. Since there is only one instance, it is obtained through the static getRuntime() method. The run time is generally used to exit the application or to invoke outside applications. The exit(int status) method ends the execution of the current application and returns the status value to the operating system. The exit method allows threads to exit gracefully before the system shuts down. The halt(int status) method on the other hand forcibly halts execution of the program and returns the status to the OS. Runtime runtime = Runtime.getRuntime(); runtime.exit(1); Another use for the Runtime is the execution of applications running outside of the virtual machine. The exec(String [] commandArray) method invokes the application. In this case the string array represents the call to the command along with any command line options for the program. These options work the same way that command line arguments work coming into a Java applications main method. For an example, the following code would be used to run the program foobie with -l 5 -p command line options. String [] command = { "foobie", "-l", "5", "-p"} Runtime runtime = Runtime.getRuntime(); runtime.exec(command); The System class provides developers with access to standard input, standard output, and standard error streams. Each of which is represented by the static members in, out, and err respectively. System.out.println("This is a test"); The println statement above is an example of accessing the static System.out member to write output to the console. The input stream can be used to gather input from the console. Rather than discussing how to read Streams at this point, it is easier to use the utility Scanner class for reading user input. The Scanner class is found in the java.util package so it must be imported before use. It has a series of next methods for reading primitive data along with string data. Program listing 48 shows an example of using the scanner class. The getenv(String name) method is used to get operating system environment variables. String env = System.getenv("PATH"); System.out.println("env = " + env); The getProperty(String property) method is used to get properties that are passed to the virtual machine. Page 149 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES Program Listing 48 Using Scanner Class import java.util.Scanner; public class Test { public static void main(String [] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter your name:"); String name = scanner.nextLine(); System.out.print("Enter your age:"); String ageValue = scanner.nextLine(); int age = Integer.parseInt(ageValue); System.out.print("Enter the angle to calculate cosine:"); String angleValue = scanner.nextLine(); double angle = Double.parseDouble(angleValue); double radians = Math.toRadians(angle); double results = Math.cos(radians); System.out.println("\nHello " + name + " you are " + age + " years old"); System.out.println("The cosine of " + angle + " is " + results); } }

String prop = System.getProperty("java.awt.headless"); System.out.println("prop = " + prop); Properties are passed to the virtual machine using the -D option. > java -Djava.awt.headless=true Test

Page 150

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.1.5 Garbage Collection


One of the advantages of using Java over languages like C/C++ is the lack of memory management required by the developer. When an object is created with a new statement, memory is allocated on the heap and assigned to the new object. In C++, the developer is required to track that allocated memory and free it when done using it. Failure to free the memory can result in a memory leak, which are very dicult to track down. Java on the other hand manages all of the memory for the developer. Once the variable associated with the object goes out of scope, then that memory location associated with the variable is marked for cleaning. Javas garbage collector periodically scans the memory for areas that are marked for cleaning. The garbage collector then frees the memory for future allocation. The System and Runtime classes both have a gc() method that is used to run garbage collection. Runtime.gc(); System.gc(); However, it doesnt force garbage collection to occur at the moment gc() is invoked. Instead it suggests that garbage collection should be run as soon as possible. But there is no guarantee that it will be run at that moment.

Page 151

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES

8.2 Working With Dates


The Date class represents a specic instance in time. This includes the data and the time down to the nearest millisecond. In early versions of Java the Data class was used to manage dates and times. Because support for internationalization was weak, most of the methods for date manipulations in the Data class were deprecated1. Now the Date class is a wrapper class the the current time. In more recent versions of Java, manipulating dates and times is reserved for the Calendar class.

1 deprecated

methods are methods that are no longer supposed to be used but are grandfathered in for backwards

compliance

Page 152

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.2.1 Calendar Class


The Calendar class is an abstract class that provides a set of methods for working with and manipulating date and time elds. Since dates are locale specic2 , the Calendar class has a static getInstance() method that returns an instance of the concrete calendar class for the current locale3 . Calendar calendar = Calendar.getInstance(); The Calendar object returned is initialized to contain the current date and time. Calendar oers the int get(int field) method for retrieving information about the date. The int field value used is determined by the Calendar classes static constants. Table 8.3 shows a list of common constants. Constant AM PM HOUR HOUR OF DAY MINUTE SECOND MILLISECOND YEAR MONTH WEEK OF MONTH WEEK OF YEAR DAY OF MONTH DAY OF YEAR DAY OF WEEK Description Returns either morning or evening. (Table 8.4) Returns the hour of the morning or the evening (1-12) Returns the hour of the day (0-23) Returns the minute value (0-60) Returns the seconds value (0-60) Returns the millisecond (0-999) Returns the year Returns the month (Table 8.4) Returns the number for the month Returns the week in the year Returns the day in the month Returns the day within the year Returns the day of the week (Table 8.4) Table 8.3: Calendar Constants

2 Not 3 For

everyone uses the Gregorian calendar system. For example the Japanese have their own calendaring system. most this would be the GregorianCalendar object

Page 153

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES Below is an example of using the Calendar to get current time and date values. Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); System.out.println("Date: " + month + "/" + day + "/" + year); System.out.println("Day of Week: " + dayOfWeek); System.out.println("Time: " + hour + ":" + minute + ":" + second); If the following code was executed on Friday October 12th, 2007 at 4:45:41 PM what results would be expected? Does that match the actual output shown below? Date: 9/12/2007 Day of Week: 6 Time: 16:45:41 Isnt October the 10th month? What good is 6 for day of the week? What is going on here? The value returned for month, day of the week, and AM/PM are the Calendars constant value for the particular time period. Looking at the Calendar class a constant value of 9 is associated with October. public static final int SEPTEMBER = 8; public static final int OCTOBER = 9; public static final int NOVEMBER = 10; Table 8.4 shows the constant values for months, days of the week and AM/PM. Constants AM PM DAY OF WEEK MONTH Values AM, PM MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER Table 8.4: Calendar Constant Values Page 154 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The set(int field, int value) method is used to adjust the Calendar classes date and time values. The same constants that were used in retrieving the date and time elds are used in setting the Calendar values. Calendar cal = Calendar.getInstance(); cal.set(Calendar.MONTH, Calendar.OCTOBER); cal.set(Calendar.DAY_OF_MONTH, 13); cal.set(Calendar.HOUR_OF_DAY, 5); cal.set(Calendar.MINUTE, 30); Another method for manipulating the date is the add(int field, int value) method. Instead of dening the particular value, the developer can add or subtract the number of units they want from a particular eld. All of the other date elds are adjusted appropriately for the time increment. Below the Calendar is initialized to Jan 1, 2007 10:00 AM. Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 2007); cal.set(Calendar.MONTH, Calendar.JANUARY); cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(Calendar.HOUR, 10); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECONDS, 0); cal.set(Calendar.AM_PM, Calendar.AM_PM); What is the new date when each of the following items are run? cal.add(Calendar.HOUR, 8) cal.add(Calendar.DAY_OF_MONTH, 2) cal.add(Calendar.YEAR, 1) cal.add(Calendar.DAY_OF_MONTH, -3) cal.add(Calendar.SECONDS, -23) The rst one would add eight hours to the time which would be Jan 1, 2007 6:00 PM. The second line would add 2 days to the month which would adjust the Calendar to Jan 3, 2007 6:00 PM. The third would add one year leaving the Calendar at Jan 3, 2008 6:00 PM. The fourth line adds -3 days which would roll back the day of the month to 0. Since it cant be zero it would roll back the previous month. The month before January is December of the previous year which means the year rolls back as well. The new value of the Calendar would be Dec 31, 2007 6:00 PM. The nal line subtracts 23 seconds which would roll back to the previous minute of the previous hour. Giving a nal time of Dec 31, 2007 5:59:37 PM. The Calendar class can also transform its date and time into other useful formats. The getTime() method returns a Date object representation Calendars time and the getTimeInMillis() returns the current long value of time in milliseconds. Both of these forms can be useful when working with dates. Especially when working with Databases. Page 155 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES Date date = cal.getTime(); One last item of importance is the comparison of dates. The Calendar object has three methods that can be used to compare two Calendar objects. The after(Object calendar), before(Object calendar) and the equals(Object calendar) methods can be used to make comparisons between two Calendar objects Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); if ( cal1.before(cal2) ) { // is cal1s date before cal2s date } else if ( cal1.after(cal2) ) { // is cal1s date after cal2s date } else ( cal1.equals(cal2) ) { // is cal1s date the same as cal2s date } The same methods are available on the Date object as well. It is not that uncommon in Java to use the Calendar object to create Date objects and then compare the Date objects.

Page 156

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.2.2 Formatting Data for Output


One of the problems with using the generic println() statements for output text to the screen is the inability to format the data. Java 5 introduces the Formatter object which can be used to format String data for numbers and dates. The Formatter classes formatting procedure draws heavily from the C languages printf statement. While Java embraces basic C formatting it expands it to take advantage of various Java data types. The basic usage of the Formatter class is shown below. String output = String.format(String string, args...) System.out.format(String string, args...) The string value in the format statement is any String object with special formatting identiers. The args are a series of values that replace the identiers with the formatted representation of the argument. The format for a formatting identier is %[argument_index$][flags][width][.precision]conversion Each of these items will be broken down in order. It is best to begin with the base %conversion implementation and add on other peices. The rst thing to understand is the conversion characters. Table 8.5 provides the common characters and their meaning. Value s d f t % Description Displays the String value. Will call the toString() method for an object. Displays an integer value Displays a oating point number Date and time formatting (see Table ??) Prints a literal % Table 8.5: Conversion Characters

Page 157

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES Below is a basic example of using the format identiers. System.out.format("The string value is %s\n", "my string"); System.out.format("The integer value is %d\n", 5); System.out.format("The floating point value is %f\n", 5.23); Provides an output of The string value is my string The integer value is 5 The floating point value is 5.230000 The optional width is the minimum number of characters that are to be written to the output stream. System.out.format("The string value is (%10s)\n", "my string"); System.out.format("The integer value is (%5d)\n", 5); System.out.format("The floating point value is (%15f)\n", 5.23); Creates an output of The string value is ( my string) The integer value is ( 5) The floating point value is ( 5.230000) Notice that the minimum number of characters for each entry is lled with spaces if the value does not ll up the space. It is also worth noting that each entry is right justied. The optional precision is the maximum number of characters to be written to the output in the case of String data. And for oating point conversions the precision refers to the number of digits to the right of the decimal to print. Floating point numbers will round appropriately. The precision option doesnt work with whole number values. System.out.format("The System.out.format("The System.out.format("The System.out.format("The Generates an output of The The The The Page 158 string value is (my st) string value is ( my string) floating point value is (5.2300) floating point value is (3.88) c 2008 n + 1, Inc All Rights Reserved string value is (%3.5s)\n", "my string"); string value is (%10.20s)\n", "my string"); floating point value is (%2.4f)\n", 5.23); floating point value is (%.2f)\n", 3.876);

INTRODUCTION TO JAVA To determine which argument is used in the output, the indexing method is used to determine which argument to use for formatting. The number is a one based index mechanism. The rst argument is referenced by 1$ and the second by 2$. Consider the following output statements. System.out.format("values %2$s, %1$s\n", "test", "magic"); System.out.format("values %1$.2f %2$2.1f, %1$.1f\n", 3.2212, 4.232); System.out.format("values %3$d, %1$.3f, %2$10s\n", 3.2212, "Testing", 4); The results would show the following. values magic, test values 3.22, 4.2, 3.2 values 4, 3.221, Testing The formatting method oers a number of ag options that eect the formatting of the output. Table 8.6 shows the ags available and how they eect the output. Flag 0 , ( Type All Numbers Numbers Numbers Description Left justies the output Zero pads the output to the left of the number for entire width Places commas in the numbers (Locale Specic) Encloses negative numbers in parenthesis Table 8.6: Formatting Flags The ags are used to perform justication and to help provide a particular look to numbers on output. Below is a series of examples using each of the ags shown in the table. System.out.format("%10s%10s%3d\n", "test1", "magic1", 5); System.out.format("%-10s%-10s%-3d\n", "test2", "magic2", 5); System.out.format("%6d\n", 4235); System.out.format("%06d\n", 4235); System.out.format("%,6d\n", -4235); System.out.format("%(6d\n", -4235); Which lead the following output. test1 magic1 5 test2 magic2 5 4235 004235 -4,235 (4235) Page 159 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES Date Formatting Date formatting uses the conversion character t. The letter t is only part of the battle. A second conversion character is necessary to determine which eld in a date is desired to be displayed. Table 8.7 provides a list of the eld specic conversion characters along with what they output. Character k l M S p Z B b A a Y y m d e Description Hour of the day in 24 hour time (0 - 23) Hour of the day in 12 hour time (1 - 12) Minute formatted as two digits (00-59) Seconds formatted as two digits (00-59) am or pm String representation of time zone Full month name Abbreviated month name Full day of week name Abbreviated day of week name Four digit year Two digit year Month formatted as two digits (01-12) Day of month as two digits (01-31) Day of month (1-31) Table 8.7: Date Format Characters This makes it easy to format a date for output. Below provides a couple of examples of formatting with dates. Date date = new Date(); System.out.format("%1$tB %1$te, %1$tY\n", date); System.out.format("%1$tl:%1$tM:%1$tS %1$tp\n", date); Given that the Date object is set for 10/18/07 at 11:14:41 AM then the following output would occur. October 18, 2007 11:14:41 am

Page 160

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

8.3 Lab Activity


Part 1. Write a simple calculator program that calculates the sine, cosine, and tangent of an angle to three decimal places. The program should prompt the user for the angle and the type of calculation to perform. Below is an example of output. What angle for the operation? 33 What operation to perform (cos, sin, tan)? cos The cosine of 33 degrees is 0.839 Part 2. Write a program that will display a calendar of the current month. It should have the following format November 2007 Su Mo Tu We Th 1 4 5 6 7 8 11 12 13 14 15 18 19 20 21 22 25 26 27 28 29

Fr 2 9 16 23 30

Sa 3 10 17 24

Part 3. Write a program to print the current years calendar. Using the format shown in part 2. Part 4. (Optional) Write a program that asks the user for the month and year. Display the month entered by the user along with the previous and next months using the format from part 2.

Page 161

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 8. UTILITY CLASSES

Page 162

c 2008 n + 1, Inc All Rights Reserved

Chapter 9

Collections
Objectives
Understand how generics work Learn the basic collection types Learn how to store and retrieve entities from collections Learn how generics are used with collections

163

CHAPTER 9. COLLECTIONS

9.1 Generics
Generics provide a means of abstracting the data types for a class. It allows the data types for a class to be determined at object creation. To better understand this concept a good example is needed. Take for instance a class whose role is to store an object. Since all objects share the base class Object a simple program can be constructed to store an Object. Program Listing 49 Generic Object Storage public class Storage{ private Object data; public void storeObject(Object data) { this.data = data; } public Object retrieveObject() { return data; } }

Program 49 provides an implementation of this simple object. In this example any object can be stored within the Storage object because any object would be converted to the base type when storeObject is called. Since the object is stored as its generic type, the only way to retrieve the object is to cast it back to its original type when calling retrieveObject. String data = "This is a test"; Storage storage = new Storage(); storage.storeObject(data); String output = (String)storage.retrieveObject(); By using the generic Object type, the developer loses type cast safety. What if the object being stored isnt the type of object one is attempting to retrieve. String data = "This is a test"; Storage storage = new Storage(); storage.storeObject(data); Integer number = (Integer)storage.retrieveObject(); In this case the program will fail at runtime because it cant cast the String to an Integer data type. Generics are a means of determining type compatibility at compile time. To use generics, the <[holder]> operator is used to provide a place holder for the data type. The holder value is then used in place of the data type within the object. When the generic object is created the same Page 164 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA operator is used to dene what type to replace the holder with at compile time, ensuring that the types match at compile time. Program 50 reworks the last example to utilize the Generics framework. Program Listing 50 Generics Storage public class Storage<XXX>{ private XXX data; public void storeObject(XXX data) { this.data = data; } public XXX retrieveObject() { return data; } } In this case the holder XXX is used for the generic type. Instead of using private Object data; it is replaced with the generic type private XXX data;. Same holds true for the method to store and retrieve the object. To use the Storage object, the type is dened at creation. Storage<String> store = new Storage<String>(); In this case the XXX in the Storage class is replaced with the object String data type. Only objects and not primitives can be used with generics. Of course with autoboxing the use of the wrapper classes can give the illusion of using primitives. String data = "This is a test"; Storage<String> store = new Storage<String>(); store.storeObject(data); String output = store.retriveObject(); Notice that when retrieving the object, their is no longer any need to cast. Because the type was dened for the retrieveObject to return a String, the need to cast is no longer necessary. It also means that type incompatibility will be caught at compile time rather than run time. String data = "This is a test"; Storage<String> store = new Storage<String>(); store.storeObject(data); Integer output = store.retriveObject(); In this example the code wont compile because output is an Integer type, but retrieveObject is returning a String value. Therefore an attempt to compile this code will fail. The incompatibility is caught at compile time. Page 165 c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS When creating classes with generics it is possible to use multiple place holders to represent data types. Each additional type is added using a comma inside of the < > command. Program listing 51 provides an example. Program Listing 51 Multiple Generic Types public class RectangleInfo<W,L>{ private W width; private L length; public void setWidth(W width) { this.width = width; } public W getWidth() { return width; } public void setLength(L length) { this.length = length; } public L getLength() { return length; } }

Below is an example of using the RectangleInfo class. RectangleInfo<Integer, Float> rect = new RectangleInfo<Integer, Float>(); int width = 10; float length = 24.32f; rect.setWidth(width); rect.setLength(length); System.out.println("Area = " + rect.getWidth() * rect.getLength());

Page 166

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

9.2 Collections
The Collections APIs in Java provide various containers for storing objects. All of the them fall into one of four categories: collections, lists, sets or maps. Each category has its own unique properties. The collection is the simplest storage type. It is a grouping of objects that have no special order. In addition the collection allows an object to be found in the grouping multiple times. Collections are dened by the Collection interface. The interface is the root interface for all collections. There are no concrete implementations of the Collection interface. The concept of the set comes from discrete mathematics. It is a compilation of objects that have no special order. The nature of a set forbids objects from appearing in the set multiple times. Each entry in the set is guaranteed to be unique. The list is the most commonly used collection object. It is a data store where objects are stored in a dened order. The ordering of the list allows for indexed access into the grouping. Like the collection, lists allow for duplicate entries. The map is a dierent type of collecting container from the other three types. The storage provides a dictionary like mechanism for storing and retrieving data. Data stored in the map is associated with a unique key value. The data is stored and retrieved based upon the key value.

Page 167

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS

9.2.1 Collections and Data Types


All of the collection types are build to store and retrieve Object data. Since every system and user dened object derives from the Object class all of them can be converted to the Object type for storage. When retrieving the object back from the collection, the developer must cast the object back to its original type in order to make the conversion back. The lack of primitive support in the collection objects means that primitives must be converted to objects before they can be stored within a collection. The task can be accomplished by using the primitives wrapper class. The example below shows how a collection traditionally has been used. Vector collection = new Vector(); collection.add("This is the first object"); collection.add(new Integer(269)); String first = (String)collection.get(0); Integer second = (Integer)collection.get(1); int third = second.intValue(); In this example, the Vector class is a simple indexed list. A String and an Integer are appended to the end of the list with the add(Object data) method. Then each object is retrieved by index and casted back to their original type. This can become a tedious process, especially when working with primitive data types. In addition there is no type checking at compile time. Because all objects in the collection are treated the same, problems can occur when casting to a incorrect derived type. To avoid the problem most developers use a single data type while working with collections. In which case, the cast is tedious and the lack of type checking problematic. Java 1.5 introduced the concept of generics. Its application to the collection classes is ideal. It removes the need to cast and provides compile time type checking for the objects. Vector<String> stringData = new Vector<String>(); Vector<Integer> intData = new Vector<Integer>(); stringData.add("This is string data"); intData.add(269); String data1 = stringData.get(0); int data2 = intData.get(0); In this case the stringData object is a collection that only can accept String data types and the intData object can only hold Integer data types. The latter can use autoboxing to convert the primitive into the wrapper data class and then provide the conversion back. Allowing the Vector<Integer> data type to work directly with primitives. Page 168 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

9.2.2 Lists
The List interface extends the Collection interface and denes the generic methods that apply to all concrete implementations of the List. Table 9.1 shows the most commonly used methods in the interface. The X in the methods represents the generic value that is associated with the list. Method boolean add(X obj) boolean add(int index, X obj) X get(int index) boolean remove(int index) X set(int index, X obj) int size() Description Appends the element to the end of list Inserts the element at the specied position in the list Returns the element at the specied position Removes the element at the specied position Replaces the element at the specied position and returns the object being replaced Returns the number of elements in the list Table 9.1: List Methods The Vector shown in previous examples is a concrete implementation of the List interface and was part of the original Java API. Later versions of Java introduced better list implementations. Currently, the ArrayList and LinkedList are the most commonly used list formats. The array list uses an underlying array for storing data. It is very fast for retrieving indexed elements from the list. Since it is based on an array, a performance penalty occurs for expanding the list past a predetermined size1 . The linked list is based on the common data structure of the same name. Each element has a link to the previous and next element in the list. The linked list is perfect if the number of elements to add is unknown and data is being retrieved by stepping through the data in order.

initial size is determined at construction. A developer can pass in the size of the initial array. If no value is passed, the implementation defaults to 10

1 The

Page 169

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS When using any of the concrete list classes it is important to remember that all of them implement the List interface. It allows the developer to abstract out the direct implementation from how it is used. This way the concrete implementation can be changed without eecting how the object is passed or used. Program listing 52 provides and example of using lists and the List interface. Program Listing 52 List Example import java.util.ArrayList; import java.util.LinkedList; public class CollectionTest { public static void main(String[] args) { LinkedList<Integer> list1 = new LinkedList<Integer>( ); ArrayList<Integer> list2 = new ArrayList<Integer>( ); list1.add(13); list1.add(25); list2.add(10); list2.add(22); printTotals(list1); printTotals(list2); } public static void printTotals(List<Integer> myList) { int total = 0; for ( int index = 0; index < myList.size(); index++ ) { total += myList.get(index); } System.out.println("Total is " + total); } }

Page 170

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

9.2.3 Looping through Lists


There are two means for looping through the elements in a list. Before Java 1.5, the developer would use an Iterator to move through the list. An Iterator is an interface that provides a simple mechanism for looping over the elements in a collection. It is simple in that it only had three methods shown in table 9.2. Method boolean hasNext( ) Object next( ) Description Determines if the list has any more items Returns the next item in the list. The iterator starts with the initial next() call returning the rst item in the list. void remove( ) Removes the current item from the list Table 9.2: Iterator Methods In the example below the iterator is used to loop over a list of Account objects and print out the balance for each entity. Iterator iterator = list.iterator(); while ( iterator.hasNext() ) { Account account = (Account)iterator.next(); System.out.println("Balance is " + account.getBalance() ); }

Page 171

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS The Iterator can also be used with generics. Program listing 52 has been modied in program listing 53 to take advantage of the iterator. Program Listing 53 Iterator Example import java.util.ArrayList; import java.util.LinkedList; public class CollectionTest { public static void main(String[] args) { LinkedList<Integer> list1 = new LinkedList<Integer>( ); ArrayList<Integer> list2 = new ArrayList<Integer>( ); list1.add(13); list1.add(25); list2.add(10); list2.add(22); printTotals(list1); printTotals(list2); } public static void printTotals(List<Integer> myList) { Iterator<Integer> iterator = myList.iterator(); while ( iterator.hasNext() ) { total += iterator.next(); } System.out.println("Total is " + total); } }

Page 172

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA New for Loop Java 1.5 also introduced a new for loop mechanism for traversing all of the elements in a data collection. This new construct can be used with arrays as well as any of the collection classes. It has the following format for ( <type> <var> : <list> ) { // do stuff with the variable <var> } Each element from the list is placed in the supplied variable one at a time until all of the elements have been consumed. Below is an example of using the for loop to iterate over a simple array. The data type of the variable must match the data type used in the collection. Also the variable name used can not conict with other variable names dened within the same scope as the for statement. The scope of the variable dened in the for statement is only available within the for loop. int total = 0; int [] data = {5, 7, 3, 2, 6}; for (int entry : data) { System.out.println("entry = " + entry); total += entry; } double average = total / 5.0; System.out.println("avg entry = " + average); Running the code would lead to the following output. entry = 5 entry = 7 entry = 3 entry = 2 entry = 6 avg entry = 4.6

Page 173

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS The same for loop can be applied to collections as well. Program listing 54 provides an example of using it with a ArrayList and LinkedList structure. Program Listing 54 For List Example import java.util.ArrayList; import java.util.LinkedList; public class CollectionTest { public static void main(String[] args) { LinkedList<String> list1 = new LinkedList<String>( ); ArrayList<String> list2 = new ArrayList<String>( ); list1.add("linked-list"); list1.add("testing"); list2.add("array-list"); list2.add("more testing"); for ( String output : list1 ) { System.out.println("list1: " + output); } for ( String output : list2 ) { System.out.println("list2: " + output); } } }

Running program listing 54 would generate the following output. list1: list1: list2: list2: linked-list testing array-list more testing

Page 174

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

9.2.4 Sets
The Set interface extends the Collection interface and denes the functionality of a set. Since ordering of elements is not important, the number of methods to deal with a set are considerably less than a list. Table 9.3 shows the most commonly used methods for a Set. Method boolean add(X obj) void clear() Iterator<X> iterator() boolean remove(X obj) int size() Description Adds the element to the set if it is not already there Removes all elements from the set. Returns an Iterator for the set. Removes an element from the set if present. Returns the size of the set. Table 9.3: Set Methods There are two major implementations of the Set interface, HashSet and the TreeSet. The HashSet uses a hashtable to store items. Any duplicate objects would have the same hash value and not be allowed. The TreeSet uses a tree to create the set. The tree orders the elements by using the natural order of the data. Duplicates are not permitted in the tree structure. Therefore the elements in the tree set are ordered by the nature of the tree. The HashSet is the most commonly used of the two implementations because it is considerably faster. And like lists it is always important to cast the object as the Set interface to be able to change the concrete implementation later without eecting existing code.

Page 175

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS Program listing 55 provides and example of using a Set. Program Listing 55 Set Example import java.util.HashSet; public class CollectionTest { public static void main(String[] args) { HashSet<String> set = new HashSet<String>( ); set.add("one"); set.add("two"); set.add("three"); set.add("four"); set.add("four"); set.add("three"); set.add("two"); set.add("one"); printSet(set); } public static void printSet(Set<String> mySet) { for ( String data : mySet ) { System.out.println("Data = " + data); } } } The output from program listing 55 using the HashSet would be something similar to the following. Data Data Data Data = = = = one two four three

The order could be dierent depending on how a particular machine handles the hash of each String. Notice that even though I tried to add duplicate entries, the system wouldnt allow it. What happens if the HashSet is replaced with the TreeSet? The results are shown below; Data Data Data Data = = = = four one three two

Notice how the data is printed out this time in alphabetical order. One of the by products of storing data based upon their natural order is it provides a means of ordering set data. Page 176 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

9.2.5 Maps
While the map is grouped with the collection classes, it is a considerably dierent data structure from the lists and sets mentioned previously. The map provides a dictionary like functionality. A piece of data is stored using a key value. The data can later be retrieved by using the same key. What makes the map interesting is that it can provide three dierent views of the data. The most common use is the key/value pair mappings to store and retrieve data. In this case the map works similarly to a data record. Where the name value pairs make up the attributes of the record. The map can also be used to return the set of keys and a collection of values. Since the key must be unique, it makes sense that the developer should be able to retrieve all of the keys as a set. The developer can also obtain a collection of values stored in the map. The Map interface denes the functionality of the map. Table 9.4 provides a list of the interfaces commonly used methods. Method void clear() boolean containsKey(X key) Y get(X key) Set<X> keySet() Y put(X key, Y value) Y remove(X key) int size() Collection<Y> values() Description Removes all of the key/value pairs from the map. Returns true if map contains key. Returns the object from the specied key If the key doesnt exist then returns null. Returns a set of keys from the map. Associates the value with the key in the map. Removes the value associated with the key from the map and returns the value. The number of key/value mappings. Returns the collection of values held in the map. Table 9.4: Map Methods

Page 177

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS The two concrete implementations of the Map interface are the HashMap and the TreeMap. The HashMap uses a hash to store the key values while the TreeMap stores the keys in natural order. The HashMap is generally faster, but the TreeMap is useful if the order of keys is important. Program 56 shows how the map can be used to store information. Program Listing 56 Map Example import java.util.HashMap; public class HashTest { public static void main(String[] args) { Account beth = new Account("ACME-1234", 502.2); Account brian = new Account("ACME-3241", 1598.25); Account jenny = new Account("ACME-4321", 321.21); HashMap<String,Account> map = new HashMap<String,Account>(); map.put("Brian", brian); map.put("Beth", beth); map.put("Jenny", jenny); Account account = map.get("Beth"); System.out.println("Beths account balance is " + account.getBalance()); } }

Page 178

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The hash map example utilizes the Account class from program listing ?? as the stored entity. 3 accounts are created and stored in the map and Beth is retrieved to print her balance.

Page 179

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 9. COLLECTIONS

9.3 Lab Activity


Overview. The goal of this lab is to create a phone book application by capturing the rst name, last name, and phone number of people. Each entry in the phone book should be stored as a Map data type. All of the entries should be stored in a List. Part 1. Create a menu program that prompts the user for the following menu: 1) 2) 3) 4) List phone book Add new phone book entry Delete phone book entry Exit

Select: When the user selects exit the program should end. Part 2. When the user selects add a phone number the program should ask for the rst name, last name, and phone number for the person. The data should be stored in a Map and added to the List. First Name? Joanne Last Name? Smith Phone #? 555-4444 Joanne Smith has been added Part 3. If the user selects the option to list the phone book then the program should print out each entry in the phone book and another menu. The output should look like the following: 1) Doe John 555-2342 2) Smith Anne 555-1233 3) Doe Jane 555-2344 Part 4. When the user selects delete phone number the program should ask which entry to delete. The user entry should match the numbers displayed on the phone book list. The entry should be removed from the List. Which phone entry to delete? 2 Deleting Anne Smith Part 5. (Optional) Arrange the names in the listing in alphabetical order. Page 180 c 2008 n + 1, Inc All Rights Reserved

Chapter 10

Java I/O
Objectives
Understand what an exception is Learn how to use exceptions Learn how to create custom exceptions Learn how to use streams Learn how to use readers and writers Understand how Serialization works

181

CHAPTER 10. JAVA I/O

10.1 Exceptions
When developing software things can go wrong. It doesnt necessarily have to be a logic error. A le doesnt exist on the le system. The end user inputs bad data. John Doe with his back hoe snaps your ber network connection. These things happen every day and the developer needs to be able to handle these situations. In Java whenever an error occurs that the virtual machine cant handle it generates an exception and allows the developer a chance to resolve the problem. If the problem isnt handled the virtual machine will exit the application. Java supports three types of exceptions. The rst exception type is the checked exception. They are caused by problems in the environment such as a socket failure, input / output problems, invalid data conversions, etc. Since checked exceptions are known possibilities, they must be accounted for when using an operation that could raise the exception. The second exception type is the runtime exception. These are exceptions that are caused by bad programming. They are logic errors that can not be foreseen. Errors such as divide by zero, array boundary problems, trying to access uninitialized objects1 . Runtime exceptions can happen at any time and are not required to be checked for while developing. Otherwise they behave in the same manner as checked exceptions. The nal type is errors. Errors are beyond the control of the developer. They relate to problems with the virtual machine. A common error is running out of memory. When these errors occur the virtual machine can no longer operate and shuts down. This chapter will explore the rst two types of exceptions.

1 Accessing

uninitialized objects creates the dreaded NullPointerException

Page 182

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.1.1 Exception Basics


When an error occurs that warrants an exception, the Java virtual machine will stop execution and throw the exception. The developer must take steps to catch the exception and handle it gracefully. Managing exceptions is a simple process. Start by placing code that might generate an exception inside of a try block of code. The next step is to create a catch block to handle the potential error. try { // some code that can throw an error } catch (Execption e) { // handle some other error } A try block can potentially throw multiple types of exceptions. In the case where multiple exceptions can occur, a catch block is needed for each error. try { // open a file // some code that can throw an error // close a file } catch (IOExecption e) { // handle file I/O problem } catch (Execption e) { // handle some other error } When an error occurs within the try block, execution of the code terminates and control jumps to the appropriate catch block. If no error materializes, the try block is completed and control jumps past all of the catch blocks. In addition to the try / catch mechanism, Java provides Java provides a finally statement. The finally block is always executed regardless if an exception surfaces or not. It is an ideal place for closing opened devices such as les and database connections.

Page 183

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O try { // open a file // some code that can throw an error } catch (IOExecption e) { // handle I/O problem } catch (Execption e) { // handle some other error } finally { // close file } Program listing 57 provides an example of a program that will generate a runtime exception. Why does this program fail? Because the array attempts to access an element that does not exist. Arrays have a zero based index. Thus when the code attempts to access the fourth element in the array it wont be able to because it doesnt exist. Program Listing 57 Program Causes Exception public class CreateException { public static void main(String [] args) { System.out.println("Starting Program..."); int [] data = { 45, 22, 53 }; printData(data, 3); System.out.println("...Program Complete"); } public static void printData(int [] data, int size) { for ( int x = 1; x <= size; x++ ) { System.out.println("data[" + x + "] = " + data[x]); } } }

When program listing 57 is executed the program will execute until it tries to exceed the size of the array. At which point it will fail and provide the following error message. $> java CreateException Starting Program... data[1] = 22 data[2] = 53 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at courseware.chp10.CreateException.printData(Unknown Source) at courseware.chp10.CreateException.main(Unknown Source)

Page 184

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The printed error message is known as the stack trace. The rst line tells what type of exception occurred along with a message describing the error. The second line provides the developer with the line number where the error occurred (if available). Each line after the second tells the developer the name of the calling method. The stack provides a trace through all methods back to the main method in the application. It provides some clue as to what was happening at the time of failure and allow the developer to track down what caused the error. Having a program print a stack trace and exit is a not what good developers allow to happen. It is preferred to supply a try / catch block to handle the error and continue executing the program. Program listing 58 is a rewrite of program listing 57. It utilizes Javas exception handling to gracefully handle the error and continue. Program Listing 58 Program Handles Exception public class CreateException { public static void main(String [] args) { System.out.println("Starting Program..."); int [] data = { 45, 22, 53 }; printData(data, 3); System.out.println("...Program Complete"); } public static void printData(int [] data, int size) { try { for ( int x = 1; x <= size; x++ ) { System.out.println("data[" + x + "] = " + data[x]); } } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Bad Data (Can not continue printing)"); } } }

When the program is executed the exception is handled by printing to the console an error message and continuing execution. Starting Program... data[1] = 22 data[2] = 53 Bad Data (Can not continue printing) ...Program Complete

Page 185

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O

10.1.2 The Throwable Class


The Throwable class is the base class for all errors and exceptions. Only objects which inherit from the Throwable class can be used in a catch expression. The Throwable class has three attributes. An execution stack representing the stack trace. An error message providing brief information about the error which occurred. It also may contain a cause exception which will be explained later. Table 10.1 shows a list of useful methods from the Throwable class. Method String getMessage() StackTraceElement [] getStackTrace() void printStackTrace() Throwable getCause() Throwable initCause Description Returns an error message Returns an array of StackTraceElement objects that can be manipulated programatically Prints stack trace information to standard out. Returns the exception that triggered this exception. Sets the exception that triggered this exception. Table 10.1: Throwable Methods

Page 186

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program listing 59 provides an example of using these methods. Program Listing 59 Exception Methods public class ExceptionMethods { public static void main(String [] args) { System.out.println("Starting Program..."); int [] data = { 45, 22, 53 }; printData(data, 3); System.out.println("...Program Complete"); } public static void printData(int [] data, int size) { try { for ( int x = 1; x <= size; x++ ) { System.out.println("data[" + x + "] = " + data[x]); } } catch (ArrayIndexOutOfBoundsException e) { String index = e.getMessage(); System.out.println("No data at index " + index ); System.out.println("--- Stack Trace ---"); e.printStackTrace(); System.out.println("-------------------"); } } }

Page 187

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O

10.1.3 Creating a New Exception Type


The Exception class is derived from the Throwable class and is the base class for all runtime and checked exceptions. While it adds no new methods from its parents class, it does introduce three constructors which are useful when dealing with exceptions. Table 10.2 provides a list of them. Method Exception() Exception(String message) Exception(String message, Throwable cause) Description Creates exception with null message value. Creates exception with specied message. Creates exception with specied message and the exception which triggered the creation of this exception. Table 10.2: Exception Constructors It is possible to create a custom exception type by extending the Exception class and overriding the Exception classes constructors. Program listing 60 provides an example of a custom exception. Program Listing 60 Custom Exception public class MyException extends Exception { public MyException() { super("This is MY exception"); } public MyException(String message) { super(message); } public MyException(String message, Exception cause) { super(message, cause); } }

Page 188

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.1.4 Exception Order in Catch Blocks


As stated previously, it is possible to have multiple catch blocks. They are traversed in order and the rst exception to match the error is the one executed. This seems simple until one takes into eect inheritance and polymorphic behavior. For instance, the IOException class extends Exception and is used to identify problems with I/O. The FileNotFoundException class extends the IOException class and is thrown when a le is not found on the le system. Which catch block would be executed in the following example? try { // loading file, but file was not there so raise a FileNotFoundException } catch (IOException e) { // print error message } catch (FileNotFoundException e) { // print error message } The obvious answer is the FileNotFoundException. But wait a second, think about the problem polymorphically. Isnt the FileNotFoundException also an IOException? Yes. Therefore the block that would execute is the IOException catch block. In fact, the FileNotFoundException block could never be reached and thus would not compile. More specic exceptions must precede more generic exceptions. The above example should be re-written to put the FileNotFoundException before the IOException. try { // loading file, but file was not so a FileNotFoundException is raised } catch (FileNotFoundException e) { // print error message } catch (IOException e) { // print error message }

Page 189

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O What if a developer wanted to have a catch all exception instead of enumerating each exception specically? Generally, it is good practice to list each possible checked exception when error handling. It makes it easier to track down problems. But if a general error handler is needed the Exception class can be used. Why? Because all exceptions derive from the Exception class. The previous example can be rewritten to use the default catch all. try { // loading file, but file was not so a FileNotFoundException is raised } catch (Exception e) { // print error message }

Page 190

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.1.5 Raising an Exception


The virtual machine will raise an exception whenever it tries to process something that it can not perform. What if the developer wants to raise a custom exception when a logic error occurs? Java provides a throw mechanism for raising an exception. The developer uses the keyword throw followed by the instance of the exception to be raised. MyException myEx = new MyException("Something Bad Happened"); throw myEx; It can be shortened to one line. throw new MyException("Something Bad Happened"); If a custom or checked exception is raised it must be caught somewhere in the code or it will fail to compile. It is also possible to throw any of the exceptions dened in the API. throw new IOException("Invalid File Format");

Page 191

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O

10.1.6 Returning Exceptions from Methods


Another problem with procedural programming is the use of return codes to determine if a function call worked or failed. In a typical application a segment of code may make a number of calls to other methods to get something done. If each call has a return code, then there must be an if/else if/else block to handle the code. If this is done for each instance the business logic can quickly become muddled. int rc = doFirst(); if ( rc == 1 ) { // error 1 } else if ( rc == 2 ) { // error 2 } rc = doSecond(); if ( rc == 1 ) { // error 1 } else if ( rc == 2 ) { // error 2 } rc = doThird(); if ( rc == 1 ) { // error 1 } else if ( rc == 2 ) { // error 2 } Instead of a method returning a return code, it would be better if the method could raise an exception when errors arise. This would allow the developer to group all of the business logic into one unit and the error handling in a separate unit of code. Java allows methods to throw exceptions using the keyword throws. Now the methods called in the example above can be modied to throw exceptions if a problem occurs instead of a return code. void doFirst() throws MyException, IOException { // do something }

Page 192

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Now the previous example can be rewritten. try { doFirst(); doSecond(); doThird(); } catch (MyException e) { // error 1 } catch (IOException e) { // error 2 } Notice that the business logic is all grouped inside the try block and all of the error handling is done after the main logic. A much cleaner method for handling errors.

Page 193

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O Program listing 61 provides a concrete example of throwing custom exceptions. Program Listing 61 Throwing Exceptions public class ExceptionThrowing { public static void main(String [] args) { System.out.println("Starting Program..."); try { int [] data = { 45, 22, 53 }; printData(data, 3); } catch (MyException e) { System.out.println(e.getMessage()); Exception cause = e.getCause(); if ( cause != null && cause instanceof ArrayIndexOutOfBoundsException) { System.out.println("No data at index " + cause.getMessage() ); System.out.println("--- Stack Trace ---"); e.printStackTrace(); System.out.println("-------------------"); } } System.out.println("...Program Complete"); } public static void printData(int [] data, int size) throws MyException { try { for ( int x = 1; x <= size; x++ ) { System.out.println("data[" + x + "] = " + data[x]); if ( data[x] < 0 ) { throw new MyException("Invalid Negative Data"); } } } catch (ArrayIndexOutOfBoundsException e) { throw new MyException("Index out of Bounds", e); } } }

The previous example introduces the concept of chaining exceptions. The method printData(...) can throw a MyException. This occurs when the data contains a negative number. What happens if an ArrayIndexOutOfBoundsException occurs? In this instance, the ArrayIndexOutOfBoundsException becomes an argument for the MyException constructor. Chaining the two exceptions. The ArrayIndexOutOfBoundsException is the cause of the MyException. Now when the MyException Page 194 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA is raised, it prints out the message and looks to see if a exception has a cause. If so the program displays the cause of the MyException.

Page 195

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O

10.2 Java I/O


Java provides two mechanisms for processing input / output manipulations. The rst is streams. Streams view I/O as a sequence of bytes to be moved. There are two types of Java streams, low level and high level. The low level streams are used to send and receive raw bytes of data. On the other end, higher level streams are used to send and receive primitives and object data types. The other major type of I/O available to Java are the readers and writers. They are used for reading and writing string data. The readers and writers also fall into two categories. Low level readers and writers are used to process character data. The higher level readers and writers allow for String processing, data buering, and conversion to streams. All of these I/O classes can be found in the java.io package of the API.

Page 196

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.2.1 Streams
In Java, streams generally come in pairs. One stream is for input and the other for output. The base classes from which all streams are derived are the InputStream and the OutputStream. The low level streams which extend the base class are used for handling binary data. The FileInputStream and FileOutputStream are used for reading and writing data to a le. The ByteArrayIntputStream and ByteArrayOutputStream are used to read and write data to and from a byte array. The PipedInputStream and PipedOutputStream are used to send binary data between threads. Examining the methods of the low level streams, it becomes apparent that these streams are used for byte level manipulations. Table 10.3 provides a list of some stream methods. Input Streams int read() int read(byte [] dest) Returns a single byte of data from the input stream Reads a series of bytes and stores them in the dest array. The value returned is the number of bytes read int available() void skip(long bytes) void close() Output Streams void write(int b) void write(byte[] out) void ush() void close() Writes a single byte to the output stream. Writes out.length bytes to the stream. Flushes the stream an forces any buered data to be written to the stream. Closes the stream Table 10.3: Low Level Stream Methods Since these methods can be working with resources that are outside of the virtual machine, all of them can potentially raise or throw an IOException. Therefore whenever a developer wants to use a stream it must be inside of a try / catch block of code. The higher level streams are used to handle primitive and object data types. DataInputStream and DataOutputStream are used to handle primitive data. BueredInputStream and BueredOutputStream provide buered streams to maximize eciency. ObjectInputStream and ObjectOutputStream supply the developer with a mechanism for streaming objects. Table 10.4 show some of the methods available from the DataInputStream and DataOutputStream. How do the streams work together? The high level streams are used in conjunction with the low level streams to either read or write data. They are connected together like pipes. For example, if a developer wants to write data to the le foobie.txt, the programmer would rst create a Page 197 c 2008 n + 1, Inc All Rights Reserved Returns the number of bytes the next read can make without blocking Skips the number of bytes from input Closes the stream

CHAPTER 10. JAVA I/O DataInputStream int readInt() double readDouble() String readUTF() void close() DataOutputStream void writeInt(int data) double readDouble(double data) void writeUTF(String data) void close() Writes the four bytes of the int to the stream Writes the eight bytes of the double to the stream Writes the String to an UTF-8 encoded string Closes the data stream Table 10.4: Data Steam Methods FileOutputStream that points to foobie.txt. The FileOutputStream is connected to the BueredOutputStream to more eciently write to the le. And nally, the BueredOutputStream is connected to the DataOutputStream to write primitive binary data to the le. Program listing 62 provides an example of connecting these pipes together. Reads four bytes and returns an int Reads eight bytes and returns a double Reads in a UTF-8 encoded string Closes the data stream

Page 198

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program Listing 62 Streaming Out Binary Data import java.io.FileOutputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; public class WriteBinaryData { public static void main(String [] args) { try { FileOutputStream fos = new FileOutputStream("foobie.dat"); BufferedOutputStream bos = new BufferedOutputStream(fos); DataOutputStream dos = new DataOutputStream(bos); dos.writeInt(269); dos.writeDouble(2.53); dos.writeUTF("This is a test"); dos.close(); bos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }

The streams in this example are connected using constructor arguments. The FileOutputStream is connected to the le foobie.dat. The BueredOutputStream is initialized with the fos stream. The bos stream is used to initialize the DataOutputStream. Once the streams are connected all that is left is to write data. When nished with the streams make sure the streams are closed. This ensures that everything is written to the le properly. The streams should be closed in the opposite order in which they were created. Notice that work with these output streams was contained inside of a try/catch block where an IOException was caught. This is because calls to streams can throw an IOException. Therefore they need to be caught.

Page 199

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O Since the le is written using binary it is not in a human readable form. The only way to retreive the data is to read it back. Reading back in the data is the same process using input streams rather than output streams. Program listing 63 provides an example of reading the data in from foobie.txt. Program Listing 63 Streaming In Binary Data import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.DataInputStream; public class ReadBinaryData { public static void main(String [] try { FileInputStream fis = new BufferedInputStream bis = DataInputStream dis = new

args) { FileInputStream("foobie.dat"); new BufferedInputStream(fos); DataInputStream(bos);

int first = dis.readInt(); double second = dis.readDouble(); String third = dis.readUTF(); System.out.println("1 = " + first); System.out.println("2 = " + second); System.out.println("3 = " + third); dis.close(); bis.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } }

Running the output and then input program will generate the following output. 1 = 269 2 = 2.53 3 = This is a test

Page 200

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.2.2 Readers and Writers


The Readers and Writers are for reading and writing character based data. The low level readers provide methods for reading and writing the char data type. Like their brethren, streams, readers and writers are generally paired together. There are a number of low level readers and writers. The CharArrayReader and CharArrayWriter read and write to character arrays. The PipedReader and PipedWriter are used to communicate character data between threads. The StringReader and StringWriter are used to create String classes. Finally the FileReader and FileWriter are for reading and writing character data to a le. Common methods of these classes are shown in Table 10.5. Like streams, each of these methods throw an IOException. Reader int read() long skip(long num) int read(char [] buf) Reads two bytes from the stream and returns as an int. Skips num number of characters. It returns the number of chars skipped. Reads from the input buf.length bytes. The data is placed in the buf array. The number of bytes read is returned. void close() Writer void write(char[] buf) void write(String str) void write(int c) void ush() void close() Writes buf.length characters. Writes the string. Writes the lower two bytes of integer. Flushes the writer an forces any buered data to be written. Closes the writer Table 10.5: Low Level Reader/Writer Methods Just like their stream counterparts, higher level readers and writers hook to the lower level readers and writers to provide better String processing. Where the lower level readers and writers focus on characters, the higher level readers and writers focus on Strings. The BueredReader and BueredWriter are high level classes that provide buered input and output. The InputStreamReader and OutputStreamWriter hook to streams allowing developers to send String data through a stream. The nal high level object is the PrintWriter which allows for more String formatting output options. Table 10.6 provides a look at some of the methods from the BueredReader and PrintWriter. Program listing 64 provides an example of combining the low and high level writers to write textual data to the le foobie.txt. Page 201 c 2008 n + 1, Inc All Rights Reserved Closes the reader

CHAPTER 10. JAVA I/O BueredReader String readLine() Reads in a string to the newline character. It strips of the newline character when string is returned. The method will return null if end of le. void close() PrintWriter void print(int i) void print(double d) void print(String s) void println(String s) void ush() void close() Writes the integer as a string without a newline. Writes the double as a string without a newline. Writes the string without a newline. Writes the string with a newline. Flushes the writer an forces any buered data to be written. Closes the writer Table 10.6: High Level Reader/Writer Methods In this example, the FileWriter opens a connection to the le foobie.txt. The BueredWriter is hooked to the FileWriter to provide better I/O eciency. And nally the PrintWriter is connected to the BuerWriter to allow for easy String writing. After running this example a le called foobie.txt would be available on the le system that would resemble this: This is the first line of text 269 This is the third line Closes the reader

Page 202

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program Listing 64 Writing Text Data to a File import java.io.FileWriter; import java.io.BufferedWriter; import java.io.PrintWriter; public class WriteStringData { public static void main(String [] args) { try { FileWriter fw = new FileWriter("foobie.txt"); BufferedWriter bw = new BufferedWriter(fw); PrintWriter pw = new PrintWriter(bw); pw.println("This is the first line of text"); pw.print(269 + "\n"); pw.println("This is the third line"); pw.close(); bw.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } }

Reading the le back in is the same process as writing except with readers. Program listing 65 provides an example of reading the le foobie.txt.

Page 203

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O Program Listing 65 Reading Text Data from a File import java.io.FileReader; import java.io.BufferedReader; public class ReadStringData { public static void main(String [] args) { try { FileReader fr = new FileReader("foobie.txt"); BufferedReader br = new BufferedReader(fw); String one = br.readLine(); String two = br.readLine(); String three = br.readLine(); int data = Integer.parseInt(two); System.out.println("1 = " + one); System.out.println("2 = " + data + " is a number"); System.out.println("3 = " + three); br.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } } }

Running ReadStringData after WriteStringData should create the following output. 1 = This is the first line of text 2 = 269 is a number 3 = This is the third line

Page 204

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

10.2.3 Serialization
Until this point, the I/O has been centered around primitive data types and String data. In addition Java has the ability to write objects to streams. Why would anyone need to stream objects? The simplest answer is to transfer objects across the network. One of the capabilities of Java is RMI2 . RMI allows methods to be called outside of the virtual machine. For this to work the remote methods must be allowed to take objects as arguments. Thus the object must be able to stream across the network. Writing an object to a data stream in Java is known as serialization. Objects by default are not serializable. They must implement the java.io.Serializable interface to be a candidate for serialization. If they dont then an attempt to stream the object will raise a NotSerializableException. import java.io.Serializable public class MyClass implements Serializable { // class implementation } Since interfaces contain virtual methods, what methods need to be implemented for the Serializable interface? The answer is none. The Serializable interface looks like the following. public interface Serializable { } An empty interface is known as a tagging interface. It allows a developer to tag a class for a specic function. In this case, the class is tagged for object serialization.

2 Remote

Method Invocation

Page 205

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O Program listing 66 provides an object that implements the Serializable interface. Program Listing 66 Serializable Wine Object import java.io.Serializable; public class Wine implements Serializable { private String name; private String vineyard; private int age; public Wine(String name, String vineyard, int age) { this.name = name; this.vineyard = vineyard; this.age = age; } public int getAge() { return age; } public String getName() { return name; } public String getVineyard() { return vineyard; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public void setVineyard(String vineyard) { this.vineyard = vineyard; } public String toString() { return "Wine: " + name + "(" + age + ") from " + vineyard; } }

Page 206

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA Program listing 67 provides an example of using the ObjectOutputStream and the ObjectInputStream to read and write Wine objects to and from a local binary le3 . Program Listing 67 Serializing an Object to a File import java.io.*; public class WineCellar { public static void main(String [] args) { Wine red = new Wine("My Red", "France", 10); Wine white = new Wine("My White", "California", 13); try { FileOutputStream fos = new FileOutputStream("winelist.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(red); oos.writeObject(white); oos.close(); fos.close(); FileInputStream fis = new FileInputStream("winelist.obj"); ObjectInputStream ois = new ObjectInputStream(fis); Wine mywine = (Wine)ois.readObject(); System.out.println(mywine); mywine = (Wine)ois.readObject(); System.out.println(mywine); ois.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } }

One nal note about serialization. If attempting to serialize a Collection, then all of the contained classes must implement the Serializable interface otherwise the collection serialization will fail with a NotSerializableException exception.

3 When writing objects to a le it is important to understand that serialization will only work as long as the class of the object that is written to the le is not changed and recompiled. Any changes will make it impossible to read the object back in from the le

Page 207

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 10. JAVA I/O

10.3 Lab Activity


Part 1. The goal of this lab is to create a mechanism for storing phone numbers. To simplify, the phone entry will have an ID, a rst name, last name and a phone number. Create a program that will take the id, rst name, last name, and phone number from the command line and appended it to the phone.txt le. The data should be stored in a comma separated le. The le should look similar to the following 11,Doe,John,555-1234 22,Doe,Jane,555-5266 33,Smith,Beth,555-5434 Part 2. Modify the program to allow the user to read in and display the information about the clients. Entry #11 John Doe - 555-1234 Entry #22 Jane Doe - 555-5266 Entry #33 Beth Smith - 555-5434 Part 3. Modify the program to store the phone book information as serialized objects rather than text. Use phone.obj as the storage le. (NOTE: For this to work it is important that the rst object you store in the le is the number of objects. That way you know how many objects to read in) Part 4. (Optional) Modify the program from Part 1 and Part 2 to allow the user to modify an entry in the le. Part 5. (Optional) Modify the program from Part 1 and Part 2 to allow the user to delete an entry from the le.

Page 208

c 2008 n + 1, Inc All Rights Reserved

Chapter 11

JDBC
Objectives
Understand the dierence between JDBC drivers Learn how to use the driver manager to connect to database Learn how to manage transactions Learn how to query the database Learn how to get results from SELECT queries Understand how Java data types relate to SQL data types

209

CHAPTER 11. JDBC

11.1 JDBC Drivers


JDBC stands for Java Database Connectivity. It resides in the java.sql and javax.sql packages in the J2SE. The Java API provides a set of interfaces for interacting with the database. It provides no concrete implementations for those interfaces. That is left to the database vendors. Since the API is nothing but a set of interfaces that are implemented by the vendors, JDBC is database independent. All of the methods for accessing and updating the data are the same regardless of what database platform the developer chooses. In theory, no code would need to be modied to convert from one database to another. In practice, this task isnt always so simple. SQL dialects and stored procedures can be dierent between databases which means the code might have to be modied to meet the SQL needs of the database software. JDBC drivers provided by database vendors fall into four categories. The rst is the Type 1 JDBC-ODBC bridge. The Type 1 drivers provide connectivity by hooking into an already existent ODBC database driver. It communicates with the ODBC driver which in turn communicates with the database. The ODBC drivers must be in place before using the bridge. Type 1 drivers are the slowest of the four. Type 2 drivers uses a native API proxy for communication. They make a native call to the database library which in turn passes the call to the database. This method is faster than Type 1 driver, but it requires the native database library on the client. Type 3 drivers are Java only network protocol drivers. They provide communication to the database in a DBMS independent protocol which is then translated by server software into a local database call to the server. Type 4 drivers are Java only native protocol drivers. They provide direct communication to the database using the databases native network protocol. Neither Type 3 nor Type 4 drivers require client loaded binaries making them the preferred JDBC driver type. Most major database provide either a Type 3 or Type 4 driver. They also tend to be faster because they dont use a client based proxy to interact with the database. Most Type 3 or Type 4 drivers are shipped as a JAR le1 . The JAR contains the implementations for the JDBC APIs. To make the driver accessible from an application, a developer must make sure the JAR le is added to the CLASS PATH. It enables the driver to be available to the Java runtime. Once the driver is added to the CLASS PATH, it can be loaded using the DriverManager.

1 A JAR le is a Java ARchive. It provides the means to package multiple les into a single le. Generally they hold all of the class les necessary to perform a task. Java applications and libraries are generally distributed using JAR les. JARs are created using the jar utility that ships with the Java JDK.

Page 210

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

11.2 Driver Manager


The DriverManager class in the java.sql package provides the basic services necessary to utilize the JDBC API. A call to the getConnection() method will utilize the underlying database driver to make a connection to the database. The only problem is the database driver needs to be loaded before DriverManager can be used. Loading the driver is done by calling the static Class.forName() method. The name of the drivers main class is the only argument necessary for the method. The vendor should provide documentation on how to load the driver. Below is an example of loading a Postgres database driver. try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { // error handling } Notice that the static forName(...) method can throw a ClassNotFoundException. The exception will occur if the name of the driver is spelled incorrectly or the database driver has not been added to the virtual machines class path. Once the driver has been loaded it is possible to get a connection to the database. The getConnection() method takes three arguments. The rst is the connection string which holds information about connecting to the database. The second and third are the username and password respectively. The method returns a Connection interface representing a connection to the database. What is the connection string? It is a vendor specic URL for connecting to a database. While each developer should check the vendors documentation, the URL generally has four parts. The rst part identies what type of database the driver is connecting. The example below shows the JDBC connection to a Postgresql database jdbc:postgresql: The second part is the network location for the DBMS. jdbc:postgresql://database.nplus1.net Third is the name of the database. jdbc:postgresql://database.nplus1.net/mydatabase

Page 211

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC Fourth are any database parameters specied as URL parameters. jdbc:postgresql://database.nplus1.net/mydatabase?user=johnd Lastly it is important to remember that almost all JDBC calls can throw a SQLException. Thus a call to getConnection() must catch the checked exception. try { Class.forName("org.postgresql.Driver"); Connection conn = DriverManager.getConnection( "jdbc:postgresql://database.nplus1.net", "johnd", "password"); } catch (SQLException e) { // sql error handling } catch (ClassNotFoundException e) { // error handling }

Page 212

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

11.3 Connection
The Connection interface represents the connection to the database. It is primarily used to retrieve a database statement. The statement sends queries to the database and returns the results. Statements will be covered in greater detail in the next section. In addition to creating statements, the connection is used to handle transactions with the database. By default the connection will auto-commit all queries. Each individual query runs inside of a database transaction and will automatically commit the results after the query. This feature can be turned o programmatically. conn.setAutoCommit(false); Once it is turned o, it is left to the developer to manage the transaction. All queries that are executed after turning o auto commit are part of the transaction. After running queries the programmer has two options. The rst is to commit the transaction. The act of committing will render any changes made in the queries to the database. If a problem occurs with the queries, the user has the option to rollback the transaction. Rolling back an operation will erase any changes made in the queries. conn.setAutoCommit(false); // run query 1 // run query 2 // run query 3 if ( failure ) { conn.rollback(); } else { conn.commit(); } In the example above, auto commit is set to false. Three queries are run. If an error occurred then the queries are rolled back. If not then they are committed to the database.

Page 213

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC The connection also allows save points for large multi-query database updates. A save point allows the developer to roll back part of a transaction without having to roll back the entire set of queries. Only the queries between the save point and the partial rollback are reversed.

Savepoint halfWay = null; conn.setAutoCommit(false); // run query 1 // run query 2 if ( failure ) { conn.rollback(); } else { halfway = conn.setSavepoint(); } // run query 3 // run query 4 if ( failure ) { conn.rollback(halfway); // run new query 3 // run new query 4 } if ( failure ) { conn.rollback(); } else { conn.commit(); }

In addition to manually managing transactions, it is also possible to manage the transaction isolation level. The isolation level determines how databases are locked during a transaction. To understand how the isolation level works it is important to know the three problems transactions have in a multi-user database environment. They are dirty reads, non-repeatable reads and phantom reads. A dirty read occurs when transaction X can read the results of transaction Y before Y is committed. It is considered a dirty read because Y can rollback the transaction which would make the data retrieved from X bad. A non-reapeatable read occurs when a SELECT query in transaction X can be run multiple times and get dierent results. This can occur when transaction Y commits a change while X is still running. Phantom reads occur when transaction Y inserts rows that satisfy the results of a WHERE clause in transaction X. This means that the same SELECT query run twice in transaction X would return a dierent row count, making it appear that new records are magically appearing. Page 214 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The isolation level determines what problems are allowed during a transaction. The Connection interface denes ve static constants to represent the dierent isolation levels. Table 11.1 shows the ve isolation levels. The entries go from least secure and fastest in performance down to most secure and slowest. Isolation Level TRANSACTION NONE TRANSACTION READ UNCOMMITTED TRANSACTION READ COMMITTED TRANSACTION REPEATABLE READ TRANSACTION SERIALIZABLE Description Runs queries outside of transactions. All problems can occur Transaction allows dirty, non-repeatable, and phantom reads. Transaction prevents dirty reads but allows non-repeatable and phantom reads. Transaction prevents dirty and non-repeatable reads while phantom reads can occur. Transaction prevents dirty, non-repeatable and phantom reads. Table 11.1: Isolation Levels The example below shows how to set the isolation level for a connection. conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); One nal note about connections. When nished with the connection make sure to call the close() method to terminate the connection to the database. It is bad practice to leave unused connections open.

Page 215

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC

11.4 Statements
Statements provides a handler for managing database queries. There are three dierent types of statements available in the JDBC API: Statements, PreparedStatements, and CallableStatements. The basic Statement interface is used to make straight SQL queries to the database. The query is executed on the server and results are returned. The PreparedStatement interface provides a mechanism for predening a SQL query and plugging in the values to pass to the SQL call at a later time. The CallableStatement interface is used for making stored procedure calls. The simplest form is the basic Statement. The Statement is retrieved from the connection and provides an interface for making SQL calls on the database. The most commonly used methods are shown in table 11.2. Method ResultSet executeQuery(String sql) int executeUpdate(String sql) Description Takes the SQL SELECT command, runs it against the DB and returns the results as a ResultSet Takes the SQL INSERT, UPDATE, or DELETE query and runs it against the DB. It returns the number of rows eected by the query void close() Closes the statement Table 11.2: Statement Methods The example below shows how the Statement can be used to run simple SQL queries. Statement statement = conn.createStatement(); int rows = statement.executeUpdate( "UPDATE employee SET last_name=Doe WHERE id = 4213"); System.out.println(rows + " Rows Effected"); The drawback to using Statements is the need to write out the entire SQL statement as a String. This becomes increasingly dicult when trying to build dynamic queries. int employeeId = 4213; String lastName = "Doe"; Statement statement = conn.createStatement(); int rows = statement.executeUpdate( "UPDATE employee SET last_name=" + lastName + " WHERE id = " + employeeId); System.out.println(rows + " Rows Effected"); The biggest problem is making sure that data is properly quoted leading to invalid SQL statements. The PreparedStatement makes this process easier. The PreparedStatement is also retrieved from Page 216 c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA the connection, but the SQL statement is passed to the PreparedStatement at creation rather than an execution. Secondly, the SQL string uses question marks to leave as place holders for the data to be lled in later. PreparedStatement ps = conn.prepareStatement( "UPDATE employee SET last_name = ? WHERE id = ?"); The data is lled in with setXXX(int index, XXX value) methods where XXX is the data type that needs to be set. The index is not zero based. It starts with one and counts forward. Below is an example of lling out the data for the SQL query. int employeeId = 4213; String lastName = "Doe"; PreparedStatement ps = conn.prepareStatement( "UPDATE employee SET last_name = ? WHERE id = ?"); ps.setString(1, lastName); ps.setInt(2, employeeId); Notice that the need for single quotes around the last name eld is not required. The prepared statement puts quotes around the data depending on the data type. In the case of the setString() method it would put single quotes around the value.

Page 217

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC Table 11.3 provides a list of common methods for the PreparedStatement interface. Method ResultSet executeQuery() int executeUpdate() Description Takes the predened SQL SELECT command, runs it against the DB and returns the results as a ResultSet Takes the predened SQL INSERT, UPDATE, or DELETE query and runs it against the DB. It returns the number of rows eected by the query void setInt(int index, int value) void setDouble(int index, double value) void setString(int index, String value) void setTimestamp(int index, Timestamp value) void clearParameters() void close() Sets the integer value at specied index Sets the double value at specied index Sets the string value at specied index Sets the time stamp value at specied index Clears all of the parameters previously set Closes the statement Table 11.3: PreparedStatement Methods

Page 218

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

11.5 ResultSet
SELECT queries run with the executeQuery(...) method on any statement will return a cursor. In JDBC the cursor is implemented by the ResultSet interface. The common usage for the ResultSet is to loop over the data and retrieve each of the results. When a ResultSet is created the cursors position is pointing before the rst record in the set. The next() method determines if if more results exist and increment the cursors position to the next element in the rowset. To retrieve data from a rowset, the ResultSet interface provides getXXX(...) methods. Where XXX is the data type the developer wishes to return. The arguments for the getXXX(...) methods are either an index value 2 or the String name of the column. Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery( "SELECT id, first_name, last_name FROM employee"); while ( rs.next() ) { int employeeId = rs.getInt("id"); String firstName = rs.getString(2); String lastName = rs.getString("last_name"); } The ResultSet provides more functionality than simply looping over the results. It provides a developer with the ability scroll backward and forward through the result set. It even allows concurrency. Concurrence is the ability to update the data in the cursor. The availability of these options is set at statement creation time. The createStatement(..) and prepareStatement(...) methods have been overloaded to take two additional arguments. One is for determining concurrency and the other is to determine what type of scrolling to use. Table 11.4 shows the static member variables that make those settings.

2 All

indexes with JDBC start with 1 instead of 0

Page 219

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC Method Concurrency CONCUR READ ONLY CONCUR UPDATABLE Scrollable TYPE FORWARD ONLY TYPE SCROLL INSENSITIVE TYPE SCROLL SENSITIVE The default is to make the ResultSet where the cursor can only move forward. Creates a scrollable result set that is not sensitive to changes made by other users. Creates a scrollable result set that is sensitive to changes made by other users. Table 11.4: Concurrency / Scrollable Types The example below shows how these settings are set when creating a Statement. Statement stat = conn.createStatement( RecordSet.TYPE_SCROLL_INSENSITIVE, RecordSet.CONCUR_READ_ONLY); ResultSet rs = stat.executeQuery( "SELECT id, first_name, last_name FROM employee"); while ( rs.next() ) { int employeeId = rs.getInt("id"); String firstName = rs.getString(2); String lastName = rs.getString("last_name"); } The default is to make the ResultSet read only. Allows the developer to update the ResultSet. Description

Page 220

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA The nal example pulls all of these concepts together into a single program. import import import import java.sql.Connection; java.sql.Statement; java.sql.PreparedStatement; java.sql.RecordSet;

public class DatabaseCode { public static void main(String [] args) { Connection conn = null; try { Class.forName("org.postgresql.Driver"); conn = DriverManager.getConnection( "jdbc:postgresql://database.nplus1.net", "johnd", "password"); conn.setAutoCommit(false); Statement stat = conn.createStatement( RecordSet.TYPE_FORWARD_ONLY, RecordSet.CONCUR_READ_ONLY); PreparedStatement ps = conn.createStatemen( "INSERT INTO phone VALUES(?, ?, ?, ?)"); ps.setInt(1, 1); ps.setString(2, "Beth"); ps.setString(3, "Jones"); ps.setString(4, "555-1234"); ps.executeUpdate(); ps.setInt(1, 2); ps.setString(2, "Sarah"); ps.setString(3, "Doe"); ps.setString(4, "555-4321"); ps.executeUpdate(); conn.commit();

Page 221

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC

ResultSet rs = stat.executeQuery("SELECT * FROM phone"); while ( rs.next() ) { int id = rs.getInt("id"); String first = rs.getString("first_name"); String last = rs.getString("last_name"); String number = rs.getString("phone_number"); System.out.println(first + " " + last + "(" + id + ") " + number); } } catch (SQLException e) { System.out.println("Unable to process SQL statements:" + e.getMessage()); } catch (ClassNotFoundException e) { System.out.println("Unable to load driver:" + e.getMessage()); } finally { try { if ( conn != null ) { conn.close(); } } catch (SQLException e) { System.out.println("Unable to commit and close the connection: " + e.getMessage()); } } } }

Page 222

c 2008 n + 1, Inc All Rights Reserved

INTRODUCTION TO JAVA

11.6 Data Types


One of the problems with accessing databases in Java is that the data types of the database do not directly align with Java data types. Table 11.5 show a list of common SQL data types and their preferred Java data type. SQL Type TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE DECIMAL NUMERIC BIT CHAR VARCHAR DATE TIME TIMESTAMP CLOB BLOB Java Type byte short int long oat double double double double boolean String String java.sql.Date java.sql.Time java.sql.Timestamp java.sql.Clob java.sql.Blob

Table 11.5: SQL - Java Data Type Mapping There are a few things to note about the chart. First, the data types for dates and times have their own Java data type dened in the java.sql package. These classes are wrappers around the java.util.Date class. The Clob type is a large character object. The Clob object provides access to a Reader and Writer object for reading and writing character data to the Clob. These can be chained with higher level readers and writers to simplify the processing of String data. The Blob type is a large binary object. The Blob provides access to an InputStream and OutputStream for reading and writing. These can be chained to higher level Streams to simplify the reading and writing of binary data.

Page 223

c 2008 n + 1, Inc All Rights Reserved

CHAPTER 11. JDBC

11.7 Lab Activity


Part 1. Obtain the JDBC driver from your instructor and add it to your CLASSPATH Part 2. Using a connection string provided by the instructor, write a simple program to connect to the database and display the contents from the phonebook table. The schema for the phonebook is shown below. create table phonebook ( id integer not null, firstname varchar(40), lastname varchar(40), number varchar(12), constraint "pk\_id" primary key (id) ); Part 3. Create a simple phone book command line application. A The default behavior of the application is to list the data from the phone book in alphabetical order. Alphabetization should be surname rst and given name second. $> 2) 8) 3) java PhoneBook list Jane Doe 555-4322 John Doe 555-1234 Jimmy Smith 555-4321

B Provide a command line parameter to allow the insertion of a new entry. Generate an error message if the incorrect number of parameters are supplied. (The INSERT should use a PreparedStatement) $> java PhoneBook add Laura Doe 555-5678 entry added C Provide a command line parameter for removing an entry from the phone book. Generate an error message if the incorrect number of parameters are supplied or the entry selected does not exist. $> java PhoneBook remove 8 entry removed D (Optional) Provide a command line parameter for updating an entry from the phone book. Generate an error message if the incorrect number of parameters are supplied or the entry selected does not exist. $> java PhoneBook update 3 Jaime Jones 555-4321 entry updated c 2008 n + 1, Inc All Rights Reserved

Page 224

Appendices

225

JAVA WEB PROGRAMMING

Lab Results

The results from the labs are shown below.

A.1 Lab 2
Part 2 - Countdown.java public class CountDown { public static void main(String[] args) { for ( int x = 10; x > 0 ; x-- ) { System.out.println(x); } System.out.println("\nCountdown Complete!"); } } Part 3 - OddCountdown.java public class OddCountdown { public static void main(String[] args) { for ( int x = 9; x > 0 ; x -= 2 ) { System.out.println(x); } System.out.println("\nCountdown Complete!"); } }

Page 227

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 4 - ShortByteCounter.java public class ShortByteCounter { public static void main(String[] args) { short shortValue = 0; byte byteValue = 0; for ( shortValue = 1; shortValue <= 200; shortValue ++ ) { byteValue = (byte)shortValue; System.out.print("Short="); System.out.print(shortValue); System.out.print(" Byte="); System.out.println(byteValue); } } } Part 5 - PrimeNumbers.java public class PrimeNumbers { public static void main(String[] args) { boolean isPrime; int primeTest; int number; for ( number = 2; number < 1001; number++ ) { isPrime = true; for ( primeTest = 2; primeTest < number; primeTest++ ) { if ( number % primeTest == 0 ) { isPrime = false; break; } } if ( isPrime ) { System.out.println(number); } } } }

Page 228

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 6 - AreaUnderCurve.java /* * This program uses the triangle method for determining the * area under the curve. A simpler system would have been to use * the rectangular method. */ public class AreaUnderCurve { public static void main(String[] args) { double width = .01; double area = 0.0; for ( double x = 0 ; x < 20; x += width ) { // get next value of x double nextX = x + width; // get values for y for x and nextX double y = (x * x) - (4 * x) + 5; double nextY = (nextX * nextX) - (4 * nextX) + 5; // we have the width so now we need the base of the // square plus the height of the triangle part on top double base = 0.0; double sideOfTriangle = 0.0; // depending on which is greater as to which we will use if ( y > nextY ) { base = nextY; sideOfTriangle = y - nextY; } else { base = y; sideOfTriangle = nextY - y; } // now we need to make our calculations // get area of rectangle and area of triangle and add together area += base * width; area += (sideOfTriangle * width) / 2; } System.out.print("Area under the curve is "); System.out.println(area); } }

Page 229

c 2009 n + 1, Inc All Rights Reserved

APPENDIX

A.2 Lab 3
Part 1 - MortgageCalculator.java

public class MortgageCalculator { private int numberYears; private double interestRate; private double loanAmount; private double monthlyPayment; // ===================================== // Calculating methods // ===================================== public void calculateMonthlyPayment() { // formula is M = P * (k / (1 - (1 + k)n)) int n = numberYears * 12; // get months double k = interestRate / 12; double p = loanAmount; double m = p * (k / (1 - Math.pow((1 + k), -n))); monthlyPayment = m; } public void calculateLoanAmount() { // formula is P = M / (k / (1 - (1 + k)n)) int n = numberYears * 12; // get months double k = interestRate / 12; double m = monthlyPayment; double p = m / ( k / (1 - Math.pow((1 + k), -n))); loanAmount = p; } // ===================================== // Accessor methods // ===================================== public double getInterestRate() { return interestRate; } public double getLoanAmount() { return loanAmount; } public double getMonthlyPayment() { return monthlyPayment; } Page 230 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING public int getNumberYears() { return numberYears; } // ===================================== // Mutator methods // ===================================== public void setInterestRate(double interestRate) { this.interestRate = interestRate; } public void setLoanAmount(double loanAmount) { this.loanAmount = loanAmount; } public void setMonthlyPayment(double monthlyPayment) { this.monthlyPayment = monthlyPayment; } public void setNumberYears(int numberYears) { this.numberYears = numberYears; } }

Page 231

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 2 - Mortgage.java public class Mortgage { private MortgageCalculator calculator; public void calculateMonthlyPayment(int numberYears, double interestRate, double loanAmount) { calculator = new MortgageCalculator(); calculator.setNumberYears(numberYears); calculator.setInterestRate(interestRate); calculator.setLoanAmount(loanAmount); calculator.calculateMonthlyPayment(); } public void calculateLoanAmount(int numberYears, double interestRate, double monthlyPayment) { calculator = new MortgageCalculator(); calculator.setNumberYears(numberYears); calculator.setInterestRate(interestRate); calculator.setMonthlyPayment(monthlyPayment); calculator.calculateLoanAmount(); } public void printMortgage() { if ( calculator != null ) { System.out.println("Amount of Loan: " + calculator.getLoanAmount()); System.out.println("Interest Rate: " + calculator.getInterestRate()); System.out.println("Number of Years: " + calculator.getNumberYears()); System.out.println("Monthly Payment: " + calculator.getMonthlyPayment()); } else { System.out.println("No mortgage information available"); } } }

Page 232

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 3 - Main.java public class Main { public static void main(String[] args) { Mortgage mortgage = new Mortgage(); System.out.println("Scenario A"); mortgage.calculateMonthlyPayment(20, .089, 100000); mortgage.printMortgage(); System.out.println("\nScenario B"); mortgage.calculateLoanAmount(30, .075, 2000); mortgage.printMortgage(); } }

Page 233

c 2009 n + 1, Inc All Rights Reserved

APPENDIX

A.3 Lab 4
Part 1 - PartOne.java public class PartOne { public static void main(String [] args) { String s = "I wish it were Monday"; System.out.println("The length of s is " + s.length()); System.out.println(s.substring(2,14)); s = s.replace(M, F); s = s.replace(o, r); s = s.replace(n, i); System.out.println(s.replace("Monday", "Friday")); } } Part 2 - PartTwo.java public class PartTwo { public static void main(String [] args) { String s = "oNe,tWo,tHree,foUr,fiVe,sIx,Seven"; String [] parts = s.split(","); String output = ""; for ( int x = parts.length - 1; x >= 0; x-- ) { output += parts[x].trim().toLowerCase() + ","; } output = output.substring(0, output.length() - 1); System.out.println(output); output = ""; for ( int x = 0; x < parts.length; x++ ) { if ( x % 2 == 1 ) { output += parts[x].trim().toUpperCase() + ","; } else { output += parts[x].trim().toLowerCase() + ","; } } output = output.substring(0, output.length() - 1); System.out.println(output); } }

Page 234

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 3 - Conversion.java public class Conversion { public static void main(String [] args) { double conversion = 0; double temp = Double.parseDouble(args[1]); if (args[0].equals("celsius") ) { conversion = (5.0/9)*(temp - 32); System.out.println("Fahrenheit of " + temp + " is converted to a Celsius of " + conversion + "."); } if (args[0].equals("fahrenheit") ) { conversion = (9.0/5)*temp + 32; System.out.println("Celsius of " + temp + " is converted to a Fahrenheit of " + conversion + "."); } } } Part 4 - Order.java public class Order { public static void main(String [] args) { int [] data = { 24, 18, 12, 29, 4, 15, 2, 9, 18, 23, 22, 7 }; for ( int x = 0; x < data.length; x++ ) { for ( int y = 0; y < data.length - 1; y++ ) { if ( data[y] > data [y + 1] ) { int temp = data[y]; data[y] = data[y + 1]; data[y + 1] = temp; } } } for ( int x = 0; x < data.length; x++) { System.out.println(data[x]); } } }

Page 235

c 2009 n + 1, Inc All Rights Reserved

APPENDIX

A.4 Lab 5
Part 1 and 5 - Date.java

public class Date { private int day; private int month; private int year; private String [] months; public Date() { this(0,0,0); } public Date(String month, int day, int year) { this(1, day, year); this.setMonth(month); } public Date(int month, int day, int year) { String [] m = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; months = m; this.setMonth(month); this.setDay(day); this.year = year; } public String getShortDate() { String date = month + "/" + day + "/" + year; return date; } public String getLongDate() { String date = months[month - 1] + " " + day + ", " + year; return date; } public void setMonth(String month) { this.month = 1; for ( int x = 0; x < 12; x++ ) { if ( month.equals(months[x]) ) this.month = x + 1; } } Page 236

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } public void setDay(int day) { if ( day < 0 ) { day = 1; } else if ( day > 31 ) { day = 31; } this.day = day; } public void setMonth(int month) { if ( month < 1 ) { month = 1; } else if ( month > 12 ) { month = 12; } this.month = month; } public void setYear(int year) { this.year = year; }

Page 237

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 2 - Event.java public class Event { private String name; private String location; private Date date; public Event() { this("", "", null); } public Event(String name, String location, Date date) { this.name = name; this.location = location; this.date = date; } public Date getDate() { return date; } public String getLocation() { return location; } public String getName() { return name; } public void setDate(Date date) { this.date = date; } public void setLocation(String location) { this.location = location; } public void setName(String name) { this.name = name; } }

Page 238

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 3 - Planner.java public class Planner { private int index; private Event [] events; public Planner() { index = 0; events = new Event[10]; } public void addEvent(Event event) { events[index] = event; index++; } public void printEvents() { for ( int x = 0; x < index; x++ ) { Event event = events[x]; String output = event.getName() + " @ " + event.getLocation(); output += " (" + event.getDate().getShortDate() + ")"; System.out.println(output); } } public void printEvent(int eventNumber) { Event event = events[eventNumber]; String output output output output = "You are coordially invited to attend "; += event.getName() + "\n"; += "at " + event.getLocation() + "\n"; += "on " + event.getDate().getLongDate();

System.out.println(output); } }

Page 239

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 4 - Main.java public class Main { public static void main(String[] args) { Date date1 = new Date(3, 10, 2008); Date date2 = new Date("March", 43, 2008); Date date3 = new Date(1, 13, 2008); Date date4 = new Date("April", 1, 2008); Date date5 = new Date(9, 28, 2008); Event Event Event Event Event event1 event2 event3 event4 event5 = = = = = new new new new new Event("My Event("My Event("My Event("My Event("My First Event", "1 East Street", date1); Second Event", "2 West Street", date2); Third Event", "3 South Street", date3); Fourth Event", "4 North Street", date4); First Event", "5 East Street", date5);

Planner planner = new Planner(); planner.addEvent(event1); planner.addEvent(event2); planner.addEvent(event3); planner.addEvent(event4); planner.addEvent(event5); planner.printEvents(); planner.printEvent(2); } }

Page 240

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 6 - InvitationMaker.java public class InvitationMaker { public static void main(String[] args) { String input = ""; for ( int x = 0; x < args.length; x++ ) { input += args[x] + " "; } String [] data = input.split(","); String String String String String name = data[0].trim(); location = data[1].trim(); monthValue = data[2].trim(); dayValue = data[3].trim(); yearValue = data[4].trim();

int month = Integer.parseInt(monthValue); int day = Integer.parseInt(dayValue); int year = Integer.parseInt(yearValue); Date date = new Date(); date.setMonth(month); date.setDay(day); date.setYear(year); Event event = new Event(); event.setDate(date); event.setLocation(location); event.setName(name); Planner planner = new Planner(); planner.addEvent(event); planner.printEvent(0); } }

Page 241

c 2009 n + 1, Inc All Rights Reserved

APPENDIX

A.5 Lab 6
Part 1 - Shape.java public class Shape { private String name; private int sides;

public Shape() { name = "shape"; }

public double getArea() { return -1.0; } public void printArea() { double area = this.getArea(); System.out.print("The " + name + " has " + this.sides + " sides with an "); if ( area < 0.0 ) { System.out.println("indeterminate area"); } else { System.out.println("area of " + area); } } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSides() { return sides; } public void setSides(int sides) { this.sides = sides; } }

Page 242

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Main.java (For the entire lab) public class Main { public static void main(String[] args) { Shape shape = new Shape(); shape.setSides(9); shape.printArea();

Circle circle = new Circle(); circle.setRadius(4.6); circle.printArea(); Rectangle rect = new Rectangle(11.1, 4.5); rect.printArea(); Square square = new Square(9.0); square.printArea(); square.setWidth(5); square.setHeight(10); square.printArea(); } }

Page 243

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 2 - Circle.java public class Circle extends Shape { public static final double PI = 3.14159; private double radius; public Circle() { this.setSides(0); this.setName("circle"); } public double getArea() { double area = Circle.PI * radius * radius; return area; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } }

Page 244

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 3 - Rectangle.java public class Rectangle extends Shape { private double width; private double height; public Rectangle(double width, double height) { this.setName("rectangle"); this.setSides(4); this.width = width; this.height = height; } public double getArea() { return width * height; } public double getHeight() { return height; } public double getWidth() { return width; } public void setHeight(double height) { this.height = height; } public void setWidth(double width) { this.width = width; } }

Page 245

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 4 - Square.java public class Square extends Rectangle { public Square(double length) { super(length, length); this.setName("square"); } public void setWidth(double width) { super.setWidth(width); super.setHeight(width); } public void setHeight(double height) { super.setWidth(height); super.setHeight(height); } }

Page 246

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING

A.6 Lab 7
Part 1 AbstractCalculator.java public abstract class AbstractCalculator implements AccountInformation, Interest Calculator { private String firstName; private String lastName; private double initialBalance; private double interestRate; abstract public double calculateFutureValue(int yearsInvested); public String getFirstName() { return firstName; } public double getInitialBalance() { return initialBalance; } public double getInterestRate() { return interestRate; } public String getLastName() { return lastName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setInitialBalance(double initialBalance) { this.initialBalance = initialBalance; } public void setInterestRate(double interestRate) { this.interestRate = interestRate; } public void setLastName(String lastName) { this.lastName = lastName; } }

Page 247

c 2009 n + 1, Inc All Rights Reserved

APPENDIX YearlyInterestCalculator.java public class YearlyInterestCalculator extends AbstractCalculator { public double calculateFutureValue(int yearsInvested) { double future = this.getInitialBalance(); future *= Math.pow(1 + this.getInterestRate(), yearsInvested); return future; } } MonthlyInterestCalculator.java public class MonthlyInterestCalculator extends AbstractCalculator { public double calculateFutureValue(int yearsInvested) { double future = this.getInitialBalance(); future *= Math.pow(1 + (this.getInterestRate()/12), yearsInvested * 12); return future; } } ContinousInterestCalculator.java public class ContinousInterestCalculator extends AbstractCalculator { public double calculateFutureValue(int yearsInvested) { double future = this.getInitialBalance(); future *= Math.pow(Math.E, this.getInterestRate() * yearsInvested); return future; } }

Page 248

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING

A.7 Lab 8
Part 1 - Angle.java import java.util.Scanner; public class Angle { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("What angle for the operation? "); String stringAngle = scanner.nextLine(); int angle = Integer.parseInt(stringAngle); System.out.print("What operation to perform (cos, sin, tan)? "); String op = scanner.nextLine(); double radians = Math.toRadians(angle); double results = 0.0; String operation = ""; if ( op.equals("cos") ) { results = Math.cos(radians); operation = "cosine"; } else if ( op.equals("sin") ) { results = Math.sin(radians); operation = "sine"; } else if ( op.equals("tan") ) { results = Math.tan(radians); operation = "tangent"; } System.out.format("\nThe %1s of %2$d degrees is %3$.3f results", operation, angle, results); } }

Page 249

c 2009 n + 1, Inc All Rights Reserved

APPENDIX Part 2 - MyCalendar.java import java.util.Calendar; import java.util.Date; public class MyCalendar { public void printMonth(Date date) { this.print(date, 1); } public void printYear(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.MONTH, Calendar.JANUARY); date = cal.getTime(); this.print(date, 12); } public void printThreeMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.MONTH, -1); date = cal.getTime(); this.print(date, 3); } private void print(Date startMonth, int numberMonths) { Calendar cal = Calendar.getInstance(); cal.setTime(startMonth); // go to first day of the month cal.set(Calendar.DAY_OF_MONTH, 1); for ( int x = 0 ; x < numberMonths; x++ ) { // print month and year using format System.out.format("%1$tB %1$tY\n", cal.getTime()); // print cal information System.out.println("Su Mo Tu We Th Fr Sa"); // find out the day of the week that month starts on int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); int day = cal.get(Calendar.DAY_OF_MONTH); int offset = this.dayOfWeekOffset(dayOfWeek); for ( int y = 0; y < offset; y++ ) { if ( y != 0 ) { Page 250 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING System.out.print(" "); } System.out.print(" "); } int lastDay = day - 1; // loop until end of the month while ( day > lastDay ) { // loop through the week dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); if ( dayOfWeek == Calendar.SUNDAY ) { System.out.println(); System.out.format("%2d", day); } else { System.out.format("%3d", day); } lastDay = day; cal.add(Calendar.DAY_OF_MONTH, 1); day = cal.get(Calendar.DAY_OF_MONTH); } System.out.println("\n"); } } private int dayOfWeekOffset(int dayOfWeek) { int offset = 0; switch (dayOfWeek) { case Calendar.MONDAY: offset = 1; break; case Calendar.TUESDAY: offset = 2; break; case Calendar.WEDNESDAY: offset = 3; break; case Calendar.THURSDAY: offset = 4; break; case Calendar.FRIDAY: offset = 5; break; case Calendar.SATURDAY: offset = 6; Page 251 c 2009 n + 1, Inc All Rights Reserved

APPENDIX break; } return offset; } }

Page 252

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING Part 3 and 4 - CalendarProgram.java import java.util.Calendar; import java.util.Date; import java.util.Scanner; public class CalendarProgram { public static void main(String[] args) { Date now = new Date(); MyCalendar cal = new MyCalendar(); cal.printMonth(now); cal.printYear(now); Calendar calendar = Calendar.getInstance(); Scanner scanner = new Scanner(System.in); System.out.print("What month (3 letters)? "); String monthValue = scanner.nextLine(); if ( monthValue.equalsIgnoreCase("jan") ) { calendar.set(Calendar.MONTH, Calendar.JANUARY); } else if ( monthValue.equalsIgnoreCase("feb") ) { calendar.set(Calendar.MONTH, Calendar.FEBRUARY); } else if ( monthValue.equalsIgnoreCase("mar") ) { calendar.set(Calendar.MONTH, Calendar.MARCH); } else if ( monthValue.equalsIgnoreCase("apr") ) { calendar.set(Calendar.MONTH, Calendar.APRIL); } else if ( monthValue.equalsIgnoreCase("may") ) { calendar.set(Calendar.MONTH, Calendar.MAY); } else if ( monthValue.equalsIgnoreCase("jun") ) { calendar.set(Calendar.MONTH, Calendar.JUNE); } else if ( monthValue.equalsIgnoreCase("jul") ) { calendar.set(Calendar.MONTH, Calendar.JULY); } else if ( monthValue.equalsIgnoreCase("aug") ) { calendar.set(Calendar.MONTH, Calendar.AUGUST); } else if ( monthValue.equalsIgnoreCase("sep") ) { calendar.set(Calendar.MONTH, Calendar.SEPTEMBER); } else if ( monthValue.equalsIgnoreCase("oct") ) { calendar.set(Calendar.MONTH, Calendar.OCTOBER); Page 253 c 2009 n + 1, Inc All Rights Reserved

APPENDIX } else if ( monthValue.equalsIgnoreCase("nov") ) { calendar.set(Calendar.MONTH, Calendar.NOVEMBER); } else if ( monthValue.equalsIgnoreCase("dec") ) { calendar.set(Calendar.MONTH, Calendar.DECEMBER); } System.out.print("What year? "); String yearValue = scanner.nextLine(); int year = Integer.parseInt(yearValue); calendar.set(Calendar.YEAR, year); Date date = calendar.getTime(); cal.printThreeMonth(date); } }

Page 254

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING

A.8 Lab 9
PhoneBook.java

import java.util.HashMap; import java.util.ArrayList; import java.util.Map; public class PhoneBook { private ArrayList<HashMap<String,String>> book; public PhoneBook() { book = new ArrayList<HashMap<String,String>>(); } public void delete(int index) { if ( index > 0 && index <= book.size() ) { book.remove(index - 1); } } public void add(String firstName, String lastName, String phone) { HashMap<String,String> entry = new HashMap<String, String>(); entry.put("firstName", firstName); entry.put("lastName", lastName); entry.put("phoneNumber", phone); book.add(entry); } public void listEntries() { int index = 1; this.sortBook(); if ( book.size() == 0 ) { System.out.println("No entries"); } else { for ( Map<String,String> entry : book ) { String output = index + ") "; output += entry.get("lastName") + " " + entry.get("firstName"); output += " " + entry.get("phoneNumber"); System.out.println(output); index++; } } } Page 255 c 2009 n + 1, Inc All Rights Reserved

APPENDIX

private void sortBook() { for ( int x = 0; x < book.size(); x++ ) { for ( int y = 0; y < book.size() - 1; y++ ) { HashMap<String,String> first = book.get(y); HashMap<String,String> second = book.get(y + 1); String name1 = first.get("lastName"); String name2 = second.get("lastName"); if ( name1.compareTo(name2) > 0 ) { book.remove(y); book.add(y + 1, first); } } } } }

Page 256

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING PhoneBookApplication.java import java.util.Scanner; public class PhoneBookApplication { public static void main(String[] args) { int menu = 0; PhoneBook book = new PhoneBook(); while ( menu != 4 ) { System.out.println("1) List phone book"); System.out.println("2) Add phone book entry"); System.out.println("3) Delete phone book entry"); System.out.println("4) Exit\n"); System.out.print("Select: "); Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); menu = Integer.parseInt(input); switch ( menu ) { case 1: book.listEntries(); break; case 2: System.out.print("First Name? "); String firstName = scanner.nextLine(); System.out.print("Last Name? "); String lastName = scanner.nextLine(); System.out.print("Phone Number? "); String phone = scanner.nextLine(); book.add(firstName, lastName, phone); System.out.println("\n" + firstName + " " + lastName + " has been added"); break; case 3: System.out.print("Which phone entry to delete? "); String value = scanner.nextLine(); int index = Integer.parseInt(value); book.delete(index); break; } System.out.println(); } Page 257 c 2009 n + 1, Inc All Rights Reserved

APPENDIX } }

Page 258

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING

A.9 Lab 10
PhoneEntry.java

import java.io.Serializable; public class PhoneEntry implements Serializable { private int id; private String firstName; private String lastName; private String phoneNumber; public String getFirstName() { return firstName; } public int getId() { return id; } public String getLastName() { return lastName; } public String getPhoneNumber() { return phoneNumber; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setId(int id) { this.id = id; } public void setLastName(String lastName) { this.lastName = lastName; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String exportData() { String data = id + "," + lastName + "," + firstName + return data; } public void importData(String data) { String [] values = data.split(","); this.id = Integer.parseInt(values[0]); this.firstName = values[2]; this.lastName = values[1]; Page 259 c 2009 n + 1, Inc All Rights Reserved

"," + phoneNumber

APPENDIX this.phoneNumber = values[3]; } }

Page 260

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING PhoneBookDB.java (comma separated le solution) import import import import import import import import java.io.BufferedReader; java.io.FileNotFoundException; java.io.FileReader; java.io.FileWriter; java.io.IOException; java.io.PrintWriter; java.util.LinkedList; java.util.List;

public class PhoneBookDB { public void addEntry(PhoneEntry entry) { try { FileWriter writer = new FileWriter("phone.txt", true); PrintWriter out = new PrintWriter(writer); out.println(entry.exportData()); out.close(); writer.close(); } catch (IOException e) { System.out.println("Unable to add entry: " + e.getMessage()); } } public List<PhoneEntry> getEntries() { LinkedList<PhoneEntry> entries = new LinkedList<PhoneEntry>(); try { FileReader reader = new FileReader("phone.txt"); BufferedReader in = new BufferedReader(reader); String data = in.readLine(); while ( data != null ) { PhoneEntry entry = new PhoneEntry(); entry.importData(data); entries.add(entry); data = in.readLine(); } } catch (FileNotFoundException e) { entries = null; } catch (IOException e) { System.out.println("Unable to retrieve entries: " + e.getMessage()); } return entries; Page 261 c 2009 n + 1, Inc All Rights Reserved

APPENDIX } public void updateEntry(PhoneEntry updateEntry) { List<PhoneEntry> entries = this.getEntries(); for ( PhoneEntry entry : entries ) { if ( entry.getId() == updateEntry.getId() ) { entry.setFirstName(updateEntry.getFirstName()); entry.setLastName(updateEntry.getLastName()); entry.setPhoneNumber(updateEntry.getPhoneNumber()); break; } } this.writeEntries(entries); } public void deleteEntry(int id) { List<PhoneEntry> entries = this.getEntries(); for ( PhoneEntry entry : entries ) { if ( entry.getId() == id ) { entries.remove(entry); break; } } this.writeEntries(entries); } private void writeEntries(List<PhoneEntry> entries) { try { FileWriter writer = new FileWriter("phone.txt", false); PrintWriter out = new PrintWriter(writer); for ( PhoneEntry entry : entries ) { out.println(entry.exportData()); } out.close(); writer.close(); } catch (IOException e) { System.out.println("Unable to add entry: " + e.getMessage()); } } }

Page 262

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING PhoneBookDB2.java (objects stored in le solution) import import import import import import import import java.io.FileInputStream; java.io.FileNotFoundException; java.io.FileOutputStream; java.io.IOException; java.io.ObjectInputStream; java.io.ObjectOutputStream; java.util.LinkedList; java.util.List;

public class PhoneBookDB2 { public void addEntry(PhoneEntry entry) { List<PhoneEntry> entries = this.getEntries(); if ( entries == null ) { entries = new LinkedList<PhoneEntry>(); } entries.add(entry); this.writeEntries(entries); } public List<PhoneEntry> getEntries() { LinkedList<PhoneEntry> entries = new LinkedList<PhoneEntry>(); try { FileInputStream fis = new FileInputStream("phone.obj"); ObjectInputStream ois = new ObjectInputStream(fis); int numberEntries = ois.readInt(); for ( int x = 0; x < numberEntries; x++ ) { PhoneEntry entry = (PhoneEntry)ois.readObject(); entries.add(entry); } ois.close(); fis.close(); } catch (FileNotFoundException e) { // set list to null entries = null; } catch (IOException e) { System.out.println("Unable to retrieve entries: " + e.getMessage()); e.printStackTrace(); } catch (ClassNotFoundException e) { System.out.println("Unable to load class: " + e.getMessage()); }

Page 263

c 2009 n + 1, Inc All Rights Reserved

APPENDIX return entries; } public void updateEntry(PhoneEntry updateEntry) { List<PhoneEntry> entries = this.getEntries(); for ( PhoneEntry entry : entries ) { if ( entry.getId() == updateEntry.getId() ) { entry.setFirstName(updateEntry.getFirstName()); entry.setLastName(updateEntry.getLastName()); entry.setPhoneNumber(updateEntry.getPhoneNumber()); break; } } this.writeEntries(entries); } public void deleteEntry(int id) { List<PhoneEntry> entries = this.getEntries(); for ( PhoneEntry entry : entries ) { if ( entry.getId() == id ) { entries.remove(entry); break; } } this.writeEntries(entries); } private void writeEntries(List<PhoneEntry> entries) { try { FileOutputStream fos = new FileOutputStream("phone.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeInt(entries.size()); for ( PhoneEntry entry : entries ) { oos.writeObject(entry); } oos.close(); fos.close(); } catch (IOException e) { System.out.println("Unable to add entry: " + e.getMessage()); } } }

Page 264

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING PhoneBook.java import java.util.List; public class PhoneBook { public static void main(String[] args) { PhoneBookDB2 db = new PhoneBookDB2(); if ( args.length < 1 ) { System.out.println("usage: PhoneBook <command> [args]"); System.exit(0); } if ( args[0].equals("add") ) { PhoneEntry entry = new PhoneEntry(); entry.setId(Integer.parseInt(args[1])); entry.setFirstName(args[2]); entry.setLastName(args[3]); entry.setPhoneNumber(args[4]); db.addEntry(entry); } else if ( args[0].equals("list") ) { List<PhoneEntry> entries = db.getEntries(); if ( entries == null ) { System.out.println("Unable to find file"); } else { for ( PhoneEntry entry : entries ) { String output = "Entry #" + entry.getId(); output += " " + entry.getFirstName() + " " + entry.getLastNa output += " - " + entry.getPhoneNumber(); System.out.println(output); } } } else if ( args[0].equals("edit") ) { PhoneEntry entry = new PhoneEntry(); entry.setId(Integer.parseInt(args[1])); entry.setFirstName(args[2]); entry.setLastName(args[3]); entry.setPhoneNumber(args[4]); db.updateEntry(entry); } else if ( args[0].equals("delete") ) { int id = Integer.parseInt(args[1]); db.deleteEntry(id); } } } Page 265 c 2009 n + 1, Inc All Rights Reserved

APPENDIX

A.10 Lab 11
PhoneEntry.java public class PhoneEntry { private int id; private String firstName; private String lastName; private String phoneNumber; public String getFirstName() { return firstName; } public int getId() { return id; } public String getLastName() { return lastName; } public String getPhoneNumber() { return phoneNumber; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setId(int id) { this.id = id; } public void setLastName(String lastName) { this.lastName = lastName; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } }

Page 266

c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING PhoneBookDB.java import import import import import import import import java.sql.Connection; java.sql.DriverManager; java.sql.PreparedStatement; java.sql.ResultSet; java.sql.SQLException; java.sql.Statement; java.util.LinkedList; java.util.List;

public class PhoneBookDB { private Connection connection; public PhoneBookDB() { connection = null; try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public List<PhoneEntry> getEntries() { LinkedList<PhoneEntry> entries = new LinkedList<PhoneEntry>(); try { Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery( "SELECT * FROM phonebook ORDER BY lastname, firstname"); while ( rs.next() ) { PhoneEntry entry = new PhoneEntry(); entry.setId(rs.getInt("id")); entry.setFirstName(rs.getString("firstname")); entry.setLastName(rs.getString("lastname")); entry.setPhoneNumber(rs.getString("number")); entries.add(entry); } } catch (SQLException e) { e.printStackTrace(); } return entries; } public void add(PhoneEntry entry) { String sql = "INSERT INTO phonebook" + Page 267 c 2009 n + 1, Inc All Rights Reserved

APPENDIX "VALUES(nextval(phonebook_seq), ?, ?, ?)"; try { PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, entry.getFirstName()); ps.setString(2, entry.getLastName()); ps.setString(3, entry.getPhoneNumber()); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void update(PhoneEntry entry) { String sql = "UPDATE phonebook SET firstname=?, " + "lastname=?, number=? WHERE id=?"; try { PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, entry.getFirstName()); ps.setString(2, entry.getLastName()); ps.setString(3, entry.getPhoneNumber()); ps.setInt(4, entry.getId()); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void remove(int id) { String sql = "DELETE FROM phonebook WHERE id = ?"; try { PreparedStatement ps = connection.prepareStatement(sql); ps.setInt(1, id); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void connect() { if ( connection == null ) { try { connection = DriverManager.getConnection( "jdbc:postgresql://localhost/testing", "brians", ""); } catch (SQLException e) { Page 268 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING e.printStackTrace(); } } } public void close() { if ( connection != null ) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }

Page 269

c 2009 n + 1, Inc All Rights Reserved

APPENDIX PhoneBook.java import java.util.List; public class PhoneBook { public static void main(String[] args) { if ( args.length < 1 ) { System.out.println("Usage: PhoneBook <command> [args]"); System.exit(0); } PhoneBookDB db = new PhoneBookDB(); db.connect(); if ( args[0].equals("list") ) { List<PhoneEntry> entries = db.getEntries(); for (PhoneEntry entry : entries) { System.out.print(entry.getId() + ") " + entry.getFirstName()); System.out.println(" " + entry.getLastName() + " " + entry.getPhoneNumber()); } } else if ( args[0].equals("add") ) { if ( args.length != 4 ) { System.out.println("Usage: PhoneBook <command> [args]"); System.out.println("PhoneBook add <first name> " + "<last name> <phone>"); db.close(); System.exit(0); } PhoneEntry entry = new PhoneEntry(); entry.setFirstName(args[1]); entry.setLastName(args[2]); entry.setPhoneNumber(args[3]); db.add(entry); System.out.println("entry added"); } else if ( args[0].equals("remove") ) { if ( args.length != 2 ) { System.out.println("Usage: PhoneBook <command> [args]"); System.out.println("PhoneBook remove <id>"); db.close(); System.exit(0); } int id = Integer.parseInt(args[1]); db.remove(id); System.out.println("entry removed"); Page 270 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING } else if ( args[0].equals("update") ) { if ( args.length != 5 ) { System.out.println("Usage: PhoneBook <command> [args]"); System.out.println("PhoneBook update <id> <first name> " + "<last name> <phone>"); db.close(); System.exit(0); } PhoneEntry entry = new PhoneEntry(); entry.setId(Integer.parseInt(args[1])); entry.setFirstName(args[2]); entry.setLastName(args[3]); entry.setPhoneNumber(args[4]); db.update(entry); System.out.println("entry updated"); } else { System.out.println("Usage: PhoneBook <command> [args]"); System.out.println("command = list,add,remove,update"); } db.close(); } }

Page 271

c 2009 n + 1, Inc All Rights Reserved

APPENDIX

B GNU Free Documentation License


Version 1.3, 3 November 2008 Copyright c 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble
The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the eective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modications made by others. This License is a kind of copyleft, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS


This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The Document, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as you. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A Modied Version of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modications and/or translated into another language. A Secondary Section is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Documents overall subject (or to related matters) and contains nothing that could fall directly within that overall Page 272 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The Invariant Sections are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not t the above denition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The Cover Texts are certain short passages of text that are listed, as Front-Cover Texts or BackCover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A Transparent copy of the Document means a machine-readable copy, represented in a format whose specication is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent le format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modication by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not Transparent is called Opaque. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standardconforming simple HTML, PostScript or PDF designed for human modication. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The Title Page means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, Title Page means the text near the most prominent appearance of the works title, preceding the beginning of the body of the text. The publisher means any person or entity that distributes copies of the Document to the public. A section Entitled XYZ means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specic section name mentioned below, such as Acknowledgements, Dedications, Endorsements, or History.) To Preserve the Title of such a section when you modify the Document means that it remains a section Entitled XYZ according to this denition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Page 273 c 2009 n + 1, Inc All Rights Reserved

APPENDIX Disclaimers may have is void and has no eect on the meaning of this License.

2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Documents license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to t legibly, you should put the rst ones listed (as many as t reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS
You may copy and distribute a Modied Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modied Version under precisely this License, with Page 274 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING the Modied Version lling the role of the Document, thus licensing distribution and modication of the Modied Version to whoever possesses a copy of it. In addition, you must do these things in the Modied Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modications in the Modied Version, together with at least ve of the principal authors of the Document (all of its principal authors, if it has fewer than ve), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modied Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modied Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Documents license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled History, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modied Version as given on the Title Page. If there is no section Entitled History in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modied Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the History section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled Acknowledgements or Dedications, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled Endorsements. Such a section may not be included in the Modied Version. Page 275 c 2009 n + 1, Inc All Rights Reserved

APPENDIX N. Do not retitle any existing section to be Entitled Endorsements or to conict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modied Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modied Versions license notice. These titles must be distinct from any other section titles. You may add a section Entitled Endorsements, provided it contains nothing but endorsements of your Modied Version by various partiesfor example, statements of peer review or that the text has been approved by an organization as the authoritative denition of a standard. You may add a passage of up to ve words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modied Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modied Version.

5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms dened in section 4 above for modied versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodied, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but dierent contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled History in the various original documents, forming one section Entitled History; likewise combine any sections Entitled Acknowledgements, and any sections Entitled Dedications. You must delete all sections Entitled Endorsements.

6. COLLECTIONS OF DOCUMENTS
Page 276 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS


A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an aggregate if the copyright resulting from the compilation is not used to limit the legal rights of the compilations users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Documents Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

8. TRANSLATION
Translation is considered a kind of modication, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled Acknowledgements, Dedications, or History, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. Page 277 c 2009 n + 1, Inc All Rights Reserved

APPENDIX However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and nally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder noties you of the violation by some reasonable means, this is the rst time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

10. FUTURE REVISIONS OF THIS LICENSE


The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may dier in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document species that a particular numbered version of this License or any later version applies to it, you have the option of following the terms and conditions either of that specied version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document species that a proxy can decide which future versions of this License can be used, that proxys public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

11. RELICENSING
Massive Multiauthor Collaboration Site (or MMC Site) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A Massive Multiauthor Collaboration (or MMC) contained in the site means any set of copyrightable works thus published on the MMC site. CC-BY-SA means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-prot corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. Incorporate means to publish or republish a Document, in whole or in part, as part of another Document. Page 278 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING An MMC is eligible for relicensing if it is licensed under this License, and if all works that were rst published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents


To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright c YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the with . . . Texts. line with this:

with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

Page 279

c 2009 n + 1, Inc All Rights Reserved

Index
abstract, 132 abstract classes, 132 interfaces, 134 addition, 29 ArrayList, 169 arrays, 66 command line arguments, 70 multi-dimensional, 67 autoboxing, 147 Blob, 223 boolean, 24 break, 40 BueredInputStream, 197 BueredOutputStream, 197, 199 BueredReader, 201, 204 BueredWriter, 201 byte, 24 ByteArrayInputStream, 197 ByteArrayOutputStream, 197 Calendar, 152156 Calendar constants, 153, 154 CallableStatement, 216 case, 36 default, 36 catch, 183, 185, 197 char, 24, 25, 201 CharArrayReader, 201 CharArrayWriter, 201 class, 19 Class.forName(), 211 classes, 45 attributes, 47 dening, 51 encapsulation, 54 methods, 48 modiers, 48 variable scope, 49 CLASSPATH, 20 Clob, 223 code blocks, 34 Collection, 167, 169, 175, 207 collections, 167 data types, 168 lists, 169 looping, 171 maps, 177 sets, 175 command line arguments, 70 comments, 34 CONCUR READ ONLY, 220 CONCUR UPDATABLE, 220 conditionals, 35 case statement, 36 else, 35, 36 if, 35, 36 switch, 36 Connection, 213 constructors, 80, 81, 97 default, 83 overloading, 85 continue, 40 DataInputStream, 197 DataOutputStream, 197, 199 Date, 152, 160 sql, 223 date format characters, 160 default constructors, 83 design patterns, 131 DivideByZeroException, 29 division, 29 do, 38, 39 double, 24 DriverManager, 211 else, 35, 36, 192 280

JAVA WEB PROGRAMMING encapsulation, 52, 54 escape sequences, 25 Exception, 188190 exceptions custom exceptions, 188 order of execution, 189 returning from methods, 192 stack trace, 184 throwing, 186 throwing exceptions, 191 try/catch block, 183 try/catch/nally block, 183, 184 extends, 93, 119 FileInputStream, 197 FileNotFoundException, 189 FileOutputStream, 197, 199 FileReader, 201, 204 FileWriter, 201 nal, 113 nally, 183 oat, 24 for, 38, 39, 173, 174 Formatter, 157 formatting output, 157 garbage collection, 151 generics, 164166 HashMap, 178 HashSet, 175 i/o, see input/output if, 35, 36, 192 implements, 119 import, 102 inheritance, 92, 93 constructors, 97 extends, 93 overriding methods, 95 super, 96 input/output, 196 high level reader/writer methods, 202 high level reader/writers, 201 high level stream methods, 198 high level streams, 197 low level reader/writer methods, 201 low level reader/writers, 201 low level stream methods, 197 Page 281 low level streams, 197 readers and writers, 201 reading text to le, 203 serialization, 205 streams, 197 writing text to le, 201 InputStream, 197, 223 InputStreamReader, 201 int, 24 interfaces, 116 casting, 117 conversion, 117 design patterns, 131 implements, 119 polymorphism, 123 IOException, 189, 197, 199 Iterator, 171 J2EE, 16 J2ME, 16 J2SE, 16, 18 jar, 18 Java, 17 java, 18, 19 java data types, 24 Java Database Connecticity, 210 auto commit, 213 connection, 213 connection parameters, 211 database data types, 223 driver categories, 210 driver manager, 211 get connection, 211 isolation levels, 214 result sets, 219 concurrency, 219 scrollable types, 219 save points, 214 statements, 216 transactions, 213 java.lang, 142 java.lang.Math, 148 java.lang.Object, 143 java.lang.Runtime, 149 java.lang.System, 149 java.util.Scanner, 149 Java2 Enterprise Edition, 16 Java2 Micro Edition, 16 c 2009 n + 1, Inc All Rights Reserved

INDEX Java2 Standard Edition, 16, 18 javac, 18, 19 javadoc, 18 JDBC, see Java Database Connectivity LinkedList, 169 List, 169 long, 24 looping, 38 break, 40 continue, 40 do/while, 38, 39 for, 39 while, 38 Map, 177 Math, 148 Math methods, 148 methods, 74 constructors, 80 default constructors, 83 object parameters, 77 overloading, 75 overloading constructors, 85 parameters, 76 primitive parameters, 76 modiers, 48, 53, 104 access, 53, 105 nal, 113 static, 108 modulus, 29 multiplication, 29 NEGATIVE INFINITY, 29 new, 51, 81 NotSerializableException, 205, 207 Object, 143, 145, 146 Object methods, 143 ObjectInputStream, 197, 207 ObjectOutputStream, 197, 207 objects, 45, see classes operators, 28 arithmetic, 29 assignment, 33 comparison, 31 unary, 28 OutputStream, 197, 223 OutputStreamWriter, 201 Page 282 overloading constructor, 85 overloading methods, 75 package, 101 packages, 99 import, 102 import wild cards, 103 package, 101 pass by reference, 77 pass by value, 76 PATH, 20 PipedInputStream, 197 PipedOutputStream, 197 PipedReader, 201 PipedWriter, 201 polymorphism, 123 POSITIVE INFINITY, 29 PreparedStatement, 217, 218 PrintWriter, 201 private, 53, 105 protected, 105 public, 53, 105 Remote Method Invocation, 205 ResultSet, 219 RMI, 205 Runtime, 149 Scanner, 149 Serializable, 205207 Set, 175 short, 24 Statement, 216 static, 48, 108, 111 String, 60 equals(), 62 split(), 69 trim(), 64 StringReader, 201 strings, 60 converting to primitive, 65 immutable, 61 methods, 63 splitting, 69 testing equality, 62 trimming, 64 StringWriter, 201 subtraction, 29 super, 96, 98 c 2009 n + 1, Inc All Rights Reserved

JAVA WEB PROGRAMMING switch, 36 System, 149 System.out.format(), 157 System.out.println(), 149 this, 87 Throwable, 186, 188 throws, 192 Timestamp, 223 toString() method, 144 TRANSACTION NONE, 215 TRANSACTION READ COMMITTED, 215 TRANSACTION READ UNCOMMITTED, 215 TRANSACTION REPEATABLE READ, 215 TRANSACTION SERIALIZABLE, 215 TreeMap, 178 TreeSet, 175 try, 183, 185, 193, 197 TYPE FORWARD ONLY, 220 TYPE SCROLL INSENSITIVE, 220 TYPE SCROLL SENSITIVE, 220 variables, 26 conversion, 27 valid, 26 Vector, 168, 169 void, 48 while, 38, 39 wrapper classes, 65, 145

Page 283

c 2009 n + 1, Inc All Rights Reserved

Você também pode gostar