Академический Документы
Профессиональный Документы
Культура Документы
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
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Page 4
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 7.1.1 7.1.2 7.1.3 Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Interface Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Polymorphism and Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.2
7.3 Page 5
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
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
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
Page 8
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
List of Figures
4.1 Java Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11
LIST OF FIGURES
Page 12
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
Chapter 1
15
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
INTRODUCTION TO JAVA
Page 17
java javadoc
jar
Page 18
INTRODUCTION TO JAVA
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
Page 20
INTRODUCTION TO JAVA
Page 21
Page 22
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
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
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
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
INTRODUCTION TO JAVA
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
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
INTRODUCTION TO JAVA
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
INTRODUCTION TO JAVA
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
Page 34
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
Page 35
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
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.
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
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.
Page 38
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.
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
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
Page 39
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
INTRODUCTION TO JAVA
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
Chapter 3
43
1 C,
Page 44
INTRODUCTION TO JAVA
2 Physical
3 Conceptual
entities would included things like chairs, desks, etc entities would be things like a bank account, time, etc
Page 45
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
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
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
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
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
INTRODUCTION TO JAVA
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
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
INTRODUCTION TO JAVA
Page 53
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
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
INTRODUCTION TO JAVA
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
Chapter 4
59
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
INTRODUCTION TO JAVA
Page 61
Page 62
INTRODUCTION TO JAVA
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
Page 64
INTRODUCTION TO JAVA
2 Wrapper
classes are discussed in greater detail within the Utility Classes module.
Page 65
Page 66
INTRODUCTION TO JAVA
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
INTRODUCTION TO JAVA
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
Page 70
INTRODUCTION TO JAVA
Page 71
Page 72
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
Page 74
INTRODUCTION TO JAVA
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)
Page 75
CHAPTER 5. METHODS
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
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
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
INTRODUCTION TO JAVA
Page 81
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
INTRODUCTION TO JAVA
Page 83
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
INTRODUCTION TO JAVA
the use of the new statement to initialize the String object in this empty constructor. If this initialization of the
Page 85
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
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
INTRODUCTION TO JAVA
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
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
Page 92
INTRODUCTION TO JAVA
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
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
INTRODUCTION TO JAVA
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
CHAPTER 6. INHERITANCE
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
INTRODUCTION TO JAVA
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
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
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
CHAPTER 6. INHERITANCE
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
INTRODUCTION TO JAVA
Of course, the Account.java le must be located in the ./net/nplus1/account/ directory for compilation.
Page 101
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
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
CHAPTER 6. INHERITANCE
6.3 Modiers
Modiers provide a mechanism to associate special characteristics to classes, methods, and attributes.
Page 104
INTRODUCTION TO JAVA
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
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
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
CHAPTER 6. INHERITANCE
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
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
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
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
INTRODUCTION TO JAVA
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
CHAPTER 6. INHERITANCE
Chapter 7
115
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
INTRODUCTION TO JAVA
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
Page 118
INTRODUCTION TO JAVA
Page 119
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
INTRODUCTION TO JAVA
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
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
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
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
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
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
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
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
Page 131
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
Page 133
Page 134
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
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
INTRODUCTION TO JAVA
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
Page 140
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
Page 142
INTRODUCTION TO JAVA
Page 143
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
INTRODUCTION TO JAVA
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
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
Page 148
INTRODUCTION TO JAVA
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
INTRODUCTION TO JAVA
Page 151
1 deprecated
methods are methods that are no longer supposed to be used but are grandfathered in for backwards
compliance
Page 152
INTRODUCTION TO JAVA
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
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
INTRODUCTION TO JAVA
Page 157
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
INTRODUCTION TO JAVA
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
Page 162
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
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
CHAPTER 9. COLLECTIONS
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
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
INTRODUCTION TO JAVA
Page 171
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
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
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
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
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
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
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
CHAPTER 9. COLLECTIONS
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
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
Page 182
INTRODUCTION TO JAVA
Page 183
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
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
Page 186
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
Page 188
INTRODUCTION TO JAVA
Page 189
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
INTRODUCTION TO JAVA
Page 191
Page 192
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
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
Page 196
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
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
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
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
INTRODUCTION TO JAVA
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
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
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
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
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
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
Page 208
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
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
INTRODUCTION TO JAVA
Page 211
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
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
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
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
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
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
Page 219
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
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
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
INTRODUCTION TO JAVA
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
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
Lab Results
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
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
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
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
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
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
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
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
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
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
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
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
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
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
APPENDIX
A.5 Lab 6
Part 1 - Shape.java public class Shape { private String name; private int sides;
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
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
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
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
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
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
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
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
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
Page 252
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
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
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
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
Page 260
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
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
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
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
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
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
APPENDIX
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.
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.
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.
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.
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
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