P. 1


|Views: 500|Likes:
Published by Navneen Yadav

More info:

Published by: Navneen Yadav on Aug 27, 2010
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less






  • Chapter 1 : Java Technology
  • 1.1 History of Java
  • 1.2 What is Java?
  • 1.3 Versions of Java
  • 1.4 Code Compatibility
  • 1.5 Java 5.0 Improvements
  • 1.6 Features of Java
  • 1.7 Java Applets and Applications
  • 1.8 Why Java is important to Internet?
  • 1.9 The Java Platform
  • 1.10 What Can Java Technology Do?
  • 1.11 Writing a Program
  • 1.12 Compiling the Program
  • 1.13 Interpreting and Running the Program
  • 1.14 Comments in Java
  • 1.15 Application Structure and Elements
  • Summary
  • Chapter 2 : Data types, variables and Arrays
  • 2.1 Data Types
  • 2.2 Literals
  • 2.3 Java Character Encoding: UTF and Unicode
  • 2.4 EscapeSequences
  • 2.5 Rules for naming an identifier
  • 2.6 Java Language Keywords
  • 2.7 Variables
  • 2.8 Declaring constants – Final variables
  • 2.9 Arrays
  • 2.10 Multidimensional Arrays
  • 2.11 Copying Arrays
  • Questions
  • Chapter 3 : Operators
  • 3.1 Operands
  • 3.2 Operator
  • 3.2.1 Arithmetic Operators
  • 3.2.2 Increment and Decrement Operators
  • 3.2.3 Relational Operators
  • 3.2.4 Bitwise Operators
  • 3.2.5 Logical Operators
  • 3.2.6 Assignment Operators
  • 3.2.7 Ternary or Conditional operator
  • 3.2.8 The [ ] Operator
  • 3.2.9 The . Operator
  • 3.2.10 The () Operator
  • 3.2.11 The (type) Operator
  • 3.2.12 The new Operator
  • 3.2.13 The instanceof Operator
  • 3.3 Expressions
  • 3.4 Statements
  • 3.5 Operator Precedence
  • 3.6 Type Conversion and Casting
  • 3.7 Automatic Type Promotions
  • Chapter 4 : Control flow statements
  • 4.1 The while and do-while Statements
  • 4.2 The for Statement
  • 4.3 The if/else Statements
  • 4.4 The switch Statement
  • 4.5 Branching Statements
  • 4.5.1 The break Statement
  • 4.5.2 The continue Statement
  • 4.5.3 The return Statement
  • 4.6 Exception Handling Statements
  • Chapter 5 : Class Fundamentals and OOP
  • 5.1 What Is an Object?
  • 5.2 What Is a Class?
  • 5.3 What Is a Message?
  • 5.4 Features of Object Oriented Programming
  • 5.4.1 Encapsulation
  • 5.4.2 Inheritance
  • 5.4.3 Polymorphism
  • 5.4.4 Abstraction
  • 5.5 Defining Classes
  • 5.6 Creating Objects
  • 5.7 Defining Methods in a class
  • 5.8 Declaring Variables in a Class
  • 5.9 Instance and Class Members
  • 5.10 Static Initializer
  • 5.11 Variable Shadowing
  • 5.12 Pass by value and Pass by reference
  • 5.13 Access Control
  • 5.14 Constructors
  • 5.15 The this keyword
  • 5.16 Overloading
  • 5.17 Recursion
  • 5.18 Native Methods
  • 5.19 Arrays of Objects
  • 5.20 Nested and Inner Classes
  • 5.21 Command-Line Arguments
  • 5.22 Enumerated types
  • 5.23 Garbage Collection
  • Chapter 6 : Inheritance
  • 6.1 Inheritance Basics
  • 6.2 Understanding how Constructors are called
  • 6.3 Overriding Methods
  • 6.4 Dynamic Method Dispatch
  • 6.5 Annotations
  • 6.6 Hiding Member Variables
  • 6.7 Abstract Classes
  • 6.8 Abstract Methods
  • 6.9 Final Classes
  • 6.10 Final Methods
  • 6.11 Access control and Inheritance
  • 6.12 Anonymous Inner Class
  • 6.13 The Object class
  • Chapter 7 : Packages and Interfaces
  • 7.1 Packages
  • 7.2 Using package members
  • 7.3 Interfaces
  • 7.4 Static Import
  • 7.5 strictfp
  • Chapter 8 : Assertions and Exception handling
  • 8.1 What is an Exception?
  • 8.2 Types of Exceptions
  • 8.3 Catching and Handling Exceptions
  • 8.4 The throw Statement
  • 8.5 The throws Clause
  • 8.6 Overriding methods that throw exceptions
  • 8.7 Java’s built in exceptions
  • 8.8 Chained Exceptions
  • 8.9 Creating Your Own Exception Classes
  • 8.10 Assertions
  • Chapter 9 : Multithreaded programming
  • 9.1 Multitasking
  • 9.2 What Is a Thread?
  • 9.3 The Thread class
  • 9.4 Using the main thread
  • 9.5 Creating a thread
  • 9.6 The Java Thread Model
  • 9.7 Thread priority
  • 9.8 Using the Thread yield method
  • 9.9 Stopping a Thread
  • 9.10 Determining When a Thread Has Finished
  • 9.11 Thread Scheduling
  • 9.12 Thread Synchronization
  • 9.13 Interthread Communication
  • 9.14 Starvation and Deadlock
  • 9.15 Suspending, Resuming & Stopping Threads
  • 9.16 ThreadGroup
  • Chapter 10 : String Handling
  • 10.1 The String class
  • 10.2 The StringBuffer Class
  • 10.3 The StringBuilder class
  • Chapter 11 : I/O
  • 11.1 I/O Streams
  • 11.2 Reading console input
  • 11.3 Writing console output
  • 11.4 System.out.printf()
  • 11.5 File class
  • 11.6 Using File Streams
  • 11.7 Scanning text with java.util.Scanner
  • 11.8 Redirecting Standard I/O
  • 11.9 Working with Random Access Files
  • 11.10 Filter Streams
  • 11.11 Object Serialization
  • Chapter 12 : API classes in java.lang package
  • 12.1 Wrapper classes
  • 12.2 Autoboxing/Unboxing of Wrappers
  • 12.3 Math class
  • 12.4 System class
  • 12.5 Runtime class
  • 12.6 Class class
  • Chapter 13 : Utility & Legacy classes
  • 13.1 Enumeration interface
  • 13.2 Vector class
  • 13.3 Stack class
  • 13.4 Dictionary class
  • 13.5 Hashtable class
  • 13.6 Properties class
  • 13.7 Formatter class
  • 13.8 Date class
  • 13.9 Calendar class
  • 13.10 GregorianCalendar class
  • 13.11 TimeZone and SimpleTimeZone classes
  • 13.12 Locale class
  • 13.13 StringTokenizer class
  • 13.14 StreamTokenizer class
  • 13.15 Random class
  • 13.16 BitSet class
  • 13.17 Timer and TimerTask classes
  • 13.18 Observable class
  • 13.19 Currency class
  • Chapter 14 : Regular Expression Processing
  • 14.1 What is a Regular Expression?
  • 14.2 Pattern class
  • 14.3 Matcher class
  • 14.4 String Class RegEx Methods
  • Chapter 15 : API classes in java.text
  • 15.1 DateFormat class
  • 15.2 SimpleDateFormat class
  • 15.3 DateFormatSymbols class
  • 15.4 NumberFormat class
  • 15.5 DecimalFormat class
  • 15.6 Format class
  • Chapter 16 : Collections Framework and Generics
  • 16.1 What is a Collection?
  • 16.2 Generics
  • 16.3 What Is a Collections Framework?
  • 16.4 Collection Interfaces
  • 16.5 The Collection Interface
  • 16.6 The Set Interface
  • 16.7 The List Interface
  • 16.8 The Queue Interface
  • 16.9 The Map Interface
  • 16.10 Object Ordering
  • 16.11 The SortedSet Interface
  • 16.12 The SortedMap Interface
  • 16.13 Relationships Among Generics
  • 16.14 Wildcard Types
  • 16.15 Defining and Using Generic Methods
  • Answers
  • Chapter 2
  • Chapter 3
  • Chapter 4
  • Chapter 5
  • Chapter 6
  • Chapter 7
  • Chapter 8
  • Chapter 10
  • Chapter 12


Index................................................................................................................................................1 Chapter 1 : Java Technology........................................................................................................7 1.1 History of Java...................................................................................................................7 1.2 What is Java?.....................................................................................................................8 1.3 Versions of Java.................................................................................................................8 1.4 Code Compatibility..........................................................................................................10 1.5 Java 5.0 Improvements....................................................................................................11 1.6 Features of Java................................................................................................................12 1.7 Java Applets and Applications.........................................................................................14 1.8 Why Java is important to Internet?..................................................................................14 1.9 The Java Platform............................................................................................................15 1.10 What Can Java Technology Do? ...................................................................................16 1.11 Writing a Program..........................................................................................................16 1.12 Compiling the Program..................................................................................................17 1.13 Interpreting and Running the Program..........................................................................17 1.14 Comments in Java..........................................................................................................17 1.15 Application Structure and Elements..............................................................................18 Summary ...............................................................................................................................19 Chapter 2 : Data types, variables and Arrays...........................................................................20 2.1 Data Types ......................................................................................................................20 2.2 Literals.............................................................................................................................21 2.3 Java Character Encoding: UTF and Unicode...................................................................21 2.4 EscapeSequences.............................................................................................................22 2.5 Rules for naming an identifier.........................................................................................22 2.6 Java Language Keywords ...............................................................................................23 2.7 Variables .........................................................................................................................23 2.8 Declaring constants – Final variables..............................................................................24 2.9 Arrays...............................................................................................................................24 2.10 Multidimensional Arrays...............................................................................................26 2.11 Copying Arrays .............................................................................................................27 Summary................................................................................................................................28 Questions................................................................................................................................29 Chapter 3 : Operators.................................................................................................................33 3.1 Operands..........................................................................................................................33 3.2 Operator ..........................................................................................................................33 3.2.1 Arithmetic Operators ...................................................................................................34 3.2.2 Increment and Decrement Operators............................................................................36 3.2.3 Relational Operators.....................................................................................................36 3.2.4 Bitwise Operators .........................................................................................................38


3.2.5 Logical Operators .........................................................................................................40 3.2.6 Assignment Operators ..................................................................................................43 3.2.7 Ternary or Conditional operator...................................................................................44 3.2.8 The [ ] Operator............................................................................................................45 3.2.9 The . Operator..............................................................................................................45 3.2.10 The () Operator...........................................................................................................45 3.2.11 The (type) Operator.....................................................................................................46 3.2.12 The new Operator.......................................................................................................46 3.2.13 The instanceof Operator..............................................................................................46 3.3 Expressions......................................................................................................................46 3.4 Statements........................................................................................................................46 3.5 Operator Precedence........................................................................................................47 3.6 Type Conversion and Casting..........................................................................................49 3.7 Automatic Type Promotions............................................................................................52 Summary................................................................................................................................53 Questions................................................................................................................................53 Chapter 4 : Control flow statements..........................................................................................57 4.1 The while and do-while Statements ................................................................................57 4.2 The for Statement ............................................................................................................58 4.3 The if/else Statements .....................................................................................................60 4.4 The switch Statement ......................................................................................................63 4.5 Branching Statements......................................................................................................65 4.5.1 The break Statement.....................................................................................................65 4.5.2 The continue Statement.................................................................................................66 4.5.3 The return Statement.....................................................................................................68 4.6 Exception Handling Statements ......................................................................................68 Summary................................................................................................................................69 Questions................................................................................................................................69 Chapter 5 : Class Fundamentals and OOP...............................................................................73 5.1 What Is an Object? ..........................................................................................................73 5.2 What Is a Class? ..............................................................................................................74 5.3 What Is a Message?.........................................................................................................74 5.4 Features of Object Oriented Programming .....................................................................75 5.4.1 Encapsulation ...............................................................................................................75 5.4.2 Inheritance.....................................................................................................................76 5.4.3 Polymorphism...............................................................................................................77 5.4.4 Abstraction....................................................................................................................78 5.5 Defining Classes .............................................................................................................78 5.6 Creating Objects...............................................................................................................78 5.7 Defining Methods in a class.............................................................................................79 5.8 Declaring Variables in a Class.........................................................................................84 5.9 Instance and Class Members............................................................................................87 5.10 Static Initializer..............................................................................................................92 5.11 Variable Shadowing.......................................................................................................93 2

5.12 Pass by value and Pass by reference..............................................................................94 5.13 Access Control...............................................................................................................97 5.14 Constructors.................................................................................................................101 5.15 The this keyword..........................................................................................................103 5.16 Overloading..................................................................................................................103 5.17 Recursion.....................................................................................................................106 5.18 Native Methods............................................................................................................107 5.19 Arrays of Objects ........................................................................................................107 5.20 Nested and Inner Classes ............................................................................................108 5.21 Command-Line Arguments ........................................................................................113 5.22 Enumerated types.........................................................................................................114 5.23 Garbage Collection......................................................................................................117 Summary..............................................................................................................................118 Questions..............................................................................................................................119 Chapter 6 : Inheritance.............................................................................................................128 6.1 Inheritance Basics..........................................................................................................128 6.2 Understanding how Constructors are called..................................................................131 6.3 Overriding Methods ......................................................................................................135 6.4 Dynamic Method Dispatch............................................................................................139 6.5 Annotations ...................................................................................................................140 6.6 Hiding Member Variables..............................................................................................142 6.7 Abstract Classes.............................................................................................................143 6.8 Abstract Methods...........................................................................................................144 6.9 Final Classes..................................................................................................................146 6.10 Final Methods..............................................................................................................148 6.11 Access control and Inheritance....................................................................................149 6.12 Anonymous Inner Class...............................................................................................149 6.13 The Object class ..........................................................................................................151 Summary..............................................................................................................................154 Questions..............................................................................................................................155 Chapter 7 : Packages and Interfaces........................................................................................158 7.1 Packages ........................................................................................................................158 7.2 Using package members................................................................................................161 7.3 Interfaces .......................................................................................................................164 7.4 Static Import ..................................................................................................................169 7.5 strictfp............................................................................................................................171 Summary..............................................................................................................................172 Questions..............................................................................................................................172 Chapter 8 : Assertions and Exception handling.....................................................................175 8.1 What is an Exception? ..................................................................................................175 8.2 Types of Exceptions.......................................................................................................180 8.3 Catching and Handling Exceptions ...............................................................................182 8.4 The throw Statement .....................................................................................................187 3

8.5 The throws Clause..........................................................................................................189 8.6 Overriding methods that throw exceptions....................................................................190 8.7 Java’s built in exceptions...............................................................................................191 8.8 Chained Exceptions ......................................................................................................195 8.9 Creating Your Own Exception Classes .........................................................................198 8.10 Assertions.....................................................................................................................200 Summary..............................................................................................................................203 Questions..............................................................................................................................203 Chapter 9 : Multithreaded programming...............................................................................206 9.1 Multitasking...................................................................................................................206 9.2 What Is a Thread? .........................................................................................................206 9.3 The Thread class............................................................................................................209 9.4 Using the main thread....................................................................................................210 9.5 Creating a thread............................................................................................................211 9.6 The Java Thread Model.................................................................................................213 9.7 Thread priority...............................................................................................................215 9.8 Using the Thread yield method......................................................................................217 9.9 Stopping a Thread..........................................................................................................218 9.10 Determining When a Thread Has Finished..................................................................219 9.11 Thread Scheduling ......................................................................................................220 9.12 Thread Synchronization...............................................................................................222 9.13 Interthread Communication.........................................................................................229 9.14 Starvation and Deadlock .............................................................................................232 9.15 Suspending, Resuming & Stopping Threads ..............................................................232 9.16 ThreadGroup................................................................................................................235 Summary..............................................................................................................................236 Chapter 10 : String Handling...................................................................................................237 10.1 The String class............................................................................................................237 10.2 The StringBuffer Class................................................................................................248 10.3 The StringBuilder class................................................................................................257 Questions..............................................................................................................................257 Chapter 11 : I/O.........................................................................................................................259 11.1 I/O Streams .................................................................................................................259 11.2 Reading console input..................................................................................................265 11.3 Writing console output.................................................................................................266 11.4 System.out.printf().......................................................................................................267 11.5 File class.......................................................................................................................270 11.6 Using File Streams.......................................................................................................274 11.7 Scanning text with java.util.Scanner............................................................................278 11.8 Redirecting Standard I/O.............................................................................................281 11.9 Working with Random Access Files ...........................................................................282 11.10 Filter Streams.............................................................................................................284 11.11 Object Serialization ...................................................................................................287 4

Summary..............................................................................................................................291 Chapter 12 : API classes in java.lang package........................................................................292 12.1 Wrapper classes...........................................................................................................292 12.2 Autoboxing/Unboxing of Wrappers............................................................................297 12.3 Math class....................................................................................................................299 12.4 System class.................................................................................................................306 12.5 Runtime class...............................................................................................................308 12.6 Class class....................................................................................................................310 Summary..............................................................................................................................310 Questions..............................................................................................................................311 Chapter 13 : Utility & Legacy classes......................................................................................314 13.1 Enumeration interface .................................................................................................314 13.2 Vector class..................................................................................................................314 13.3 Stack class....................................................................................................................316 13.4 Dictionary class............................................................................................................318 13.5 Hashtable class.............................................................................................................318 13.6 Properties class.............................................................................................................319 13.7 Formatter class.............................................................................................................321 13.8 Date class.....................................................................................................................323 13.9 Calendar class..............................................................................................................324 13.10 GregorianCalendar class............................................................................................325 13.11 TimeZone and SimpleTimeZone classes...................................................................326 13.12 Locale class................................................................................................................328 13.13 StringTokenizer class.................................................................................................329 13.14 StreamTokenizer class...............................................................................................332 13.15 Random class.............................................................................................................334 13.16 BitSet class.................................................................................................................335 13.17 Timer and TimerTask classes....................................................................................335 13.18 Observable class ........................................................................................................337 13.19 Currency class............................................................................................................339 Chapter 14 : Regular Expression Processing..........................................................................340 14.1 What is a Regular Expression?....................................................................................340 14.2 Pattern class.................................................................................................................342 14.3 Matcher class...............................................................................................................342 14.4 String Class RegEx Methods.......................................................................................345 Chapter 15 : API classes in java.text........................................................................................346 15.1 DateFormat class..........................................................................................................346 15.2 SimpleDateFormat class..............................................................................................348 15.3 DateFormatSymbols class............................................................................................350 15.4 NumberFormat class....................................................................................................351 15.5 DecimalFormat class....................................................................................................353


15.6 Format class.................................................................................................................355 Summary..............................................................................................................................357 Chapter 16 : Collections Framework and Generics...............................................................358 16.1 What is a Collection?...................................................................................................358 16.2 Generics.......................................................................................................................358 16.3 What Is a Collections Framework?..............................................................................360 16.4 Collection Interfaces ...................................................................................................361 16.5 The Collection Interface .............................................................................................362 16.6 The Set Interface..........................................................................................................367 16.7 The List Interface ........................................................................................................371 16.8 The Queue Interface.....................................................................................................381 16.9 The Map Interface .......................................................................................................383 16.10 Object Ordering ........................................................................................................388 16.11 The SortedSet Interface..............................................................................................395 16.12 The SortedMap Interface...........................................................................................398 16.13 Relationships Among Generics .................................................................................398 16.14 Wildcard Types .........................................................................................................399 16.15 Defining and Using Generic Methods ......................................................................400 Answers.......................................................................................................................................402 Chapter 2..............................................................................................................................402 Chapter 3..............................................................................................................................403 Chapter 4..............................................................................................................................404 Chapter 5..............................................................................................................................405 Chapter 6..............................................................................................................................408 Chapter 7..............................................................................................................................410 Chapter 8..............................................................................................................................410 Chapter 10............................................................................................................................411 Chapter 12 ...........................................................................................................................411


Chapter 1 : Java Technology
1.1 History of Java
Around 1990 James Gosling , Bill Joy and others at Sun Microsystems began developing a language called Oak. They wanted it primarily to control microprocessors embedded in consumer items such as cable set-top boxes,VCR's, toasters, and also for personal data assistants (PDA). To serve these goals, Oak needed to be:
o o o

Platform independent (since multiple manufacturers involved) Extremely reliable Compact.

However, as of 1993, interactive TV and PDA markets had failed to take off. Then the Internet and Web explosion began, so Sun shifted the target market to Internet applications and changed the name of the project to Java. By 1994 Sun's HotJava browser appeared. Written in Java in only a few months, it illustrated the power of applets, programs that run within a browser, and also the capabilities of Java for speeding program development. Riding along with the explosion of interest and publicity in the Internet, Java quickly received widespread recognition and expectations grew for it to become the dominant software for browser and consumer applications. However, the early versions of Java did not possess the breadth and depth of capabilities needed for client (i.e. consumer) applications. For example, the graphics in Java 1.0 seemed crude and clumsy compared to mature software developed with C and other languages. Applets became popular and remain common but don't dominate interactive or multimedia displays on web pages. Many other "plug-in" types of programs also run within the browser environment. So Java has not succeeded at development of consumer applications. However, Java's capabilities grew with the release of new and expanded versions and it became a very popular language for development of enterprise, or middleware, applications such as on line web stores, transactions processing, database interfaces, and so forth. Java has also become quite common on small platforms such as cell phones and PDAs. Java is now used in several hundred cell phone models. Over 600 million JavaCards, smart cards with additional features provided by Java, have been sold as of the summer of 2004.


1.2 What is Java?
The term Java actual refers to more than just a particular language like C or Pascal. Java encompasses several parts, including :

A high level language – the Java language is a high level one that at a glance looks very similar to C and C++ but offers many unique features of its own. Java bytecode - a compiler, Sun's javac, transforms the Java language source code to bytecode that runs in the JVM. Java Virtual Machine (JVM) – a program, such as Sun's java, that runs on a given platform and takes the bytecode programs as input and interprets them just as if it were a physical processor executing machine code.

Sun provides a set of programming tools such as javac, java and others in a bundle that it calls a Java Software Development Kit for each version of the language and for different platforms such as Windows, Linux, etc.. Sun also provides a runtime bundle with just the JVM when the programming tools are not needed. Note that because of the open nature of Java any or all of these parts can be replaced by non-Sun components. For example, just as many different languages can create machine code for a given processor, compilers of other languages have been created that output bytecode to run in the JVM. Similarly, many JVMs have been written by groups outside of Sun. Java, Open or Closed? Java is not quite an open language but not quite a proprietary one either. All the core language products - compiler, virtual machines (VM), class packages, and other components - are free. Detailed specifications and source code are made openly available. The Java Community Process (JCP) leads the development of new standards for the language. Other companies and organizations can legally create a clean sheet compiler and/or a Virtual Machine as long as it follows the publicly available specifications. Microsoft did this with the Version 1.1 JVM that it used in its Internet Explorer browser. Sun, however, does still assert final say on the specifications and controls the copyrights to logos, and trademarks.

1.3 Versions of Java
Since its introduction, Sun has released a new version of the Java language every two years or so. These new versions brought enhancements, new capabilities and fixes to bugs. Until recently, the versions were numbered 1.x, where x reached up till 4. (Intermediate revisions were labeled with a third number - 1.x.y - as in 1.4.2.) The newest version, however, is called Java 5.0 rather than Java 1.5.


1842 classes o Performance enhancements including the Hotspot virtual machine. or editions. of Java.0 included Java 1. inner classes. This edition contains the core language packages (the name for code libraries in Java) and is aimed for desktop programming. compatible Java Virtual Machine for the Internet Explorer.2.3: o 76 packages .0-4. 2004: Version 5. o Many browsers in use are still compatible only with 1.1.504 classes o Improvements include better event handling. 2002: Version 1.2991 classes o Improved IO. One is aimed at small.1520 classes o Code and tools distributed as The Software Development Kit (SDK) o Java Foundation Classes (JFC). 1999: Version 1. XML support. of Java along with some of the new features that each one introduced.1. embedded applications and the other for large scale middleware applications: Micro Java 9 . improved JVM. sets. over 3000 classes o Faster startup and smaller memory footprint o Metadata o Formatted output o Generics o Improved multithreading features • • • • • Other Editions of Java In the late 1990s. 2000: Version 1.0 of the Java Development Kit (JDK) was released for free by Sun.4: o 135 packages .0 (previously numbered 1.5): o 165 packages. also called the Java 2 Platform o 59 packages . for improved graphics and user interfaces. now included with the core language. etc.0.Below is a timeline of the different versions of the basic. and hash maps. o Microsoft and other companies licensed Java. o Swing packages of greatly improved graphics became available during this time but not included with the core language. or Standard Edition (SE). • 1995: Version 1.1: o 23 packages . 1997: Version 1. based on Swing. o Collections API included support for various lists. o 8 packages with 212 classes o Netscape 2. o Microsoft developed its own 1. Sun split off two other more specialized branches.

classes and even methods in the core language can be thrown out to make room.Java 2 Platform. For such systems Sun offers slimmed down versions of Java. however. It also usually means a smaller display or perhaps no display at all.1 for 32 bit system with about 512kb each for ROM and RAM. such as the event handling system introduced in Java 1.1. Micro Edition (J2ME) . PersonalJava . you can just use the latest version . the newer versions maintain compatibilty with older code. Also. online storefronts.   J2EE . Generally.) 10 .   JavaCard .4 Code Compatibility Sun has maintained good compatibility among codes written with the different versions. For this course.0 . (In some cases.based on the Java 2 Platform. 1.based on Java 1. The approach has been to add new features without subtracting any older features. terms change such as Java Development Kit becoming Software Development Kit.extremely limited Java for systems with only 16kb nonvolatile memory and 512 bytes volatile EmbeddedJava . The developer will choose from different configurations to suit the capacity of a given system.8 for larger systems with 2MB ROM and more than 1MB RAM. Individual packages.Java 5.1 based systems (EmbeddedJava and PersonalJava but not JavaCard). code using newer classes and techniques should not be mixed in the same program with older version code. J2ME replaces the Java 1.based on Java 1.Embedded systems such as cell phones and device controllers typically offer reduced resources as compared to desktop PCs. and less of other types of nonvolatile memory. Enterprise Edition With the Java 2 Platform came a separate version with enhanced resources targeted at enterprise applications. This means substantially less disk space or no disk at all. and other services.1.and not worry about all these historical issues. Java 2 Platform. The Java 2 Enterprise Edition now provides a wide array of tools for building middleware software such as for database access applications. Naming Conventions All of these editions and version numbers can be a bit confusing for newcomers.

Stability. A program written according to Java 1.0.0 is the most tested release ever. For example. With a few important exceptions.5 Java 5. especially any code that worked with earlier versions of Java but failed under 5. thus producing fewer runtime errors. code that is repeated frequently) to do it. Java maintains backwards compatibility. it just sometimes took a lot more boilerplate code (i. making coding faster and more error free.0 will compile with a Java 5 compiler. Some features enable improved compile-time type checking. The most important changes to the platform include the following: Quality. Many of these features are built right in to the system. Release 5. and you can add additional monitoring and managing features to your own code. the new EoD features are all about syntax shortcuts that greatly reduce the amount of code that must be entered. stability. Ease of Development It is in the EoD area that the most significant changes appear. 2004.0 compiler will still run in a Java 5 virtual machine. Monitoring and Manageability The 5. The Sun engineers made a public plea for users worldwide to test their code with the 5. In most cases. These have been achieved through careful tuning of the software and use of class data sharing.0) was launched as the official Java version by Sun on September 30. 1. and Compatibility The designers of J2SE considered quality. Most of the changes fall into the ease of development (EoD) category.0 Improvements Java 2 Platform. The exception to this general statement has to do with the new multithreading and concurrency features that provide capabilities previously unavailable. the changes do not add new functionality but rather provide an easier way of doing the same things you could do before but with less code and better compiler-time error detection.0 release includes the ability to remotely monitor and even manage a running Java application.e. it is now much easier to watch memory usage and detect and respond to a low-memory condition. In many cases.4. 11 . (Though some obsolete methods will generate "deprecation" warning messages from the compiler. Great efforts were made to ensure compatibility with previous versions of Java. and compatibility to be the most important aspect of the new release. no new functionality was added in the sense that almost anything you can do with 5.0 (J2SE 5.0 Beta releases and to report any problems that appeared.Thus far.) The bytecode from a Java 1. Standard Edition 5.0 you could do with 1. Performance and Scalability Faster JVM startup time and smaller memory footprint were important goals.

there is a new. and a new easy-to-customize skinnable look and feel called Synth in which you can use XML configuration files to specify the appearance of every visual component in the system. The Java programming language is unusual in that a program is both compiled and interpreted. the GTK and XP look and feels introduced in J2SE 1. you either compile or interpret a program so that you can run it on your computer.2 have received further improvements. highcompression format for JAR files that can greatly reduce download times for applets and other networked applications. 12 . 1. improvements to Java's database connectivity package known as JDBC.0 include core XML support. There is support for OpenGL and better performance on Unix X11 platforms.6 Features of Java The Java programming language is a high-level language that can be characterized by all of the following buzzwords:  Simple  Object oriented  Distributed  Interpreted  Robust  Secure  Architecture neutral  Portable  High performance  Multithreaded  Dynamic With most programming languages. improvements to Unicode. The following figure illustrates how this works. In addition. Compilation happens just once.Improved Desktop Client The last great theme of the 5. improved Swing look and feel called Ocean. first you translate a program into an intermediate language called Java bytecodes —the platform-independent codes interpreted by the interpreter on the Java platform. Other new features in J2SE 5. and an improved. In addition to better performance because of a faster startup time and smaller memory footprint.4. The Java Web Start and Java Plug-In technologies (both used to run Java applications downloaded over the Web) have been improved.0 release was an improved experience on the desktop client. With the compiler. interpretation occurs each time the program is executed. The interpreter parses and runs each Java bytecode instruction on the computer.

The Java runtime system comes with an elegant yet sophisticated 13 . run anywhere" possible. or on an iMac. whether it's a development tool or a Web browser that can run applets. a Solaris workstation. Java frees you from having to worry about many of the most common causes of programming errors. is an implementation of the Java VM. It also checks the code at run-time. because Java provide Garbage Collection for unused objects. Because Java is a strictly typed language. You can compile your program into bytecodes on any platform that has a Java compiler. In fact. The bytecodes can then be run on any implementation of the Java VM.You can think of Java bytecodes as the machine code instructions for the Java Virtual Machine (Java VM). That means that as long as a computer has a Java VM. Java supports multithreaded programming which allows you to write programs that do many things simultaneously. Java bytecodes help make "write once. Every Java interpreter. Java was designed to be easy for the professional programmer to learn and use effectively. the same program written in the Java programming language can run on Windows 2000. Java virtually eliminates the memory access by managing memory allocation and deallocation. deallocation is completely automatic. it checks your code at compile-time.

you can safely download Java applets without fear of viral infection or malicious intent. soon they'll be able to access tailored applications from a mobile phone based on the Java platform. Another specialized program is a servlet. replacing the use of CGI scripts.7 Java Applets and Applications The most common types of programs written in the Java programming language are applets and applications. An applet is a program that adheres to certain conventions that allow it to run within a Java-enabled browser. Examples of servers are Web servers. e. Java supports dynamic programming where small fragments of bytecode may be dynamically updated on a running system. users can securely access their personal information and applications when they're far away from the office by using any computer that's connected to the Internet. A special kind of application known as a server serves and supports clients on a network. For example. and print servers. Another reason why Java is important to Internet is due to its portability i. 14 . mail servers. Java is designed for the distributed environment of the Internet. Operating system upgrades. Java Servlets are a popular choice for building interactive web applications. processor upgrades and changes in core system resources can all combine to make a program malfunction. configuring or tailoring the server. An applet is an application designed to be transmitted over the Internet and executed by a Java-compatible Web browser. or even use smart cards as a pass key to everything from the cash machine to ski lifts. thus making Java architecture neutral. When you use a Java-compatible web browser. Accessing a resource using a URL is not much different from accessing a file. the Java platform is helping computer users to do things that were previously unimaginable. 1. With Java technology. because it handles TCP/IP protocols. The Java designers made several hard decisions in the Java language and Java Virtual Machine in an attempt to alter this situation. Servlets are similar to applets in that they are runtime extensions of applications. Java achieves this protection by confining a Java program to the Java execution environment and not allowing it access to other parts of the computer.solution for multiprocess synchronization that enables you to construct smoothly running interactive systems. A servlet can almost be thought of as an applet that runs on the server side. the Internet and private networks become your computing environment. proxy servers. 1. Write once run anywhere feature. though. Coupled with the power of networking.8 Why Java is important to Internet? Java provides a firewall between a networked application and your computer. servlets run within Java Web servers. Instead of working in browsers. An application is a standalone program that runs directly on the Java platform.

1.Why Java technology? Networks require software that is portable.9 The Java Platform A Java platform is the software environment in which a program runs.all areas where Java technology shines. and secure -. and speeds software development. The Java API is a large collection of ready-made software components that provide many useful capabilities. As the figure shows. at work and on the road. Businesses are using Java technology because it connects easily to existing computing systems. 15 . The Java compiler and interpreter are case-sensitive. The Java platform has two components: • • The Java Virtual Machine (Java VM) The Java Application Programming Interface (Java API) The compiler. because it was designed for use on networks from the beginning. This interpreter takes your bytecode file and carries out the instructions by translating them into instructions that your computer can understand. such as graphical user interface (GUI) widgets. The compiler converts these instructions into a bytecode file. And consumers benefit from Java technology because it brings personal. The Java API is grouped into libraries of related classes and interfaces. business. and entertainment services to them -. modular.easily and securely -. It also lets businesses use the Internet to securely connect to their customers. The following figure depicts a program that's running on the Java platform. The Java interpreter installed on your computer implements the Java VM. the Java API and the virtual machine insulate the program from the hardware. javac. suppliers and partners. takes your source file and translates its text into instructions that the Java Virtual Machine (Java VM) can understand.in many locations and on many different kinds of appliances and devices at home. these libraries are known as packages. lowers computing costs.

Internationalization: Help for writing programs that can be localized for users worldwide. so if you type the code in yourself. telephony. numbers. access control. input and output. //A Very Simple Example class ExampleProgram { public static void main(String[] args){ System. the compiled code runs on a specific hardware platform. including electronic signatures. As a platform-independent environment. system properties. } 16 .Native code is code that after you compile it. accessibility.out. and be sure to name the text file ExampleProgram. Java programs are case sensitive. data structures. public and private key management. Security: Both low level and high level. smart compilers.println("I'm a Simple Program").11 Writing a Program The easiest way to write a simple program is with a text editor. the Java platform core classes.10 What Can Java Technology Do? Every full implementation of the Java platform gives you the following features: • • • • • • • • The essentials: Objects. 1. date and time. can plug into existing component architectures. Java Database Connectivity (JDBCTM): Provides uniform access to a wide range of relational databases. pay particular attention to the capitalization. Applets: The set of conventions used by applets. and just-in-time bytecode compilers can bring performance close to that of native code without threatening portability. Object serialization: Allows lightweight persistence and communication via Remote Method Invocation (RMI). 1. servers. However. Applications are standalone programs. Software components: Known as JavaBeansTM. Networking: URLs. Programs can automatically adapt to specific locales and be displayed in the appropriate language.java. Java 2 Runtime Environment (JRE) consists of the virtual machine. and so on. The Java platform also has APIs for 2D and 3D graphics. strings. and more. and supporting files. and IP (Internet Protocol) addresses. The Java 2 SDK includes the JRE and development tools such as compilers and debuggers. create a text file with the following text. the Java platform can be a bit slower than native code. using the text editor of your choice. speech. UDP (User Datagram Protocol) sockets. TCP (Transmission Control Protocol). well-tuned interpreters. threads. So. and certificates. collaboration. animation.

} } 17 . which converts the Java byte codes to platformdependent machine codes so your computer can understand and run the program. to comment-out lines of code to isolate the source of a problem for debugging purposes.out.14 Comments in Java Code comments are placed in source files to describe what is happening in the code to someone who might be reading the file.13 Interpreting and Running the Program Once your program successfully compiles into Java bytecodes.12 Compiling the Program A program has to be converted to a form the Java VM can understand so any computer with a Java VM can interpret and run the program The Java compiler is invoked at the command line on Unix and DOS shell operating systems as follows: javac ExampleProgram.java 1. Interpreting and running a Java program means invoking the Java VM byte code interpreter. //A Very Simple Example class ExampleProgram { public static void main(String[] args){ System. you should see: I'm a Simple Program 1. and doc comments.} 1. and tell the compiler to treat everything from the slashes to the end of the line as text. you can interpret and run applications on any Java VM. To these ends. the Java language supports three kinds of comments: double slashes. The Java interpreter is invoked at the command line on Unix and DOS shell operating systems as follows: java ExampleProgram At the command line. or interpret and run applets in any Web browser with a Java VM built in such as Netscape or Internet Explorer. C-style. or to generate API documentation.println("I'm a Simple Program"). Double Slashes Double slashes (//) are used in the C/C++ programming language.

*/ class ExampleProgram { public static void main(String[] args){ System.println("I'm a Simple Program"). Methods that work on the data are called accessor methods. a very simple class might store a string of text and define one method to set the string and another method to get the string and print it to the console. So you could.15 Application Structure and Elements An application is created from classes.out. A class is similar to a RECORD in the Pascal language or a struct in the C language in that it stores related data in fields. for example. API documentation makes sense when you have an application made up of a number of complex classes that need documentation. /* These are C-style comments */ class ExampleProgram { public static void main(String[] args){ System. an integer in another field. } } Doc Comments To generate documentation for your program. 18 . store a text string in one field. 1. The javadoc tool locates the doc comments embedded in source files and uses those comments to generate API documentation. This class is the entry point for the program. The difference between a class and a RECORD or struct is that a class also defines the methods to work on the data. you can use C-style comments (/* */) to enclose one or more lines of code to be treated as text.println("I'm a Simple Program"). there is no reason to generate API documentation.C-Style Comments Instead of double slashes.out. use the doc comments (/** */) to enclose lines of text for the javadoc tool to find. and a floating point in a third field. where the fields can be different types. The tool generates HTML files (Web pages) that describe the class structures and contain the text enclosed by doc comments. Every application needs one class with a main method. } } With one simple class. /** This class displays a text string at * the console. and is the class name passed to the java interpreter command to run the application. For example.

The code in the main method executes first when the program starts. 19 . It can be used for embedded as well as mobile applications. but because it is the only class in the program. Java is not only a programming language it’s a platform. and is the control point from which the controller class accessor methods are called to work on the data. Java is important because of its cross-platform functionality. it has a main method. and the program does not return data to the Java VM interpreter (void) when it ends. Summary In this chapter you learnt the history of Java and how the Java language has evolved. It has no fields or accessor methods. Also Java is a secure language. Java can be used for simple as well as complex applications. The public static void keywords mean the Java virtual machine (JVM) interpreter can call the program's main method to start the program (public) without creating an instance of the class (static).

is a reference to (an address of) the value or set of values represented by the variable. Min. The Java programming language does not support the explicit use of addresses like other languages do. A reference is called a pointer. classes. a character. Primitive Data Types Keyword byte short int long float double char boolean Description (integers) Byte-length integer Short integer Integer Long integer (real numbers) Single-precision floating point Double-precision floating point (other types) A single character A boolean value (true or false) Size/Format 8-bit two's complement 16-bit two's complement 32-bit two's complement 64-bit two's complement 32-bit IEEE 754 64-bit IEEE 754 16-bit Unicode character true or false You can put a literal primitive value directly in your code. in contrast to that of a primitive type.1 Data Types The Java programming language has two categories of data types: primitive and reference. You use the variable's name instead. Range of primitive data types Primitive Type Size Range of Values byte 8 bit -27 to 27-1 short 16 bit -215 to 215-1 int 32 bit -231 to 231-1 long 64 bit -263 to 263-1 char 16 bit '\u0000' to '\uffff'(0 to 216-1 ) float 32 bit Max. positive value: (2-2-23)*2127. int anInt = 4. variables and Arrays 2. positive value: 2-149 20 . The value of a reference type variable. or a memory address in other languages. A variable of primitive type contains a single value of the appropriate size and format for its type: a number. or a boolean value. Arrays. and interfaces are reference types.Chapter 2 : Data types.

2 Literals A specific primitive value in a line of code is called a literal. Hexadecimal literals begin with zero and an 'x' e. 0x23e4A (digits allowed are 0-9 and a to f. 013042 (and obviously only digits 0-7 are allowed). 2. The two boolean literals are simply true and false.3 Java Character Encoding: UTF and Unicode Java uses two closely related encoding systems UTF and Unicode. A literal character value is any single Unicode character between single quote marks. You can specify a long integer by putting an 'L' or 'l' after the number. Use \u followed by four hexadecimal digits representing the 16 bit unicode character e.363F 26.g. positive value: 2-1074 2. You can specify a float by putting an 'f' or 'F' after the number. Unicode characters are stored in two bytes 21 . Construct a literal value of char type using Java's unicode escape format for a specified character code. char x='\u1234' Java also supports certain escape codes for special characters such as '\n' for newline. Constructing literal numeric values using octal and hexadecimal formats. Java was designed from the ground up to deal with multibyte character sets and can deal with the vast numbers of characters that can be stored using the Unicode character set.266 Data Type int long double double float double char boolean boolean 37.double 64 bit Max. A series of digits with a decimal point is of type double. 'L' is preferred as it cannot be confused with the digit '1'. positive value: (2-2-52)*21023.g. Examples of Literal Values and Their Data Types Literal 178 8864L 37. Min.266D 87. These will be translated into values by the compiler and inserted into the byte code.77e3 'c' true false A series of digits with no decimal point is typed as an integer. the 'x' and the letters can be upper or lower case). Octal literals begin with zero e.g.

Note that Java is case sensitive so A1 and a1 are different identifiers.5 Rules for naming an identifier When we learn to program we have to give names or identifiers to things we create such as files. for example: cubeRoot. 22 . classes. most of which can easily be stored within one byte. words or even objects). firstNumber. For reasons of compactness Java uses a system called UTF-8 for string literals. this is sometimes called camel hump notation. This means it can deal with Japanese Chinese.java. identifiers and other text within programs. and just about any other character set known. The filename for the class code is the same as the name of the class. Naming Conventions Class identifiers begin with a capital letter. objects. variables and attributes (attributes could be numbers. the code for the class JTRectangle is stored in the file JTRectangle. numbers. 2.4 EscapeSequences \b \t \n \f \r \" \' \\ OctalEscape /* /* /* /* /* /* /* /* /* \u0008: backspace BS */ \u0009: horizontal tab HT */ \u000a: linefeed LF */ \u000c: form feed FF */ \u000d: carriage return CR */ \u0022: double quote " */ \u0027: single quote ' */ \u005c: backslash \ */ \u0000 to \u00ff: from octal value */ 2. other special characters or punctuation marks a Java keyword must not be used. the underscore character ( _ ) or dollar character ($) they cannot start with a number they must not include spaces. Although Unicode can represent almost any character you would ever likely to use it is not an efficient coding method for programming. Most of the text data within a program uses standard ASCII. There are rules which govern what is allowable.g. A convention that is sometimes adopted to make identifiers more readable is to use a capital letter to indicate the beginning of a new word. e. Identifiers must be chosen according to certain rules: • • • • they can contain letters.which allows for up to 65K worth of characters. This can result in a considerable saving by comparison with using Unicode where every character requires 2 bytes.

abstract boolean break byte case catch char class const * continue default do enum**** double Else extends Final finally Float For goto * If implements import instanceof assert*** int interface long native new package private protected public return short static strictfp ** super switch synchronized this throw throws transient try void volatile while * indicates a keyword that is not currently used ** indicates a keyword that was added for Java 2 *** new in J2SE 1. The variable's type determines what values it can hold and what operations can be performed on it. 2. a variable has scope. You use the variable name to refer to the data that the variable contains. You must explicitly provide a name and a type for each variable you want to use in your program.4 **** new in J2SE 5. You can perform arithmetic operations. on integer variables.Object identifiers start with a lowercase letter. The variable's name must be a legal identifier --an unlimited series of Unicode characters that begins with a letter. Attributes identifiers start with a lowercase letter. which generally looks like this: type name In addition to the name and type that you explicitly give a variable. false. 23 .0 2. Every variable must have a data type.7 Variables A variable is an item of data named by an identifier. you write a variable declaration.6 Java Language Keywords true. so you cannot use them as names in your programs either. A variable's data type determines the values that the variable can contain and the operations that can be performed on it. Integers can contain only integral values (both positive and negative). To give a variable a type and a name. such as addition. and null are not keywords but they are reserved words.

After creation. The value of a final variable cannot change after it has been initialized. like this: isVisible.8 Declaring constants – Final variables You can declare a variable in any scope to be final. the name of constant values are spelled in uppercase letters. an array is a fixed-length structure. Again. and any later attempts to assign a value to blankfinal result in a compile-time error. it cannot be set. and each word after the first begins with an uppercase letter.141592653589793. and class names begin with an uppercase letter. whose value is pi. all at once. . Simply declare the local variable and initialize it later. A final local variable that has been declared but not yet initialized is called a blank final. If a variable name consists of more than one word. .141592653589793) and cannot be changed: final double PI = 3. The following variable declaration defines a constant named PI. Subsequent attempts to assign a value to aFinalVar result in a compiler error. use the final keyword in the variable declaration before the type: final int aFinalVar = 0. You may. once a final local variable has been initialized. but by convention is used only to separate words in constants (because constants are all caps by convention and thus cannot be case-delimited). blankfinal = 0. the words are joined together. if necessary. 24 . Such variables are similar to constants in other programming languages. The underscore character (_) is acceptable anywhere in a name. like this: final int blankfinal. 2. 2. defer initialization of a final local variable. the ratio of the circumference of a circle to its diameter (3. To declare a final variable.9 Arrays An array is a structure that holds multiple values of the same type. The previous statement declares a final variable and initializes it.Variable names begin with a lowercase letter. By convention. . The length of an array is established when the array is created (at runtime).

boolean[] anArrayOfBooleans. plus the data type of the array elements. The sample program uses int[]. anArray = new int[10]. when creating an array. Object[] anArrayOfObjects. Here are declarations for arrays that hold other types of data: float[] anArrayOfFloats. Declaring an Array This line of code from the sample program declares an array variable: int[] anArray. String[] anArrayOfStrings. and [] indicates that this is an array. The next statement in the sample program allocates an array with enough memory for ten integer elements and assigns the array to the variable anArray declared earlier. you use the new operator. Remember that all of the elements within an array are of the same type. The sample program must assign a value to anArray before the name refers to an array. new elementType[arraySize] 25 . // create an array of integers In general. plus the number of elements desired enclosed within square brackets ('[' and ']').An array element is one of the values within an array and is accessed by its position within the array. An array's type is written type[]. so the array called anArray will be used to hold integer data. As with declarations for variables of other types. // declare an array of integers Like declarations for variables of other types. the declaration for an array variable does not allocate any memory to contain the array elements. Creating an Array You create an array explicitly using Java's new operator. an array declaration has two components: the array's type and the array's name. where type is the data type of the elements contained within the array.

. either to assign a value to it. the compiler would print an error like the following one and compilation would fail. length is a property provided by the Java platform for all arrays. false }.java:4: Variable anArray may not have been initialized. you write arrayname.length Be careful: Programmers new to the Java programming language are tempted to follow length with an empty set of parenthesis. This part of the code shows that to reference an array element.print(anArray[2] + " "). The length of the array is determined by the number of values provided between { and }. ArrayDemo. you append square brackets to the array name. false. true. 2. or to access the value. array indices begin at 0 and end at the array length minus 1. an n-dimensional array or simply n-D array) is a collection of items which is accessed via n subscript expressions 26 .e.out. Accessing an Array Element Now that some memory has been allocated for the array. the program assigns values to the array elements: anArray[2] = 10. Getting the Size of an Array To get the size of an array. System. This doesn't work because length is not a method. Before initialization arrays are always set to contain default values wherever they are created. true. The value between the square brackets indicates (either with a variable or some other expression) the index of the element to access.If the new statement were omitted from the sample program. Here's an example of this syntax: boolean[] answers = { true.10 Multidimensional Arrays A multi-dimensional array of dimension n (i. Note that in Java. Array Initializers The Java programming language provides a shortcut syntax for creating and initializing an array.

a two-dimensional array x is really an array of onedimensional arrays: int[][] x = new int[3][5]. uses arraycopy to copy some elements from the copyFrom array to the copyTo array. 'f'.11 Copying Arrays Use System's arraycopy method to efficiently copy data from one array into another. 'c'. The three integer arguments indicate the starting location in each the source and the destination array. The two Object arguments indicate the array to copy from and the array to copy to. 27 . int srcIndex. The arraycopy method requires five arguments: public static void arraycopy(Object source. It does. Object dest. You can allocate remaining dimensions separately. In Java. you need only specify the memory for the first (leftmost) dimension.3}.The Java programming language does not really support multi-dimensional arrays. and the number of elements to copy. 'a'. aMatrix[2]=new int[]{4. 'e'. public class ArrayOfArraysDemo2 { public static void main(String[] args) { int[][] aMatrix = new int[3][]. This diagram illustrates how the copy takes place: The following program. When you allocate memory for multidimensional array. } } 2.5. ArrayCopyDemo. public class ArrayCopyDemo { public static void main(String[] args) { char[] copyFrom = { 'd'. //populate matrix aMatrix[0]=new int[]{1}.6}. 'e'. int length). however. support arrays of arrays. 'f'. aMatrix[1]=new int[]{2.int destIndex.

'e'. 28 . Summary When you declare a variable. You can declare a variable as final. 0. An array is a fixed-length data structure that can contain multiple objects of the same type. The arraycopy method call puts the copied elements into the destination array beginning at the first element (element 0) in the destination array copyTo. The copy copies 7 elements: 'c'. System. 'a'. System. you explicitly set the variable's name and data type. Arrays. 'e'.out.'i'. char[] copyTo = new char[7]. so that the copy begins at the array element 'c'. the arraycopy method takes the "caffein" out of "decaffeinated". you use the type of object that the array can contain and brackets. and interfaces are reference types. An array can contain any type of object. 't'. 'f'. Effectively. and 'n'. including arrays. The Java programming language has two categories of data types: primitive and reference. 7). The value of a final variable cannot change after it's been initialized. To declare an array. 'd' }. 'i'. You can provide an initial value for a variable within its declaration by using the assignment operator (=).arraycopy(copyFrom. Recall that array indices start at 0. 'f'. } } The arraycopy method call in this example program begins the copy at element number 2 in the source array. like this: Note that the destination array must be allocated before you call arraycopy and must be large enough to contain the data being copied. 'a'.println(new String(copyTo)). copyTo. 2. 'n'. A variable of primitive type contains a value. The table in the Data Types section shows all of the primitive data types along with their sizes and formats. classes.

// 3 = '\b'. // 4 = '\''. Indices begin at 0 and end at the length of the array minus 1. e. 1 2 3 4 5 None of the above 29 . To get the length of the array.You can use the new operator to create an array. An element within an array can be accessed by its index. // 2 = '\"'. // 5 A compile-time error is generated at which line? a. you use the length attribute. To copy an array. use the arraycopy method in the System class. f. c. or you can use an array initializer. Questions 1. class MCZ11 { } public static char a char b char c char d char e } void main (String[] args) { = '\c'. d. // 1 = '\r'. the size of the array cannot change. Once created.The length of the array must be specified when it is created. b.

Compile-time error at line 2. Compile-time error at line 3. g. f. 8i. label to type until i. value virtual xor None of the above 4. g. l. f.2. b. _i2. d. qualified record repeat restricted int int int int int int int int i1. g. $i5. e. c. i_3. i$7. c. d. %i6. An attempt to run GRC6 from the command line fails. b. e. Compile-time error at line 1. h. 1 2 3 4 5 6 7 8 30 . f. An attempt to run GRC4 from the command line fails. An attempt to run GRC5 from the command line fails. j. #i4. // // // // // // // // 1 2 3 4 5 6 7 8 e. class Identifiers { } Compile-time errors are generated at which lines? a. b. d. k. class GRC4 {public static void main(String[] args) {}} // 1 class GRC5 {public static void main(String []args) {}} // 2 class GRC6 {public static void main(String args[]) {}} // 3 What is the result of attempting to compile and run the above programs? a. None of the above 3. c. Which of these words belongs to the set of Java keywords? a. h.

f. c. e. d. Which of the following represent the full range of type char? a. '\u0000' to '\u7fff' '\u0000' to '\uffff' 0 to 32767 0 to 65535 -32768 to 32767 -65536 to 65535 31 .5. b.

5. // 4 int[] a5 = new int[5]{1.2. System.6 Compile-time error Run-time error None of the above 32 .2}.2}.8 Prints: 7.6}.9."+a1[1][0]+".print(a1[0][2]+". 3 d. // 3 int []a4 = {1.5}.8.3. d. 2 7.{4. 5 public static void main(String[] args) { int[][] a1 = {{1. // 1 int a2[] = new int[5]. b.10}}. 1 b. // 5 Compile-time errors are generated at which lines? a. 4 e.6.2. Prints: 3.4.out.{7. class MWC201 { c. } } What is the result of attempting to compile and run the program? a.4."+a1[2][1]). // 2 int[] a3 = new int[]{1. e. c. class MWC101 { } } public static void main(String[] args) { int[] a1 = new int[].2.3}.

the arithmetic operators.2 Operator An operator performs a function on one. you get an integer back.integer. ?:. which means that the operator appears between its operands: op1 operator op2 //infix notation The ternary operator is also infix. which in numeric operations is treated as an unsigned two byte integer 3. The return value and its type depend on the operator and the type of its operands. floating point or character any primitive type variable . or string. The data type returned by an arithmetic operator depends on the type of its operands: If you add two integers. ++ is a unary operator that increments the value of its operand by 1. For example. An operation is said to evaluate to its result. which perform basic arithmetic operations such as addition and subtraction. two. And finally.1 Operands An operand can be: • • • • • • a numeric variable . return numbers-the result of the arithmetic operation. An operator that requires one operand is called a unary operator. a ternary operator is one that requires three operands. Prefix notation means that the operator appears before its operand: operator op //prefix notation Postfix notation means that the operator appears after its operand: op operator //postfix notation All of the binary operators use infix notation. For example.Chapter 3 : Operators 3. boolean value.numeric and boolean reference variable to an object a literal . each component of the operator appears between operands: op1 ? op2 : op3 //infix notation In addition to performing the operation. For example.numeric value. The unary operators support either prefix or postfix notation. which is a short-hand if-else statement. an array element. The Java programming language has one ternary operator. or three operands. 33 . "a[2]" char primitive. an operator returns a value. An operator that requires two operands is a binary operator. = is a binary operator that assigns the value from its right-hand operand to its left-hand operand.

println(" y = " + y). int j = 42.println(" j = " + j). System.println(" x = " + x). and % (modulo). System.out.println(" i = " + i). System. then infinity returned if op1 is not zero otherwise NaN if op1 is zero. double x = 27.We divide the operators into these categories: • • • • • • • Arithmetic Operators Increment and decrement operators Relational Operators Bitwise Operators Logical Operators Assignment Operators Conditional or ternary operator 3.22.out. //adding numbers 34 .out. Operator + * / op1 op1 op1 op1 Use + – * / op2 op2 op2 op2 Description Adds op1 and op2 Subtracts op2 from op1 Multiplies op1 by op2 Divides op1 by op2 If floating point arithmetic and op2 = 0.out.. * (multiplication). / (division).(subtraction). then NaN returned ArthmeticException thrown if op1 & op2 are integer types and op2 is zero. System. These operators are + (addition).475. double y = 7.println("Variable values.0.1 Arithmetic Operators The Java programming language supports various arithmetic operators for all floating-point and integer numbers.2. ArthmeticException thrown if op1 & op2 are integer types and op2 is zero.0 or infinity. public class ArithmeticDemo { public static void main(String[] args) { //a few numbers int i = 37. The following table summarizes the binary arithmetic operations in the Java programming language..").out. System. . % op1 % op2 Computes the remainder of dividing op1 by op2 If floating point arithmetic and op2 = 0.

out. //subtracting numbers System..out.").out. neither operand is a long."). System.out.. } } Note that when an integer and a floating-point number are used as operands to a single arithmetic operation..println("Mixing types. The necessary conversions take place before the operation is performed.println(" x . System. //computing the remainder resulting from dividing numbers System.println(" x + y = " + (x + y))..out. based on the data type of the operands.out. System. each of these operators has unary versions that perform the following operations: Operator Use Description 35 . At least one operand is a float.println(" i * j = " + (i * j)).out..j)).println(" i % j = " + (i % j)).out. System.println(" j + y = " + (j + y)).println(" x * y = " + (x * y)). Data Type of Result long int double float Data Type of Operands Neither operand is a float or a double (integer arithmetic).out.println("Computing the remainder.out. The following table summarizes the data type returned by the arithmetic operators. the result is floating point.out.y))..println(" x % y = " + (x % y)).").println("Dividing.out.out..out."). System.").out. System.println(" i / j = " + (i / j)). //multiplying numbers System. In addition to the binary forms of + and -. System.System. The integer is implicitly converted to a floating-point number before the operation takes place. At least one operand is a double.println(" i + j = " + (i + j)).println(" x / y = " + (x / y)).println("Multiplying."). //dividing numbers System.out.println("Subtracting. System.out. System.. Neither operand is a float or a double (integer arithmetic). System.. neither operand is a double. //mixing types System.println(" i * x = " + (i * x)).j = " + (i .println(" i . System..y = " + (x ... System. at least one operand is a long.out.println("Adding.

System. evaluates to the value of op before it was ++op Increments op by 1. int j = 42.2 Increment and Decrement Operators Increment operator (++) increments its operand by 1. ++op/--op. op++/op--.out."). or char -op Arithmetically negates op 3. short. evaluates to the value of the operand after the increment/decrement operation. The prefix version. System.2.out. Either ++ or -.. Operator ++ ++ --- Use incremented Description op++ Increments op by 1. 36 . evaluates to the value of op after it was incremented op-. System.can appear before (prefix) or after (postfix) its operand. The postfix version. != returns true if the two operands are unequal..Decrements op by 1.println(" j = " + j).println(" i = " + i). This table summarizes the relational operators: Operator > >= < <= == != Use op1 > op1 >= op1 < op1 <= op1 == op1 != op2 op2 op2 op2 op2 op2 Returns true if op1 is greater than op2 op1 is greater than or equal to op2 op1 is less than op2 op1 is less than or equal to op2 op1 and op2 are equal op1 and op2 are not equal public class RelationalDemo { public static void main(String[] args) { //a few numbers int i = 37.2.out. evaluates to the value of op before it was decremented --op Decrements op by 1.println("Variable values. For example.+ - +op Promotes op to int if it's a byte. evaluates the value of the operand before the increment/decrement operation. int k = 42.3 Relational Operators A relational operator compares two values and determines the relationship between them. and decrement operator (--)decrements its operand by 1. evaluates to the value of op after it was decremented 3.

out.out...println("Not equal to.println(" i <= j = System. " + (i >= j)).").println(" k <= j = equal to.out. j = " + (k > j)). } } //false //true //true //false Relational operators often are used with conditional operators to construct more complex decision-making expressions.System.out.println(" k < j = " + (k < j)).println(" j >= i = System.println(" j <= i = System. //false " + (j >= i)).out.out.")."). i = " + (j > i)).println(" i < j = " + (i < j)).").println("Less than.out. System.println("Greater System..out. System. conditionally evaluates op2 op is false op1 and op2 are both true. j = " + (i > j)). " + (i <= j)).println(" j > System.out.println(" k >= j = or equal to. //greater than System.. //true //less than System..println("Greater than System.out..out.out.out.println(" i != j = " + (i != j)).out.").out. than.println("Equal to.out..println(" k > //false. conditionally evaluates op2 either op1 or op2 is true.out. they are equal //false //true //greater than or equal to System. System. " + (j <= i))."). System. System.out.println(" j < i = " + (j < i)). //true " + (k >= j)).println(" k = " + k). System.println("Less than or System.. //less than or equal to System.println(" k == j = " + (k == j)). System.out. Operator && || ! & Use op1 && op2 op1 || op2 ! op op1 & op2 Returns true if op1 and op2 are both true. The Java programming language supports six conditional operators-five binary and one unary--as shown in the following table.println(" k != j = " + (k != j)). //true //false //false //true //false //true //equal to System.println(" i > System.out.. //not equal to System..out. always evaluates op1 and op2 37 .. " + (k <= j)).println(" i == j = " + (i == j)).out..println(" i >= j = System.out.

The shift occurs in the direction indicated by the operator itself. the following statement shifts the bits of the integer 13 to the right by one position: 13 >> 1.4 Bitwise Operators A shift operator performs bit manipulation on data by shifting the bits of its first operand right or left. the & operation performs the bitwise AND function on each parallel pair of bits in each operand. or 6 in decimal. The binary representation of the number 13 is 1101. The AND function sets the resulting bit to 1 if the corresponding bit in both operands is 1. For example. The left-hand bits are filled with 0s as needed. Operator >> << >>> Use Operation op1 >> op2 shift bits of op1 right by distance op2 op1 << op2 shift bits of op1 left by distance op2 op1 >>> op2 shift bits of op1 right by distance op2 (unsigned) Each operator shifts the bits of the left-hand operand over by the number of positions indicated by the right-hand operand. op1 op2 0 0 1 1 0 1 0 1 Result 0 0 0 1 38 . The following table shows the four operators the Java programming language provides to perform bitwise functions on their operands: Operator & | ^ ~ Use op1 & op2 op1 | op2 op1 ^ op2 ~op2 Operation bitwise and bitwise or bitwise xor bitwise complement When its operands are numbers. as shown in the following table.2.| ^ op1 | op2 op1 ^ op2 either op1 or op2 is true. This table summarizes the shift operators available in the Java programming language. always evaluates op1 and op2 if op1 and op2 are different--that is if one or the other of the operands is true but not both 3. The result of the shift operation is 1101 shifted to the right by one position-110.

1101 & 1100 -----1100 //13 //12 //12 If both operand bits are 1.Suppose that you were to AND the values 13 and 12. the resulting bit in the result is also 1. 39 . So. Among other things. To set the "visible" flag when something became visible you would use this statement: flags = flags | VISIBLE. Thus. The low-order bits evaluate to 0 because either one or both bits in the operands are 0. The following table shows the results of inclusive or operations: op1 op2 0 0 1 1 0 1 0 1 Result 0 1 1 1 Exclusive or means that if the two operand bits are different the result is 1. DRAGGABLE = 2. EDITABLE = 8. the | operator performs the inclusive or operation. otherwise. and the binary representation of 13 is 1101. otherwise the result is 0. The following table shows the results of an exclusive or operation. when you line up the two operands and perform the AND function. like this: 13 & 12. int flags = 0. When both of its operands are numbers. the complement operator inverts the value of each bit of the operand: if the operand bit is 1 the result is 0 and if the operand bit is 0 the result is 1. Inclusive or means that if either of the two bits is 1. static static static static final final final final int int int int VISIBLE = 1. bitwise manipulations are useful for managing sets of boolean flags. SELECTABLE = 4. the result is 1. the resulting bit is 0. op1 op2 0 0 1 1 0 1 0 1 Result 0 1 1 0 And finally. and ^ performs the exclusive or (XOR) operation. The result of this operation is 12 because the binary representation of 12 is 1100. the AND function sets the resulting bit to 1. you can see that the two high-order bits (the two bits farthest to the left of each number) of each operand are 1.

. SELECTABLE = 4. DRAGGABLE = 2. } } 40 . However what if a particular action is to be taken only if several conditions are true? You can use a sequence of if statements to test the conditions. } } flags = flags | EDITABLE.out.2. <=. } } } 3.println("Flags are Visible and Draggable. ==) are sufficient when you only need to check one condition..5 Logical Operators The relational operators you've learned so far (<. if ((flags & EDITABLE) == EDITABLE) { System. if ((flags & VISIBLE) == VISIBLE) { if ((flags & DRAGGABLE) == DRAGGABLE) { System.out. !=.out. >.").println("Both conditions are true. flags = flags | VISIBLE. } A program example is given below: public class BitwiseDemo { static static static static final final final final int int int int VISIBLE = 1. public static void main(String[] args) { int flags = 0. flags = flags | DRAGGABLE.")."). as follows: if (x == 2) { if (y != 2) { System. EDITABLE = 8. >=.To test for visibility. you could then write: if ((flags & VISIBLE) == VISIBLE) { .println("Flags are now also Editable.

// now b is false The last logic operator is ! which means not. 2 || 5 < 7. so Java doesn't bother checking the value of c. If b is false !b is true. it first checks whether b is true. 41 . the expression on the left side of the operator is evaluated first. consider the following: boolean b. // b is true 3 || 5 < 7. It reverses the value of a boolean expression. // d is false When Java evaluates the expression d = b && c.").println("Both conditions are true. // b is still true 3 || 5 > 7. // b is true These operators allow you to test multiple conditions more easily. && combines two boolean values and returns a boolean which is true if and only if both of its operands are true. however. // b is true b = 2 > 3 && 5 < 7. d. For example. For instance the previous example can now be written as if (x == 2 && y != 2) { System. boolean b. c.out. // b is false c = !(2 > 3). || and !. Fortunately. b = !(3 > 2). Java provides an easy way to handle multiple conditions: the logic operators. b = !(3 > 2). There are three logic operators.This. b = 3 > 2 && 5 < 7. &&. is logical and. // b is false b = !(2 > 3). } The Order of Evaluation of Logic Operators When Java sees a && operator or a ||. is hard to write and harder to read.. It only gets worse as you add more conditions. // c is true d = b && c. Thus if b is true !b is false. For instance || boolean b = 3 > b = 2 > b = 2 > b. // b is now false is logical or. || combines two boolean variables or expressions and returns a result that is true if either or both of its operands are true. so b && c must be false regardless of whether c is or is not true. Here b is false. For instance && boolean b.

out. if((b1==true) && ((Output+=10)==20)) { System. Mathematically this makes sense because m/0 is in some sense infinite which is greater than two. public class MyClass1{ public static void main(String argv[]){ int Output=10. For instance consider this code. boolean b = (n == 0) || (m/n > 2). because the left hand side is always evaluated first. the overall calculation will show up as true because only one evaluation must return true to return an overall true. you decide that what you really want to know is whether m/n is finite and greater than zero you should use a line like this boolean b = (n != 0) && (m/n > 0). If. if the first operand is false it doesn't matter what the second operand evaluates to. And if m is also zero. Even if n is zero this line will never cause a division by zero. If m is negative and n is zero then m/n is negative infinity which is less than two. Still it's possible to force them.out. If n is zero then the left hand side is true and there's no need to evaluate the right hand side. if the first operand has turned out true. } } } 42 .println("We are equal "+Output). The Java approach makes sense if you consider that for an AND. upon reflection. Take the following example.println("Not equal! "+Output). Also for a logical OR.On the other hand when faced with an || Java short circuits the evaluation as soon as it encounters a true value since the resulting expression must be true. This short circuit evaluation is less important in Java than in C because in Java the operands of && and || must be booleans which are unlikely to have side effects that depend on whether or not they are evaluated. the overall result will be false. boolean b1 = false. } else { System. The short circuit effect with logical operators The logical operators (&& and ||) have a slightly peculiar effect in that they perform "shortcircuited" logical AND and logical OR operations. This can have an effect with those clever compressed calculations that depend on side effects. Therefore if there's a real chance your program will have a divide by zero error think carefully about what it means and how you should respond to it. then m/n is very undefined. This isn't a perfect solution though because m may be 0 or it may be negative.

If you change the value of b1 to true processing occurs as you would expect and the output is "We are equal 20". shift.6 Assignment Operators You use the basic assignment operator. or bitwise operation and an assignment operation all with one operator. x operation= y is equivalent to x = x operation y x and y must be numeric or char types except for "=". Suppose you wanted to add a number to a variable and assign the result back into the variable. to assign one value to another. However make sure you use these only on boolean expressions.The output will be "Not equal 10". The two previous lines of code are equivalent. =. the rules for mixed types in expressions apply.2. then you can use & and | instead of && and ||. In this case. like this: i = i + 2. Avoiding Short Circuits If you want all of your boolean expressions evaluated regardless of the truth value of each. The Java programming language also provides several shortcut assignment operators that allow you to perform an arithmetic. like this: i += 2. Unlike && and ||.. This may be handy sometimes when you really don't want to process the other operations if any of them return false. & and | also have a meaning for numeric types which is completely different from their meaning for booleans. x must be of the same type of class or interface as y. but it can be an unexpected side effect if you are not completely familiar with it. You can shorten this statement using the shortcut operator +=. This illustrates that the Output +=10 calculation was never performed because processing stopped after the first operand was evaluated to be false. If mixed floating-point and integer types. which allows x and y also to be object references. 3. The following table lists the shortcut assignment operators and their lengthy equivalents: Operator += -= *= /= op1 op1 op1 op1 Use += -= *= /= op2 op2 op2 op2 Equivalent to op1 op1 op1 op1 = = = = op1 op1 op1 op1 + * / op2 op2 op2 op2 43 .

(a the second value. Conditional or ternary operator Used to declare arrays. is an expression which returns one of two values. create arrays.7 Ternary or Conditional operator The ?: operator is a conditional operator that is short-hand for an if-else statement: op1 ? op2 : op3 The ?: operator returns op2 if op1 is true or returns op3 if op1 is false. b.2. is 44 . and access array elements Used to form qualified names Delimits a comma-separated list of parameters Casts (converts) a value to the specified type Creates a new object or a new array Determines whether its first operand is an instance of its second operand 3. If it is false. ( params ) ( type ) new instanceof Description Shortcut if-else statement. } else { max = b. In Java you might write if (a > b) { max = a.%= &= |= ^= <<= >>= >>>= op1 %= op2 op1 &= op2 op1 |= op2 op1 ^= op2 op1 <<= op2 op1 >>= op2 op1 >>>= op2 op1 = op1 % op2 op1 = op1 & op2 op1 = op1 | op2 op1 = op1 ^ op2 op1 = op1 << op2 op1 = op1 >> op2 op1 = op1 >>> op2 Other Operators Operator ?: [] . } Setting a single variable to one of two states based on a single condition is such a common use of if-else that a shortcut has been devised for it. The value of a variable often depends on whether a particular boolean expression is or is not true and on nothing else. or b. Using the conditional operator you can rewrite the above example in a single line like this: max = (a > b) ? a : b. (a > b) ? a : b. The condition. is returned. a. If it is true the first value. is tested. ?:. the conditional operator. a > b). For instance one common operation is setting the value of a variable to the maximum of two quantities.

using a value in a method invocation. You can never use a void method as an argument to the ? : operator. The condition can be any expression which returns a boolean value. The first argument to the conditional operator must have or return boolean type and the second and third arguments must return values compatible with the value the entire expression can be expected to return. to create arrays. and to access a particular element in an array. Whichever value is returned is dependent on the conditional test. The previous code declares an array that can hold ten floating point numbers. Here's an example of an array declaration: float[] arrayOfFloats = new float[10]. Operator The dot (.) operator accesses instance members of an object or class members of a class. } else { System. consider the following if (name.out.out.equals("Rumplestiltskin") ? System.equals("Rumplestiltskin")) { System. For example. or in some other way that indicates the type of its second and third arguments. a > b.println("Laugh").println("Give back child").out. Note that array indices begin at 0. Secondly. 3. The conditional operator only works for assigning a value to a variable.println("Laugh").println("Give back child") : System. both the second and third arguments are void.2.2. Here's how you would access the 7th item in that array: arrayOfFloats[6].10 The () Operator 45 .9 The . 3. no assignment is present to indicate the type that is expected for the second and third arguments (though you know void must be wrong). 3. First of all.2. } This may not be written like this: name.8 The [ ] Operator You use square brackets to declare arrays.returned.out.

Examples include: • • • • i = 2 k++ : the assignment puts 2 into the i variable and returns the value 2 : returns k. You can specify an empty argument list by using () with nothing between them. the statement int x = 1. op1 instanceof op2 must be the name of an object and op2 must be the name of a class.2*y)). then k is incremented by 1 : logical "less than" comparison.11 The (type) Operator Casts (or "converts") a value to the specified type. 3. declares a variable x and then assigns the value 1 to it. It can encompass multiple operators and operands. For example. you list the method's arguments between ( and ).13 The instanceof Operator The instanceof operator tests whether its first operand is an instance of its second. as well as multiple sub-statements. 3. 3. returns a Boolean true or false value : returns the value of a bitwise OR operation on bits in the two variables. 3.2.3 Expressions An expression produces a result and returns a value.1 / Math.cos (0. x < y i | j Expressions involve at least one operator.2. A single operator can have 1.3 *(4. 2 or 3 operands.When declaring or calling a method. Here's an example of creating a new Integer object from the Integer class in the java.12 The new Operator You use the new operator to create a new object or a new array. This statement x = 5. An object is considered to be an instance of a class if that object directly or indirectly descends from that class. op1 3.lang package: Integer anInteger = new Integer(10).2. 46 .4 Statements A statement is essentially any complete sentence that causes some action to occur.

consists of several expressions . not after.0. You can use parentheses to adjust the order much as they are used in the above formula. // step size 47 . // Print a Fahrenheit to Celsius table class FahrToCelsius { public static void main (String args[]) { // lower limit of temperature table double lower = 0. division. 3.5 Operator Precedence Highest Precedence () ++expr --expr +expr -expr ~ ! * / % + << >> >>> < > <= >= instanceof == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= >>>= Lowest Precedence Overriding Operator Precedence Parenthesis is used to override operator precedence. The next program prints a table showing the conversions from Fahrenheit and Celsius between zero and three hundred degrees Fahrenheit every twenty degrees. // upper limit of temperature table double upper = 300. Sometimes the default order of evaluation isn't what you want. You must subtract 32 from the Fahrenheit temperature before you multiply by 5/9.32) where C is degrees Celsius and F is degrees Fahrenheit. the formula to change a Fahrenheit temperature to a Celsius temperature is C = (5/9) (F .multiplication.0. For instance. a method call to a math function .but is still considered a single statement.

0) * (fahr-32.444 240 115. } } } Here's the output: 0 -17.667 280 137.0).println(fahr + " " + celsius).44444 60 15.7778 120 48. System. fahr = fahr + step.778 300 148.1111 180 82.889 Everything inside the parentheses will be calculated before anything outside of the parentheses is calculated.7778 20 -6.out.8889 140 60 160 71.556 260 126.5556 80 26.3333 220 104. double fahr = lower.double step = 20.0 / 9. 48 .6667 100 37.66667 40 4. All other operators (see precedence table above) are evaluated left to right. Operator Associativity The following operators have Right to Left associativity. while (fahr <= upper) { double celsius = (5.0.2222 200 93.

// Error in assigning long to int // OK So a data type with lower precision (fewer bits) can be converted to a type of higher precision without explicit casting. That is. To convert type AA data into type BB data.6 Type Conversion and Casting Converting one type of data into another must follow the rules of casting. Note that when you cast a value of a wider type down to a more narrow type. BB b = (BB)a. float f. such as an int value to a byte variable. put the type BB name in parentheses in front of the type AA data: AA a = aData. the lowest order byte in the int value will be copied to the byte value. // Literals are int types so require L suffix j=i. f=(float)i.= *= /= %= += -= <<= >>= >>>= &= ^= |= ?: new (type cast) ++x --x +x -x ~ 3. // OK However. If a conversion results in the loss of precision. the upper bytes will be truncated. as in an int value converted to a short. 49 . // cast type AA to type BB For example. to convert integer data to floating point: int i=0. long j=3L. // Cast int as float Expressions can promote to a wider type without an explicit cast: int i=1. however. an explicit cast is required or the compiler will flag an error. To convert a higher precision type to a lower precision. i=(int)j. then the compiler will issue an error message unless an explicit cast is made. you can not assign a value to a more narrow type without an explicit cast: i=j.

For example. Otherwise.Primitive Type Conversion Table Below is a table that indicates to which of the other primitive types you can cast a given primitive data type. Otherwise. class IntAndDouble { 50 . N indicates that the conversion is not allowed. the lower precision or narrower value operand is converted to a higher precision or wider type. // OK since i will be promoted to float j= i*y. int j. int long float double char byte short boolean int C C C A A A N long A C C A A A N float A* A* C A A A N double A A* A A A A N char C C C C C C N byte C C C C C C N short C C C C C A N boolean N N N N N N N - The * asterisk indicates that the least significant digits may be lost in the conversion even though the target type allows for bigger numbers. The program below uses both ints and doubles.i=3. if either operand is of type long. the other is converted to long. Mixed Types in an Expression If an expression holds a mix of types. as in x+i: • • • • If either operand is of type double. // Error since result is a float value j= (int)(i*y) // OK The process of converting a value to a wider or higher precision integer or floating point type is called "numeric promotion". both operands are converted to type int. The symbol C indicates that an explicit cast is required since the precision is decreasing. the other is converted to float. Otherwise.y=3. x= i*y. The Java VM specification states the following rules for promotion in an expression of two operands. for example. This result then must be cast if it goes to a lower precision type: float x. The symbol A indicates that the precision is increasing so an automatic cast occurs without the need for an explicit cast. a large value in an int type value that uses all 32 bits will lose some of the lower bits when converted to float since the exponent uses 8 bits of the 32 provided for float values. the other is converted to double. if either operand is of type float.

System.out. System. double x = 2.75 3. System. For example. System.75 You cannot assume that the usual mathematical laws of commutativity apply when mixing data types.out.75 1 / 2. * x is " + k).5 / 2 = 1.0 * 3. . 1.println("x is " + x).i. System.75 3.5 = 1.0 / 2 * 3.println("i is " + i).5 * 1.println("x } } + x is " + k).out.5 * 1.i is " + k).x.x is .5 25 7. k = i + x.5 = 1.0 / 2 = 1.75 51 .println("i k = x . System.public static void main (String args[]) { int i = 10.println("i k = x / i.75 3. 1 / 2 * 3.25 Order can make a difference when data types are mixed.5 4 0.0 / 2. This program produces the following output: i x i i i x i x is 10 is 2. .5 * 1 / 2 = 1.5 + x is * x is .println("x k = i / x.5 -7.println("i k = i . double k.5.i is / x is / i is 12.out. / i is " + k).out. especially integer and floating point types.0 = 1. / x is " + k). System.out.out.5 = 0.x is " + k). System.println("i k = i * x.out.0 3.

If the floating point number is too small the integer is set to the smallest possible value of its type. then the integer is set to the largest possible value of its type. However when it does there will be no warning or error message. Anything except a double can fit in a float. then Java treats both values as an int. if there's an equals sign. For instance: int i = (int) (9. If neither value is a double but one is a float. If the right hand side can fit inside the left hand side. The basic rule is that if either of the variables in a binary operation (addition. but a float or a double can't. After all 3 * 54. and ints. It can also be hard to find since everything may work perfectly 99 times out of a hundred and only on rare occasions will the rounding become a problem.e. multiplication. If neither is a float or a double but one is a long. 52 .0). subtraction. the assignment is completed. then Java treats both values as longs. even if there aren't any ints in the equation. Anything can fit in a double. On the other hand if the number is too large. It won't change the type of the left hand side. the fractional part of the floating point number is truncated (rounded toward zero). In an assignment statement. Any integral type can fit in a long. float. but it will check to make sure that the value it has (double. use a cast. remainder) are doubles then Java treats both values as doubles. the assignment takes place with no further ado. To cast a variable or a literal or an expression to a different data type just precede it with the type in parentheses. long or int depending on the types of the arguments. but what about an int divided by a double or a double divided by an int? When doing arithmetic on unlike types Java tends to widen the types involved so as to avoid losing information. When it's necessary to force a value into a particular type. When a value is cast down before assignment.2E18 will be a perfectly valid double but much too big for any int.7 Automatic Type Promotions An int divided by an int is an int.0/4. floats or longs. and bytes can fit inside ints. This can be a nasty bug in your code. float. This produces an integer. then Java treats both values as floats. In fact it's so troublesome the compiler won't let you do it unless you tell it you really mean it with a cast. i. A cast lets the compiler know that you're serious about the conversion you plan to make. If the integer is small enough to fit in the left hand side. You need to be very careful when assigning floating point values to integer types. Java compares the type of the left hand side to the final type of the right hand side. shorts. int or long) on the right hand side can fit in the type on the left hand side. For a conversion between a floating point number and an int or a long. Finally if there are no doubles.3. Assigning long values to int variables or double values to float variables can be equally troublesome. series of operations takes place to chop the right hand side down to size. and a double divided by a double is a double. Therefore the result will be a double. addition.

} What is the result of attempting to compile and run the program? a. It included all the standard arithmetic operators. class MCZ24 { public static void main (String[] args) { char a = 061. b.3 e." + b + ".print(""+a+b+c+d+e).3.3 i.3. Compile-time error g. Questions 1.0 Prints: 3.3.out.0 Prints: 3. // 5 System. Prints: null 2. c. Prints nothing.0. // 3 char d = 0x0031. // 1 char b = '\61'.print(a + ". int c = 1 || (2 ^ (3 && 5)).Summary This chapter discussed the operators that you can use in Java to manipulate the values of variables.3. b.0. System. Prints: 0 e.3 Prints: 3. Prints an undefined value. None of the above 3. class EBH201 { d.println(x+y+z). None of the above } public static void main (String[] args) { int a = 1 || 2 ^ 3 && 5. Finally it discussed the concept of operator precedence that defined the rules by which the order of operators is evaluated.out.0 Prints: 0. Prints: 0. // 2 char c = '\061'.0 Prints: 0. g. Prints: 3." + c).0. c. System. h. Compile-time error k. int b = ((1 || 2) ^ 3) && 5.y. d. class GFM11{ } public static void main (String[] args) { int x. Run-time error f. the increment and decrement operators. // 4 char e = '\u0031'.0. f.z. the relational operators.out. } What is the result of attempting to compile and run the program? a. Run-time error j. the bit-wise operators. and the shift operators. } 53 .3 Prints: 0.

f. d. c.} A compile-time error is generated at which line? a. 1 2 3 4 5 None of the above 54 . e. b.

System. class EBH014 { public static void main (String[] args) { byte x = 3.println(b<<33). None of the above 7. } } What is the result of attempting to compile and run the above program? a.print(a). Prints: false.out.out. None of the above 5. } What is the result of attempting to compile and run the program? a. Prints: 0 c. Prints: 1 d. Prints: 4 c.true e. Prints: 7 f. Run-time error f. Prints: 3 b. System. Prints: true. Prints: false. Compile-time error h. Prints: 5 d.false b.print((y % x) + ". Compile-time error g.4."). Prints: true. class EBH012 { public static void main (String[] args) { byte x = 3. y = 5. Prints: 6 e. Compile-time error h. Prints: -1 b. System. class EBH106 { public static void main(String args[]) { int a = 1. class EBH007{ } public static void main (String[] s) { byte b = 5. Run-time error g. None of the above 6. y = 5. 55 ."+(-y == ~y + 1)).true c. } } What is the result of attempting to compile and run the program? a. Prints: 5 e. Prints: 10 f. System.false d. a += ++a + a++.out.print((-x == ~x + 1)+". Run-time error g.out.

Prints: 1. What is the result of attempting to compile and run the program? a. h.} public static void main(String [] args) { boolean b1 = false?false:true?false:true?false:true.true c. None of the above 8. Prints: 2. f. k.println(m1(b1) + m1(b2) + m1(b3)).print(y == ((y/x)*x + (y%x))). boolean b2 = false?false:(true?false:(true?false:true)). } } What is the result of attempting to compile and run the program? a.out. Prints: TFF Prints: TFT Prints: TTF Prints: TTT i. c. boolean b3 = ((false?false:true)?false:true)?false:true.false d. Compile-time error g.out. d. b. Run-time error f.false e. Prints: 2. Run-time error Compile-time error None of the above 56 . class EBH023 { static String m1(boolean b){return b?"T":"F". System.true b. g.} } System. Prints: FFF Prints: FFT Prints: FTF Prints: FTT e. j. Prints: 1.

because the code is easier to read and it helps to prevent errors when modifying code. label:. then the while statement executes the statement(s) associated with it. the interpreter executes these statements in the order they appear in the file from left to right. to repeatedly execute a block of statements. and to otherwise change the normal. return try-catch-finally.println(x--).Chapter 4 : Control flow statements Without control flow statements.1 The while and do-while Statements You use a while statement to continually execute a block of statements while a condition remains true. switch-case break. the braces. However. You can use control flow statements in your programs to conditionally execute statements. top to bottom. are not required if the block contains only one statement. public class WhileDemo { public static void main(String[] args) { int x=10. we recommend that you always use { and }. which must return a boolean value. for if-else. { and }. 4. The general syntax of the while statement is: while (expression) { statement } First.throw In the sections that follow. you will see the following notation to describe the general form of a control flow statement: control flow statement details { statement(s) } Technically. do-while . sequential flow of control.out. The while statement continues testing the expression and executing its block until the expression returns false. the while statement evaluates expression. throws. } } 57 . while (x != 0) { System. Statement Type looping decision making branching exception handling Keyword while. If the expression returns true. continue.

When the expression evaluates to false.2 The for Statement The for statement provides a compact way to iterate over a range of values. do-while evaluates the expression at the bottom. All these components are optional. do { System. to write an infinite loop. increment is an expression that gets invoked after each iteration through the loop. the loop terminates. Finally. } while(x != 0). Instead of evaluating the expression at the top of the loop. public class DoWhileDemo { public static void main(String[] args) { int x=10. assigning values to its elements. termination. In fact.length to determine when to terminate the loop.. This expression is evaluated at the top of each iteration of the loop. increment) { statement } The initialization is an expression that initializes the loop-it's executed once at the beginning of the loop. . The termination expression determines when to terminate the loop.out. The general form of the for statement can be expressed like this: for (initialization. } } This program prints numbers from 10 to 0 in the descending order 4. } // infinite loop The for loop in the sample program iterates over each element of anArray. 58 . Thus the statements associated with a do-while are executed at least once..} This program prints numbers from 10 to 1 in the descending order The Java programming language provides another statement that is similar to the while statement--the do-while statement.println(x--). The for loop uses anArray. ) { . The general syntax of the do-while is: do { statement(s) } while (expression). you omit all three expressions: for ( .

// declare an array of integers anArray = new int[10]. 2000. 12. for(int i = 0 . for (int i = 0. i < anArray. i++) { System. j < 5 .length.print(anArray[i] + " "). called ArrayDemo. System. If the variable that controls a for loop is not needed outside of the loop. 589. i++) { anArray[i] = i. and displays the values. The scope of this variable extends from its declaration to the end of the block governed by the for statement so it can be used in the termination and increment expressions as well. } System. i < x. declaring them within the for loop initialization expression limits their life-span and reduces errors. that creates the array.println(). 127 }. the expression x[i][j] selects the jth element from that array. int k=0. j++) { x[i][j] = k++. } } Often for loops are used to iterate over the elements in an array. } } for(int i = 0 . The names i. i < 3 . or the characters in a string.println(). puts some values in it.print(arrayOfInts[i] + " ").out. 3. i++) { 59 . public class ArrayDemo { public static void main(String[] args) { int[] anArray. } System. The expression x[i] selects the ith one-dimensional array. i++) { for (int j = 0. } } Note that you can declare a local variable within the initialization expression of a for loop.out.Here's a simple program. it's best to declare the variable in the initialization expression. i < arrayOfInts.out.length. j. public class ArrayofArraysDemo1 { public static void main(String args[]) { int [] [] x = new int [3][5]. 8. 622.length . 1076. 87.out. and k are often used to control for loops. // create an array of integers // assign a value to each array element and print for (int i = 0. public class ForDemo { public static void main(String[] args) { int[] arrayOfInts = { 32.

} } You can read the for statement in the preceding snippet like this: For each int element in arrayOfInts.. 127 }. If it isn't raining then you don't.length . For instance you stick your hand out the window to test if it's raining. the simple form of if can be written like this: if (expression) { statement(s) } 60 .out. 1076.0) for (type value : container) statement This for statement was created especially for collections and arrays. 3. This is the simplest version of the if statement: The block governed by the if is executed if a condition is true. This is quite common in real life. 4. Generally. If it is raining then you take an umbrella with you. for (int element : arrayOfInts) { System..print(x[i][j] + ‘\t’). 87.3 The if/else Statements All but the most trivial computer programs need to make decisions. j++) { System. 2000. 622.println(). 589. } } } Enhanced for loop (added with Java 5.print(element + " "). } System. j < x[i]. They test a condition and operate differently based on the outcome of the test.for (int j = 0. All programming languages have some form of an if statement that tests conditions. public class ForEachDemo { public static void main(String[] args) { int[] arrayOfInts = { 32. An example to print all elements in the array. 8.println().out. 12. } System.out.out.

You can test whether a number is less than or equal to or greater than or equal to another number with the <= and >= operators. However there is one way you can still get into trouble: boolean b = true.println(“Number is divisible by 10”).println(“Number is divisible by 10”).println("b is false"). It's not uncommon for even experienced programmers to write == when they mean = or vice versa.println("b is false").out. } To avoid this. } } } In Java numerical greater than and lesser than tests are done with the > and < operators respectively.out. that is something that evaluates to true or false.println(“Number is not divisible by 10”). Using the else statement class HelloProgram { public static void main(String args[]) { int x=10. if (b = false) { System.out. some programmers get in the habit of writing condition tests like this: boolean b = true. class HelloProgram { public static void main(String args[]) { int x=10. this causes a compiler error if you misuse the = sign when you mean to write ==.out.The arguments to a conditional statement like if must be a boolean value. } } 61 . Fortunately in Java. } else { System. if (false = b) { System. Integers are not permissible. you are not allowed to use == and = in the same places. if(x%10 == 0) { System. } Since you can't assign to a literal.out. if(x%10 == 0) { System. Therefore the compiler can catch your mistake and make you fix it before you can run the program.

boolean flag = true. Some forms are given below 1.out. if (flag2 < 0) { // Do something! } else { // Do something! } } else { // Do something! } Example: if (i == j) { if (j == k) System. } 62 .. if(condition){ // code to run if(condition){ // code to run } else { // other code to run } } 2. } else { System.out.else statement. if (flag) { int flag2 = 1.println("i doesn't equal j")..else statement into an if block or an else block.println("i equals k").else statement is writing an if. There can be any level of nested if. if(condition){ // code to run if(condition){ // code to run } } else{ // other code to run } 3.} Nested if/else statements Nested if..

out.out. break.out. break. } else if (testscore >= 70) grade = 'C'. break.out.println("January"). case 9: System. executes a statement based on another expression. break.4 The switch Statement Use the switch statement to conditionally perform statements based on an integer expression. 4. else if.out. break.println("August"). case 11: System.println("November").out. break. break. case 4: System. char grade.out. } else if (testscore >= 60) grade = 'D'. case 10: System. case 7: System. break. public class IfElseDemo { public static void main(String[] args) { int testscore = 76.println("February"). break. } } } 63 . case 2: System. public class SwitchDemo { public static void main(String[] args) { int month = 8. case 5: System.println("Grade = { { { } } " + grade).println("March").println("September").out. break. switch (month) { case 1: System. break. An if statement can have any number of companion else if statements but only one else. Another form of the else statement.out. case 6: System..println("April"). } else { grade = 'F'.out. case 12: System.out. if (testscore >= 90) { grade = 'A'.out.else if ladder The else block is executed if the if part is false.println("May"). case 8: System.println("December"). } else if (testscore >= 80) grade = 'B'.println("October").out. } System.if.println("July"). case 3: System. break.println("June").

int year = 2000. case 2: if (((year % 4 == 0) && !(year % 100 == 0)) 64 . That is.println("February").out. // and so on Deciding whether to use an if statement or a switch statement is a judgment call. break. based on readability and other factors. the case statements fall through. Each break statement terminates the enclosing switch statement. break. Also. .println("January").out. case 4: case 6: case 9: case 11: numDays = 30. whereas a switch statement can make decisions based only on a single integer value.The switch statement evaluates its expression. An if statement can be used to make decisions based on ranges of values or conditions. } . and executes the appropriate case statement. The break statements are necessary because without them. Another point of interest in the switch statement is the break statement after each case. if (month == 1) { System. control will flow sequentially through subsequent case statements. int month = 8. without an explicit break. int numDays = 0. the value provided to each case statement must be unique. in this case the value of month. switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31. public class SwitchDemo2 { public static void main(String[] args) { int month = 2. You can decide which to use. . and the flow of control continues with the first statement following the switch block. } else if (month == 2) { System.

|| (year % 400 == 0) ) numDays = 29; else numDays = 28; break;

} }

} System.out.println("Number of Days = " + numDays);

Technically, the final break is not required because flow would fall out of the switch statement anyway. However, we recommend using a break for the last case statement just in case you need to add more case statements at a later date. This makes modifying the code easier and less error-prone. Finally, you can use the default statement at the end of the switch to handle all values that aren't explicitly handled by one of the case statements. The variable or expression in the switch statement can be of only int or byte or short or char data types.

4.5 Branching Statements
The Java programming language supports three branching statements: • The break statement • The continue statement • The return statement label is an identifier placed before a statement. The label is followed by a colon (:): statementName: someJavaStatement;

4.5.1 The break Statement
The break statement has two forms: unlabeled and labeled. An unlabeled break terminates the enclosing switch statement, and flow of control transfers to the statement immediately following the switch. You can also use the unlabeled form of the break statement to terminate a for, while, or do-while loop.
public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; int searchfor = 12; int i = 0; boolean foundIt = false; for ( ; i < arrayOfInts.length; i++) { if (arrayOfInts[i] == searchfor) { foundIt = true;


} }


if (foundIt) { System.out.println("Found "+ searchfor +" at index "+ i); } else { System.out.println(searchfor + "not in the array"); } } }

The break statement terminates the labeled statement; it does not transfer the flow of control to the label. The flow of control transfers to the statement immediately following the labeled (terminated) statement.
public static void main(String[] args) { int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } }; int searchfor = 12; int i = 0; int j = 0; boolean foundIt = false; search: for ( ; i < arrayOfInts.length; i++) { for (j = 0; j < arrayOfInts[i].length; j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true; break search; } } } if (foundIt) { System.out.println("Found "+searchfor+" at "+i+", " + j); } else { System.out.println(searchfor + "not in the array"); } } }

4.5.2 The continue Statement


You use the continue statement to skip the current iteration of a for, while , or do-while loop. The unlabeled form skips to the end of the innermost loop's body and evaluates the boolean expression that controls the loop, basically skipping the remainder of this iteration of the loop. The labeled form of the continue statement skips the current iteration of an outer loop marked with the given label. A continue statement returns to the beginning of the innermost enclosing loop without completing the rest of the statements in the body of the loop. If you're in a for loop, the counter is incremented. For example this code fragment skips even elements of an array
for (int i = 0; i < m.length; i++) { if (m[i] % 2 == 0) continue; // process odd elements... }

The continue statement is rarely used in practice, perhaps because most of the instances where it's useful have simpler implementations. For instance, the above fragment could equally well have been written as
for (int i = 0; i < m.length; i++) { if (m[i] % 2 != 0) { // process odd elements... } }

continue with label
public class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true;


break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); } }

Here is the output from this program:
Found it

4.5.3 The return Statement
You use return to exit from the current method. The flow of control returns to the statement that follows the original method call. The return statement has two forms: one that returns a value and one that doesn't. To return a value, simply put the value (or an expression that calculates the value) after the return keyword:
return ++count;

The data type of the value returned by return must match the type of the method's declared return value. When a method is declared void, use the form of return that doesn't return a value:

4.6 Exception Handling Statements
The Java programming language provides a mechanism known as exceptions to help programs report and handle errors. When an error occurs, the program throws an exception. It means that the normal flow of the program is interrupted and that the runtime environment attempts to find an exception handler--a block of code that can handle a particular type of error. The exception handler can attempt to recover from the error or, if it determines that the error is unrecoverable, provide a gentle exit from the program. Three statements play a part in handling exceptions:
• •

The try statement identifies a block of statements within which an exception might be thrown. The catch statement must be associated with a try statement and identifies a block of statements that can handle a particular type of exception. The statements are executed if an exception of a particular type occurs within the try block. The finally statement must be associated with a try statement and identifies a block of statements that are executed regardless of whether or not an error occurs within the try block.

Here's the general form of these statements:


try { statement(s) } catch (exceptiontype name) { statement(s) } finally { statement(s) }

For controlling the flow of a program, the Java programming language has three loop constructs, a flexible if-else statement, a switch statement, exception-handling statements, and branching statements. Use the while statement to loop over a block of statements while a boolean expression remains true. Use the do-while statement to loop over a block of statements while a boolean expression remains true. The expression is evaluated at the bottom of the loop, so the statements within the do-while block execute at least once. The for statement loops over a block of statements and includes an initialization expression, a termination condition expression, and an increment expression The Java programming language has two decision-making statements: if-else and switch. The more general-purpose statement is if; use switch to make multiple-choice decisions based on a single integer value. Some branching statements change the flow of control in a program to a labeled statement. You label a statement by placing a legal identifier (the label) followed by a colon ( :) before the statemen. Use the unlabeled form of the break statement to terminate the innermost switch, for, while, or do-while statement. Use the labeled form of the break statement to terminate an outer switch, for, while, or do-while statement with the given label. A continue statement terminates the current iteration of the innermost loop and evaluates the boolean expression that controls the loop. The labeled form of the continue statement skips the current iteration of the loop with the given label. Use return to terminate the current method. You can return a value to the method's caller, by using the form of return that takes a value.

1. class Black {


public static void main(String args[]) { int[] i = {1,2,3,4,5}; long[] l = new long[5]; for (int j = 0; j < l.length(); j++) { l[j] = i[j]; } }

// // // //

1 2 3 4


A compile-time error is generated at which line? a. b. c. d. e. 1 2 3 4 None of the above


2. class MWC206 {


public static void main (String[] args) { int[][] a1 = {{1,2,3},{4,5,6},{7,8,9}}; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { System.out.print(a1[j][i]); } } }

What is the result of attempting to compile and run the program? a. Prints: 123456789 b. Prints: 147258369 c. Prints: 321654987
3. class JMM102 {

d. Prints: 369258147 e. Run-time error f. Compile-time error

g. None of the above

public static void main(String args[]) { for (int i = 0; i<5 ;i++) { switch(i) { case 0: System.out.print("v ");break; case 1: System.out.print("w "); case 2: System.out.print("x ");break; case 3: System.out.print("y "); case 4: System.out.print("z ");break; default: System.out.print("d "); } } } }

What is the result of attempting to compile and run the program? a. Prints: v w x y z b. Prints: v w x y z d c. Prints: v w x x y z z
4. class JMM105 {

d. Prints: v w w x y y z d e. Prints: d d d d d d f. Run-time error

g. Compile-time error h. None of the above

public static void main(String args[]) int x = 6; int success = 0; do { switch(x) { case 0: System.out.print("0"); case 1: System.out.print("1"); case 2: System.out.print("2"); case 3: System.out.print("3"); case 4: System.out.print("4");

x += 5; break; x += 3; break; x += 1; break; success++; break; x -= 1; break;


case 5: System.out.print("5"); x -= 4; break; case 6: System.out.print("6"); x -= 5; break; } } while ((x != 3) || (success < 2)); } }

What is the result of attempting to compile and run the program? a. Prints: 60514233 b. Prints: 6152433 c. Prints: 61433 d. Prints: 6143 e. Run-time error f. Compile-time error


The object can maintain private information and methods that can be changed at any time without affecting the other objects that depend on it. A software object maintains its state in one or more variables. A particular object is called an instance. Also. an object can be easily passed around in the system. The access level determines which other objects and classes can access that variable or method. Information hiding: An object has a public interface that other objects can use to communicate with it.1 What Is an Object? The real-world objects share two characteristics: They all have state and behavior. Packaging an object's variables within the protective custody of its methods is called encapsulation This conceptual picture of an object-a nucleus of variables packaged within a protective membrane of methods-is an ideal representation of an object and is the ideal that designers of object-oriented systems strive for. The object diagrams show that the object's variables make up the center. Encapsulating related variables and methods into a neat software bundle is a simple yet powerful idea that provides two primary benefits to software developers: • • Modularity: The source code for an object can be written and maintained independently of the source code for other objects. Software objects are modeled after real-world objects in that they too have state and behavior. You can represent real-world objects by using software objects. Methods surround and hide the object's nucleus from other objects in the program. A method is a function (subroutine) associated with an object. The following illustration is a common visual representation of a software object: Everything that the software object knows (state) and can do (behavior) is expressed by the variables and the methods within that object.Chapter 5 : Class Fundamentals and OOP 5. 73 . or nucleus. of the object. A software object implements its behavior with methods.

There is no concept of free standing code and even the most simple application involves the creation of a class. the bicycle is incapable of any activity. This information is passed along with the message as parameters. when you want to change gears on your bicycle. the receiving object needs more information so that it knows exactly what to do. all Java code occurs within a class. Instead.5. you have to indicate which gear you want. Through the interaction of these objects.3 What Is a Message? A single object alone is generally not very useful. The bicycle is useful only when another object (you) interacts with it (pedal). Sometimes. by itself. that defines the variables and the methods common to all objects of a certain kind.2 What Is a Class? A class is a blueprint. Your bicycle hanging from a hook in the garage is just a bunch of metal and rubber. The next figure shows the three parts of a message: 74 . Object is an instance of the class. object A sends a message to object B (see the following figure). programmers achieve higher-order functionality and more complex behavior. Software objects interact and communicate with each other by sending messages to each other. When object A wants object B to perform one of B's methods. for example. or prototype. The role of classes in Java Classes are the heart of Java. 5. an object usually appears as a component of a larger program or application that contains many other objects.

No other information or context is required.1 Encapsulation Encapsulation is the principal of keeping the internal details of a classes state and behaviours hidden from the other classes that use it. so (aside from direct variable access) message passing supports all possible interactions between objects. Objects don't need to be in the same process or even on the same machine to send and receive messages back and forth to each other. You do not want to 75 . and minimising it makes for more reusable and maintainable classes. Messages provide two important benefits. The expectated behaviour of a class or method is referred to as its 'contract'. 5. without breaking compatibility.4.• • • The object to which the message is addressed (YourBicycle) The name of the method to perform (changeGears) Any parameters needed by the method (lowerGear) These three components are enough information for the receiving object to perform the desired method. The interconnectness between pieces of code is called 'coupling'.   An object's behavior is expressed through its methods.  Encapsulation  Inheritance  Polymorphism  Abstraction 5.4 Features of Object Oriented Programming There are four features of OOP. This allows you to change those details where necessary.

poor quality. To achieve good encapsulation. road bikes. Mountain bikes. or you can end up with tangled interdependent code with poor maintainabilty. Similarly. Encapsulation involves hiding data of a class and allowing access only through a public interface. you would know that it had two wheels. objects are defined in terms of classes. Each subclass inherits state and behavior from the superclass. speed. and tandems share some states: cadence. each subclass inherits methods from the superclass.expose any more than the minimum required to support the contract. and tandems share some behaviors: braking and changing pedaling speed. In object-oriented terminology.4. Mountain bikes. road bikes. and tandems. Also. if we tell you it was a bicycle. You know a lot about an object by knowing its class. and tandems are all kinds of bicycles.if the internal details of a class are exposed and used. 5. mountain bikes. and pedals. Object-oriented systems take this a step further and allow classes to be defined in terms of other classes. and in all likelyhood. for example. 76 . the bicycle class is the superclass of mountain bikes. limit the access to prohibit it. handle bars. road bikes. This relationship is shown in the following figure. road bikes. road bikes. mountain bikes. make everything have the tightest possible access control so if something should not be used in a given context. it is very hard to substitute a different implementation of the same contract. Encapsulation also aids polymorphism and inheritance . Even if you don't know what a penny-farthing is.2 Inheritance Generally speaking. and the like. and tandems are all subclasses of the bicycle class. For example.

The specific action is determined by the exact nature of the situation. one for floating point values and one for characters. If we implemented a tricycle class. It could confuse users. In general. In an non-object-oriented-programming language. Inheritance offers the following benefits:  Subclasses provide specialized behaviors from the basis of common elements provided by the superclass. or class hierarchy. Subclasses can also override inherited methods and provide specialized implementations for those methods. such as an instance of a class or an array. Through the use of inheritance. multiple methods”. This means that it is possible to design a generic interface to a group of related activities.4. the farther down in the hierarchy a class appears. both tricycles and bicycles have a current speed and cadence — but because a tricycle is not a bicycle.However. the more specialized its behavior. The Object class is at the top of class hierarchy.3 Polymorphism The word polymorphism comes from the Greek for "many forms. programmers can reuse the code in the superclass many times. it might be convenient to make it a subclass of the bicycle class — after all. One stack is used for integer values. You might have a program that requires three types of stacks. even though the data being stored is different. subclasses are not limited to the state and behaviors provided to them by their superclass. Methods and variables are inherited down through the levels. The abstract superclass defines and may partially implement the behavior. The algorithm that implements each stack is same. Note: Class hierarchies should reflect what the classes are. Consider a stack. but much of the class is undefined and unimplemented. A variable of type Object can hold a reference to any object. However. Object provides behaviors that are required of all objects running in the Java Virtual Machine. make the tricycle class have methods (such as "change gears") that it doesn't need. Programmers can implement superclasses called abstract classes that define "generic" behaviors. This helps 77 . Other programmers fill in the details with specialized subclasses. with each set using different names. The concept of polymorphism is expressed by the phrase “one interface.  5. you would require three different sets of stack routines. and make updating or improving the tricycle class difficult." It allows one interface to be used for a general class of action. it's unwise to publicly tie the two classes together. in Java you can specify a general set of stack routines that all share same names. The inheritance tree. can be as deep as needed. because of polymorphism. Subclasses can add variables and methods to the ones they inherit from the superclass. and each class is its descendant (directly or indirectly).

. transmission. 5. It is the compiler’s job to select the specific action (i. 5. The declared type is an interface which the object's class implements: MyInterface myObject = new MyClass(). The declared type is a parent class of the object's class: MyParent myObject = new MyClass(). 5. They can ignore the details of how the engine. } //End of class definition. people do not think of a car as a set of tens of thousands of individual parts.5 Defining Classes The general syntax for defining a class in Java is shown below. They think of it as a well defined object with its own unique behavior. Polymorphism in Java is implemented with Method Overloading and Overriding. This syntax defines a class and creates a new type named MyClassName. You do not need to make the selection manually. You can also declare a variable on its own line.e method) as it applies to each situation. You need only remember to utilize the general interface.6 Creating Objects Declaring a Variable to Refer to an Object The declared type matches the class of the object: MyClass myObject = new MyClass(). . Instead they are free to utilize the object as a whole. and braking systems work.4. For example. such as: 78 . This abstraction allows people to use a car to drive to the grocery store without being overwhelmed by the complexity of thje parts that form the car. class MyClassName{ .reduce complexity by allowing the same interface to be used to specify a general class of action. Abstraction is hiding the irrelevant details and knowing only the relevant ones.4 Abstraction Humans manage complexity through abstraction.

Note: The phrase "instantiating a class" means the same thing as "creating an object". The name of the method is specified by name. The new operator requires a single. Instantiating a Class The new operator instantiates a class by allocating memory for a new object. A variable in this state. therefore "instantiating" a class. When you create an object. The parameter-list is a sequence of type and identifier pairs separated by commas. This can be any legal identifier other than those already used by other items within the current scope. including class types that you create. This can be any valid type. is said to hold a null reference. this reference is assigned to a variable of the appropriate type. The new operator returns a reference to the object it created. 5. the object is unreachable after the statement in which the new operator appears finishes executing.MyClass myObject. If the method has no parameters. Parameters are essentially variables that receive the value of the arguments passed to the method when it is called. The constructor initializes the new object. postfix argument: a call to a constructor. which currently references no object. The name of the constructor provides the name of the class to instantiate. If the method does not return a value. variable declaration alone does not actually create an object. The general form of a method is as follows: type name (parameter-list) { // body of method } The type specifies the return type of the method. you can think of the two as being synonymous. If the reference is not assigned to a variable.7 Defining Methods in a class Classes usually consists of two things: instance variables and methods. the value of myObject will be automatically set to null until an object is actually created and assigned to it. Method Declaration Elements Function (Optional) Access level for the method (Optional) Declares a class method Element accessLevel static 79 . you are creating an instance of a class. Often. then the parameter list will be empty. Remember. When you use this approach. its return type must be void.

abstract final native synchronized returnType methodName ( paramList ) throws exceptions

(Optional) Indicates that the method is not implemented (Optional) Indicates that the method cannot be overridden (Optional) Indicates that the method is implemented in another language (Optional) The method requires a monitor to run The method's return type and name The list of arguments to the method (Optional) The exceptions thrown by the method

Each element of a method declaration can be further defined and is discussed as indicated in the following list: accessLevel As with member variables, you control which other classes have access to a method using one of four access levels: public, protected, package, and private

As with member variables, static declares this method as a class method rather than an instance method.

An abstract method has no implementation and must be a member of an abstract class.

A final method cannot be overridden by subclasses

If you have a significant library of functions written in another language, such as C, you may wish to preserve that investment and to use those functions from a program written in the Java programming language. Methods implemented in another language are called native methods and are declared as such using the native keyword

Concurrently running threads often invoke methods that operate on the same data. Mark these methods with the synchronized keyword to ensure that the threads access information in a thread-safe manner. returnType A method must declare the data type of the value that it returns. If your method does not return a value, use the keyword void for the return type. methodName A method name can be any legal identifier. You need to consider code conventions, name overloading, and method overriding when naming a method.
( paramlist )

You pass information into a method through its arguments.


throws exceptionList

If your method throws any checked exceptions, your method declaration must indicate the type of those exceptions. Two of these components comprise the method signature: the method's name and the parameter list. Methods that have return type other than void return a value to the calling routine using the following form of return statement: return value; Here, value is the value returned. Let’s add a method to a Box class.
class Box { double width, height, depth; void volume() { System.out.println(“Volume is :”+ (width * depth * height)); } } class BoxDemo { public static void main(String args[]) { Box mybox1 = new Box(); mybox1.width = 10; mybox1.height = 20; mybox1.depth = 30; mybox1.volume(); } }

Naming a Method Although a method name can be any legal identifier, code conventions restrict method names. In general, method names should be verbs and should be in mixed case, with the first letter in lowercase and the first letter of each internal word in uppercase. Here are some examples:
toString compareTo isDefined setX getX


The JavaBeans architecture naming conventions further describe how to name methods for setting and getting properties. Passing information to a method The declaration for a method declares the number and the type of the arguments for that method or constructor. For example, the following is a method that computes the monthly payments for a home loan, based on the amount of the loan, the interest rate, the length of the loan (the number of periods), and the future value of the loan:
public double computePayment(double loanAmt, double rate, double futureValue, int numPeriods) { double I, partial1, denominator, answer; I = rate / 100.0; partial1 = Math.pow((1 + I), (0.0 - numPeriods)); denominator = (1 - partial1) / I; answer = ((-1 * loanAmt) / denominator) - ((futureValue * partial1) / denominator); return answer; }

This method takes four arguments: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer. As with this method, the set of arguments to any method or constructor is a comma-separated list of variable declarations, where each variable declaration is a type/name pair. As you can see from the body of the computePayment method, you simply use the argument name to refer to the argument's value. Argument Types You can pass an argument of any data type into a method. This includes primitive data types, such as doubles, floats, and integers, as you saw in the computePayment method, and reference data types, such as classes and arrays. Here's an example of a factory method that accepts an array as an argument. In this example, the method creates a new Polygon object and initializes it from a list of Points (assume that Point is a class that represents an x, y coordinate):
public Polygon polygonFrom(Point[] listOfPoints) { ... }

The Java programming language doesn't let you pass methods into methods. But you can pass an object into a method and then invoke the object's methods. Argument Names


When you declare an argument to a method, you provide a name for that argument. This name is used within the method body to refer to the data. The name of an argument must be unique in its scope. It cannot be the same as the name of another argument for the same method or constructor, the name of a local variable within the method or constructor, or the name of any parameter to a catch clause within the same method or constructor. An argument can have the same name as one of the class's member variables. If this is the case, the argument is said to shadow the member variable. Shadowing member variables can make your code difficult to read and is conventionally used only within methods that set a particular member variable. For example, consider the following Circle class and its setOrigin method:
public class Circle { private int x, y, radius; public void setOrigin(int x, int y) { ... } }

The Circle class has three member variables: x, y, and radius. The setOrigin method accepts two arguments, each of which has the same name as one of the member variables. Each method argument shadows the member variable that shares its name. So using the simple names x or y within the body of the method refers to the argument, not to the member variable. To access the member variable, you must use a qualified name. Returning a Value from a Method You declare a method's return type in its method declaration. Within the body of the method, you use the return statement to return the value. Any method declared void doesn't return a value and cannot contain a return statement. Any method that is not declared void must contain a return statement. Let's look at the isEmpty method in the Stack class:
public boolean isEmpty() { if (items.size() == 0) { return true; } else { return false; } }

The data type of the return value must match the method's declared return type; you can't return an integer value from a method declared to return a boolean. The declared return type for the isEmpty method is boolean, and the implementation of the method returns the boolean value true or false, depending on the outcome of a test.


The isEmpty method returns a primitive type. A method can return a reference type. For example, Stack declares the pop method that returns the Object reference type:
public Object pop() { if (top == 0) { throw new EmptyStackException(); } Object obj = items[--top]; items[top]=null; return obj; }

When a method uses a class name as its return type, such as pop does, the class of the type of the returned object must be either a subclass of or the exact class of the return type. Suppose that you have a class hierarchy in which ImaginaryNumber is a subclass of java.lang.Number, which is in turn a subclass of Object, as illustrated in the following figure.

Now suppose that you have a method declared to return a Number:
public Number returnANumber() { ... }

The returnANumber method can return an ImaginaryNumber but not an Object. ImaginaryNumber is a Number because it's a subclass of Number. However, an Object is not necessarily a Number — it could be a String or another type. You also can use interface names as return types. In this case, the object returned must implement the specified interface.

5.8 Declaring Variables in a Class

uses the following line of code to define its variables:
class Stack { int top; }

This code declares member variable and not other types of variable, such as local variable, because the declaration appears within the class body but outside any methods.


accessLeve l static final transient volatile type name

Variable Declaration Elements Function (Optional) Access level for the variable (Optional) Declares a class variable (Optional) Indicates that the variable is a constant (Optional) Indicates that the variable is transient (Optional) Indicates that the variable is volatile The type and name of the variable

Each component of a member variable declaration is further defined and discussed in later sections of this chapter, as follows: accessLevel Lets you control what other classes have access to a member variable by specifying one of four access levels: public, protected, package, and private.

Declares this is a class variable rather than an instance variable.

Indicates that the value of this member cannot change.

Marks member variables that should not be serialized.

Prevents the compiler from performing certain optimizations on a member type Like other variables, a member variable must have a type. You can use primitive type names such as int, float, or boolean. Or you can use reference types, such as array, object, or interface names. name A member variable's name can be any legal identifier and, by convention, begins with a lowercase letter. A member variable cannot have the same name as any other member variable in the same class.

Automatic local variables Automatic variables are method variables. They come into scope when the method code starts to execute and cease to exist once the method goes out of scope. As they are only visible within the


method they are typically useful for temporary manipulation of data. If you want a value to persist between calls to a method then a variable needs to be created at class level. Variable Initialization Local variables and member variables can be initialized with an assignment statement when they're declared. Local variables have to explicitly initialized before their use. The data type of the variable must match the data type of the value assigned to it.
char aChar = 'S'; boolean aBoolean = true;

Parameters and exception-handler parameters cannot be initialized in this way. The value for a parameter is set by the caller. Variable Scope A variable's scope is the region of a program within which the variable can be referred to by its simple name. Secondarily, scope also determines when the system creates and destroys memory for the variable. Scope is distinct from visibility, which applies only to member variables and determines whether the variable can be used from outside of the class within which it is declared. Visibility is set with an access modifier. The location of the variable declaration within your program establishes its scope and places it into one of these four categories:
• • • •

member variable local variable method parameter exception-handler parameter

A member variable is a member of a class or an object. It is declared within a class but outside of any method or constructor. A member variable's scope is the entire declaration of the class. However, the declaration of a member needs to appear before it is used when the use is in a member initialization expression.


You declare local variables within a block of code. In general, the scope of a local variable extends from its declaration to the end of the code block in which it was declared. The scope of each variable in that program extends from the declaration of the variable to the end of the main method --indicated by the first right curly bracket } in the program code. Parameters are formal arguments to methods or constructors and are used to pass values into methods and constructors. The scope of a parameter is the entire method or constructor for which it is a parameter. Exception-handler parameters are similar to parameters but are arguments to an exception handler rather than to a method or a constructor. The scope of an exception-handler parameter is the code block between { and } that follow a catch statement.
if (...) { int i = 17; ... } System.out.println("The value of i = " + i);

// error

The final line won't compile because the local variable i is out of scope. The scope of i is the block of code between the { and }. The i variable does not exist anymore after the closing }. Either the variable declaration needs to be moved outside of the if statement block, or the println method call needs to be moved into the if statement block.

5.9 Instance and Class Members
When you declare a member variable such as aFloat in MyClass:
class MyClass { float aFloat; }

you declare an instance variable. Every time you create an instance of a class, the runtime system creates one copy of each the class's instance variables for the instance. Instance variables are in constrast to class variables (which you declare using the static modifier). The runtime system allocates class variables once per class regardless of the number of instances created of that class. The system allocates memory for class variables the first time it encounters the class. All instances share the same copy of the class's class variables. You can access class variables through an instance or through the class itself. Methods are similar: your classes can have instance methods and class methods. Instance methods operate on the current object's instance variables but also have access to the class variables. Class methods, on the other hand, cannot access the instance variables declared within the class (unless it creates a new object and accesses them through the object). Also, class methods can be invoked on the class, you don't need an instance to call a class method.


the code is manipulating two different copies of x: the one contained in the myX object and the one contained in the anotherX object. . } public void setX(int newX) { x = newX. "if all instances of AnIntegerNamedX share the same implementation of x() and setX() isn't this ambiguous?" The answer is no. It creates two different objects of type AnIntegerNamedX. all instances of AnIntegerNamedX share the same implementation of x() and setX().println("anotherX. the name of an instance variable refers to the current object's instance variable (assuming that the instance variable isn't hidden by a method parameter).x()). . Notice that the code used setX() to set the x value for myX but just assigned a value to anotherX. anotherX. myX. AnIntegerNamedX myX = new AnIntegerNamedX(). refer to the object's instance variable x by name. System.out.x = " + anotherX. Suppose that this code snippet was in another object's method. System. All instances of a class share the same implementation of an instance method. These copies are associated with the new object. The output produced by this code snippet is: myX. } } Every time you instantiate a new object from a class. Objects outside of AnIntegerNamedX that wish to access x must do so through a particular instance of AnIntegerNamedX.x = 2. Either way. The class defined below has one instance variable--an integer named x--and two instance methods--x() and setX()--that let other objects set and query the value of x: class AnIntegerNamedX { int x.setX(1). Within an instance method. you ask.x = 1 anotherX. "But".out. public int x() { return x. unless otherwise specified. x() and setX(). So. Note that both methods. you get a new copy of each of the class's instance variables.x directly. a member declared within a class is an instance member. AnIntegerNamedX anotherX = new AnIntegerNamedX(). .x()).x = 2 88 . sets their x values to different values. every time you instantiate a new AnIntegerNamedX object from the class.By default.println("myX. then displays them: .x = " + myX. . . you get a new copy of x that is associated with the new AnIntegerNamedX object.

when declaring a member variable. You use class variables for items that you need only one copy of and which must be accessible by all objects inheriting from the class in which the variable is declared. Let's change the AnIntegerNamedX class such that its member variable x is once again an instance variable. let's change the AnIntegerNamedX class such that its x variable is now a class variable: class AnIntegerNamedX { static int x. Similarly. you can specify that a method is a class method rather than an instance method. All instances of that class share the same copy of the class variable. } } Now the exact same code snippet from before that creates two instances of AnIntegerNamedX. specify that the variable is a class rather than an instance variable. You can. For example. use the static keyword. output. when declaring a method. To specify that a method is a class method. public int x() { return x. and its two methods are now class methods: class AnIntegerNamedX { 89 . Class methods can only operate on class variables and cannot access the instance variables defined in the class. use the static keyword in the method declaration. When you invoke setX() on either instance. } public void setX(int newX) { x = newX. The system creates a single copy of a class variable the first time it encounters the class in which the variable is defined. you change the value of x for all instances of AnIntegerNamedX. Class methods can only operate on class variables--they cannot access the instance variables defined in the class. Similarly. myX.x = 2 The output is different because x is now a class variable so there is only one copy of the variable and it is shared by all instances of AnIntegerNamedX including myX and anotherX. class variables are often used with final to define constants (this is more memory efficient as constants can't change so you really only need one copy). For example. you can specify that method to be a class method rather than an instance method.x = 2 anotherX.showing that each instance of the class AnIntegerNamedX has its own copy of the instance variable x and each x has a different value. and then displays them produces this. different. To specify that a member variable is a class variable. sets their x values.

} private int x. return x. Another difference between instance members and class members is that class members are accessible from the class itself.x = 2 Again. You don't need to instantiate a class to access its class members. static public int x() { return x. you will get compiler errors: AnIntegerNamedX. changing x through myX also changes it for other instances of AnIntegerNamedX. x = newX.java:7: Can't make a static reference to nonstatic variable x in class AnIntegerNamedX. } static public void setX(int newX) { x = newX.x = 2 anotherX. ^ 2 errors This is because class methods cannot access instance variables unless the method created an instance of AnIntegerNamedX first and accessed the variable through it. } static public void setX(int newX) { x = newX. ^ AnIntegerNamedX. static public int x() { return x. sets their x values. and then prints the x values produces this output: myX. } When you try to compile this version of AnIntegerNamedX. Let's fix AnIntegerNamedX by making its x variable a class variable: class AnIntegerNamedX { static private int x. Let's rewrite the code snippet from before to access x() and setX() directly from the AnIntegerNamedX class: 90 .java:4: Can't make a static reference to nonstatic variable x in class AnIntegerNamedX. } } Now the class will compile and the same code snippet from before that creates two instances of AnIntegerNamedX.

out. Default Values of Variables Type boolean byte char short int long float double Object Array Default value false 0 '\u0000' 0 0 0l 0.println(" Local array ref: " + a[3]). // local variable int[] a = new int[5].x = " + AnIntegerNamedX. .out.out.0d null based on Array type Field variables (class members) are automatically initialized to default values. you can only invoke instance methods from an object and can only access instance variables from an object.x()).. // field array reference variable static String[] s = new String[10]. // local variable array // causes compile error if not explicitly initialized j = 10. System.println(" Local variable: " + j). System. You cannot do this with instance members. Arrays. .out. whether field or local variables.println("AnIntegerNamedX. . 91 . Local variables (method or constructor variables) are not automatically initialized. } public static void main(String[] args) { System. class CheckInit { // field variable static int i.println("Field variable i: " + i). . static void myMethod(){ int j.setX(1). Notice that you no longer have to create myX and anotherX. .0f 0. are automatically initialized to the default values of their declared type. You can access class variables and methods either from an instance of the class or from the class itself. You can set x and retrieve x directly from the AnIntegerNamedX class. System. AnIntegerNamedX.

The code is executed in the same order as it is declared in the class. 3. it doesn't need to specify a return type. parameters don't make any sense. } } Output of CheckInit: Field Field Local Local variable i: 0 array ref: null variable: 10 array ref: 0 // default value of int // default value for String[] // explicit value // default value of int[] 5. 5. when the class is loaded. Because it is executed automatically when the class is loaded. } // Static initializer block static { System. 13. 10. The following code illustrates the use of a static initializer block: 1. and no return type. It doesn't need a name. myMethod(). The code in a static initializer block is executed only once.out.10 Static Initializer A static initializer block resembles a method with no name. Therefore. a static initializer block cannot contain a return statement.println("2::str = " + str).out. public TestStaticInitializer() { System. because there is no need to refer to it from outside the class definition.out. 14. static { } Static initializers are blocks of code within a class that are outside the scope of a method.println("1::str = " + str). 7. 15. 8. public class TestStaticInitializer { static String str = "Default".System. 9. 2. Like a constructor. so a static initializer block doesn't have an argument list. The code in a static initializer block is executed by the virtual machine when the class is loaded. 6. no arguments. } // Main routine to test the class public static void main(String[] args) { 92 . 12. str = "Static". 4. 11.println(" Field array ref: " + s[2]).

x = " + TestShadowing. Static initializer blocks may be used for executing code that initializes the state of the object or for providing debugging functionality. overuse of this feature can lead to complex and unreadable code. // field variable public static void main(String[] args) { int x = 0.println("TestShadowing. Multiple static initializer blocks You may include any number of static initializer blocks in your class definition. A static string is declared on Line 2 and set to "Default.x = 1 because the identifier x is used within a code block main() a search is made for a declaration of x within the body of main().out. the simple identifier name x is assumed to be within scope as a local variable. } } TestStaticInitializer tsi = new TestStaticInitializer(). 5. 93 .11 Variable Shadowing A field declaration can be shadowed by a local variable declaration class TestShadowing { static int x = 1. The code in static initializer blocks is always executed when the class is loaded and before any method in the class is executed.x) } } Output: x = 0 TestShadowing." Next. 17. However. The output of this program is: 2:: str = Default 1:: str = Static When the class is loaded (because it was constructed) on line 17. int x = 0. // local variable System. The static initializer blocks will be executed in the order in which they appear in the code. System. As one is found.out. lines 9-12 are executed before the constructor is called. Only static members can be referenced within static initializer.println("x = " + x). The constructor on Lines 4-6 merely prints the variable out. a static initializer block prints the string out and resets it to the value "Static" on Lines 8-12.16. 18.

class AClass { int j = 1. a1. . int i = 2. Modify Reference Variables 94 . int m = i. in method arguments.To access the field variable x. it has no affect whatsoever on variable i the code on the left. The following shows code on top that creates an instance of AClass and invokes the aMethod with an int argument. That is..12 Pass by value and Pass by reference Primitive data type operations deal only with value. k = 5. For example. i's value passes to j i = 2. // j still holds "1" Similarly. // m = i = 2 not 5 . primitive variables pass by value. a data value passes and not a reference or pointer to a data location.. j = k * 10. int i = 1. int j = i.x 5. you must use its fully-qualified name TestShadowing. The code on the bottom shows the AClass definition and the aMethod. When that method assigns a value of 5 to k. a copy is made and passed to the method. // Now j holds "1" // that is. } } The value in variable i in the code on the left will be passed to variable k in the aMethod argument list. AClass a1 = new AClass ().. the following code shows that assigning primitive data variable i to another named j simply passes a copy of the value in i into j.. void aMethod (int k) { int i = 10 * k.aMethod (i). Changes to the passed value do not affect the variable in the calling code. That is.

For example. Then we assign the "b" object to the "a" reference with the a=b.. statement. That is. the JVM makes a copy of the internal memory pointer and the copy of the pointer goes into the argument value.. AClass a. in the following code. "a" and "b". Note that assigning a new object to the "a" variable orphans the original object that "a" pointed to previously. However. a.j = 400. References in Method Arguments The argument list of a method can include object references.You can always assign a new object to a reference variable. // x = 400 since a and b now // reference same object. we create two instances of the AClass.j. then the garbage collector will eventually reclaim the memory that it occupies. . b = new AClass ().. public class AClass { public int j = 1. the reference itself passes by value. } } // a now references same // object as does the b variable.j = 40. So both the "a" and "b" variables now reference the same object. and then assign new values to the "j" variable for each object: . a. 95 . a = new AClass (). So if the reference variable in the method is set to a new object. k = 5. int x = b.. b. The methods and data of that object can be accessed and modified by the method. j = k * 10.j = 4. If an object is no longer referenced by any other variables.b. void aMethod (int k) { int i = 10*k. a = b. that will have no affect on the reference variable in the calling method.

. } Since reference variables only hold pointers. AClass a. simply tests whether a and b point to the same object. class AClass { void aMethod (BClass bb) { bb.j = 100. b = new BClass ().. In that method..j = 20. j = b. } } class BClass { int j = 0.j = 5. in the following code. . a = new AClass (). many classes provide an "equals()" method such that a. the argument variable is assigned to a new instance of the BClass.. However. the test if (a == b). the original reference remains unaffected. bb. a. when the process returns to the calling code. 96 .aMethod (b).For example. int i = 2. BClass b. bb= new BClass ().// j = 20 not 5 or 100 . b.j..equals(b) returns true if the object b data matches that in object a.. not if the referenced objects have equal data values. If you need to test whether two objects hold the same data values. a reference to a BClass object passes to the method of a AClass object.

. and blue member variables of its RGBColor argument: public class Pen { private int redValue. aColor. greenValue. //This method does not work as intended. green = greenValue. . and blue variables exist only within the scope of the getRGBColor method. } Now we can rewrite getRGBColor so that it accepts an RGBColor object as an argument. The getRGBColor method returns the current color of the pen by setting the red. Let's rewrite the getRGBColor method so that it does what was intended. aColor.. blueValue. When that method returns. greenValue. public void getRGBColor(RGBColor aColor) { aColor.13 Access Control Access or visibility rules determine whether a method or a data variable can be accessed by another method in another class or subclass. and blue values of a color in RGB space: public class RGBColor { public int red. . blue = blueValue. blue. } } The changes made to the RGBColor object within the getRGBColor method persist after the method returns. green. RGBColor. This method is attempting to return three values by setting the values of its arguments: public class Pen { private int redValue.green = greenValue. int green. that can hold the red.red = redValue. First. we need a new type of object. those variables are gone and any changes to them lost.. int blue) { red = redValue.blue = blueValue. green. blueValue. green.. public void getRGBColor(int red. because aColor is a reference to an object that exists outside the scope of the method. } } This simply does not work. 5. Java provides for 4 access modifiers : 97 . green.Let's look at a method called getRGBColor within a class called Pen. The red.

Second. Modifier public Used with Classes Interfaces Constructors Inner Classes Methods Field variables Constructors Inner Classes Methods Field variables Constructors Inner Classes Methods Field variables Classes Interfaces Constructors Inner Classes Methods Description A Class or Interface may be accessed from outside its package. Even methods in subclasses in the same package do not have access.1. you need to decide what access level every member variable and every method in your class should have.accessible by the package classes and any subclasses that are in other packages . Methods and Field variables may be accessed from wherever their class is accessed. Also. 3.accessible only within the class. such as naming methods. such as the classes in the Java platform.access by any other class anywhere. May only be accessed from within the package in which they are declared. Constructors. By making some of your data and methods private. access levels determine which members of those classes your classes can use. when you write a class. if you distribute new versions of your classes at a later point. Inner Classes. protected May be accessed by other classes in the same package or from any subclasses of the class in which they are declared. you can prevent the subclass code from interfering with the internal workings of your classes. when you use classes that come from another source. private no modifier 98 . private . 4. you can change or eliminate these private attributes and methods without worrying that these changes will affect the subclasses. For example. Access levels affect you in two ways. public . You need to put as much effort into deciding the access level for a member as you put into making other decisions about your class's API.(also known as "package private") accessible to classes in the same package but not by classes in other packages. protected . 2. May be accessed only from within the class in which they are declared. First. even if these are subclasses. These access rules allow one to control the degree of encapsulation of your classes. you may distribute your class files to other users who can make subclasses of them. Default . One way of thinking about access levels is in terms of the API: access levels directly affect the public API of a class and determine which members of the class can be used by other classes.

}//End of main } If the constructors are declared private then the object of that class can be created only in that class. This means they are NOT visible within sub classes. } } class Enc{ public static void main(String argv[]){ Base b = new Base(). } else { System.setEnc(20).iEnc = 20. 99 . b. Public The public modifier can be applied to a variable (field) or a class. and an instance can be created from anywhere within or outside of a program. Using the public modifier with a variable makes it available from anywhere. }//End if } public static void main(String args[]) { Base b=new Base(). Only one non inner class in any file can be defined with the public keyword. This allows a variable to be insulated from being modified by any methods except those in the current class.Field variables Private Private variables are only visible from within the same class as they are created in. It cannot be created outside the class definition. b. //compile-time error b. public void setEnc(int iEncVal){ if(iEncVal < 1000){ iEnc=iEncVal. It is the first modifier you are likely to come across in learning Java.iEnc = 20.out. class Base{ private int iEnc=10. public int myint =10. It is used as follows.println("Enc value must be less than 1000"). A public class has global scope. If you define more than one non inner class in a file with the keyword public the compiler will generate an error.

The name of the class file should be same as that of the public class. Take the example where you had a variable used to store the age of a student. The public classes should be stored in separate class files. The visibility modifiers are a key part of the encapsulation mechanism for java. The benefit of this is that the details of the code inside a class can be changed without it affecting other objects that use it. The naming convention for these methods are setFoo to change a variable and getFoo to obtain the contents of a variable. Encapsulation allows separation of the interface from the implementation of methods. A variable defined with no access modifier is said to have default visibility. These methods are known as a accessor and mutator methods.java file can contain multiple classes but only one public class. b.iNoEnc).iNoEnc=2. Any class in the same directory is considered to be in the default package. An aside note: the use of get and set in the naming of these methods is more significant than just programmer convenience and is an important part of the Javabeans system.If you want to create a variable that can be modified from anywhere you can declare it as public. } class NoEnc{ public static void main(String argv[]){ Base b = new Base(). Encapsulation generally takes form of methods to retrieve and update the values of private class variables. The qualification that it is visible from the same package can give more visibility than you might suspect. }//End of main } One . You can then access it using the dot notation similar to that used when calling a method. The accessor (or get) method retrieves the value and the mutator changes (or sets) the value. and in sub classes. Default visibility means a variable can be seen within the class. the same package but not elsewhere. 100 . and from elsewhere within the same package. Protected A protected variable is visible within a class.println(b. but not from sub-classes that is not in the same package. Access Modifiers and encapsulation The visibility modifiers are part of the encapsulation mechanism for Java. This means that a protected variable is more visible than a variable defined with no access modifier. System. class Base { public int iNoEnc=77. and thus protected classes will be visible. Encapsulation allows separation of the interface from the implementation of methods.out. This is a key concept of the Object Oriented paradigm.

The setAge method might take an integer parameter and update the private value for Age and the getAge method would take no parameter but return the value from the private age field. So wherever your programs change the age value. you write if statements that check for the range. The Object Oriented approach to this problem using encapsulation.14 Constructors Classes have a special method called a constructor that is called implicitly when a class instance is created. Note: If you do not write your own constructor. The default constructor initializes all non-initialized fields and variables to zero. with names like setAge and getAge. can be changed whilst the way it looks to the outside world (the interface) remains the same. } At first this seems a little pointless as the code seems to be a long way around something that could be done with simple variable manipulation.You might store it simply with a public integer variable int iAge. The empty constructor is called the default constructor. By this approach the implementation of code. the compiler adds an empty constructor. } public int getAge(){ return iAge. is to create methods that access a private field containing the age value. public void setAge(int iStudentAge){ iAge = iStudentAge. (the actual lines of program code). which calls the no-arguments constructor of its parent class. 101 . if(iAge > 70){ //do something } if (iAge <3){ //do something } In the process of doing this you miss some code that used the iAge variable and you get called back because you have a 19 year old student who is on your records has being 190 years old. You are asked to put in code to check for these error conditions. 5. The class constructor always has the same name as the class and no return type. However when they come back to you with the requirement to do more and more validation on the iAge field you can do it all in these methods without affecting existing code that uses this information. later when your application is delivered you find that some of your students have a recorded age of more than 200 years and some have an age of less than zero.

out.println(retrievedText).If you create constructors of your own. The following example illustrates code that will not compile. Thus as soon as you create any constructors for a class you need to create a zero parameter constructor. } public static void main(String[] args){ LessonTwoD progInst = new LessonTwoD(). //Constructor LessonTwoD(){ text = "I'm a Simple Program".e.println("single int constructor"). } } //This will compile 102 . String retrievedText = progInst. } } public class Cons { public static void main(String argv[]){ Base c = new Base().getText(). } //Accessor method String getText(){ return text. Java does not supply the default zero parameter constructor class LessonTwoD { String text. class Base{ Base(int i){ System. If you then try to create an instance of the class without passing any parameters (i. This can be fixed by creating a "do nothing" zero parameter constructor in the class Base. invoking the class with a zero parameter constructor). } } As soon as you create any constructors of your own you loose the default no parameter constructor.out. //Warning: will not compile. Because Base has an integer constructor the zero parameter constructor is not available and a compile time error occurs. When the compiler checks to create the instance of the Base class called c it inserts a call to the zero parameter constructor. System. you will get an error.

drawInteger. the following constructor for the HSBColor class initializes the object's member variables according to the arguments passed into the constructor. and so on. Each argument to the constructor hides one of the object's member variables. which means that multiple methods in the same class can share the same name if they have different parameter lists. 5. synchronized or final. drawFloat. you can use the same name for all the drawing methods but pass a different type of argument to each method. In the Java programming language.15 The this keyword Within an instance method or a constructor.class Base{ Base(int i){ System. } } Constructors cannot be native. you have to think of a new name for each method. this is a reference to the current object — the object whose method or constructor is being called.hue = hue. int brightness) { this. Thus. abstract.println("single int constructor"). each of which takes a different type of argument.saturation = saturation. this. for example. } } this keyword cannot be used in a static reference.16 Overloading The Java programming language supports name overloading for methods. } Base(){} } public class Cons { public static void main(String argv[]){ Base c = new Base(). drawString.brightness = brightness. 5. Suppose that you have a class that can draw various types of data (strings. static. and so on) and that contains a method for drawing each data type. brightness. int saturation. In other languages.out. this. integers. 103 . For example. the data drawing class might declare three methods named draw. You can refer to any member of the current object from within an instance method or a constructor by using this. saturation. so this constructor must refer to the object's member variables through this: public class HSBColor { private int hue. public HSBColor (int hue. The most common reason for doing so is that a member variable is hidden by an argument to the method or the constructor.

The compiler does not consider return type when differentiating methods. Thus imagine you were designing the interface for a system to run mock Java certification exams. Thus a overloading allows the same method name to have multiple meanings or uses. 104 .. Overloading is a one of the ways in which Java implements one of the key concepts of Object orientation... It would be more useful if you could use a single method name and the compiler would resolve what actual code to call according to the type and number of parameters in the call. because the compiler cannot tell them apart. The method call is resolved during the compile-time hence it uses static or early binding. In the code sample....public class DataArtist { .. a boolean or a text string. so you cannot declare two methods with the same signature even if they have a different return type.. draw(String s) and draw(int i) are distinct and unique methods because they require different argument types. polymorphism. markanswerboolean(boolean answer){ } markanswerint(int answer){ } markanswerString(String answer){ } This would work but it means that future users of your classes have to be aware of more method names than is strictly necessary. You cannot declare more than one method with the same name and the same number and type of arguments. } public void draw(float f) { . public void draw(String s) { . An answer may come in as an integer. } public void draw(int i) { . You could create a version of the method for each parameter type and give it a matching name thus. Polymorphism is a word constructed from Poly meaning "many" and "morphism" implying meaning. } } Overloaded methods are differentiated by the number and the type of the arguments passed into the method.

boolean a) { i = j. A second constructor passes an initial value to just one of the variables. but this time indicating that a method cannot be redefined with a different return type. type and order of parameters. } 105 . } int get() { return i. Thus changing one of the above to have an int return value will still result in a compile time error. class Test { int i.The following is not an example of overloading and will cause a compile time error indicating a duplicate method declaration. } This constructor initializes the two properties to the values passed as arguements. That is something to worry about with overriding. Overloaded methods are differentiated only on the number. void markanswer(String answer){ } void markanswer(String title){ } The return type does not form part of the signature for the purpose of overloading. b = a. } Test(int j) { i = j. Test(int j. Overloaded methods do not have any restrictions on what exceptions can be thrown. not on the return type of the method Overloading Constructors You can define multiple constructors to provide optional ways to create and initialize instances of the class. boolean b=true.

using 0s as default values. this. Doing so is called an explicit constructor invocation. The constructors provide a default value for any member variable whose initial value is not provided by an argument. int width. int y. //A simple example of recursion class Factorial { //this is a recursive function int fact(int n) { int result. the compiler determines which constructor to call. the code Test ex = new Test(). you can also use the this keyword to call another constructor in the same class. A method that calls itself is said to be recursive. 0).height = height. 106 . public class Rectangle { private int x. } public Rectangle(int width. Each constructor initializes some or all of the rectangle's member variables. Recursion is an attribute that allows a method to call itself..17 Recursion Recursion is a process of defining something in terms of itself. Use of this() From within a constructor. If present. So for the class shown above. As before. } public Rectangle(int x. the java compiler does not create the default constructor. based on the number and the type of arguments. 0. this. an explicit constructor invocation must be the first line in the constructor. y. this. int height) { this(0. 0. } This class contains a set of constructors. the no-argument constructor calls the four-argument constructor. will generate a compiler error stating that no such constructor exists. private int width. height. 0. width. height).y = y.Note that if a class includes one or more explicit constructors.width = width. public Rectangle() { this(0.. 5. } . int height) { this.x = x. For example.

when using arrays that contain objects. Thus the following would call an external routine. However.out. you can create an array without putting any elements in it.toLowerCase()).fact(3)). written perhaps in C++. System. ArrayOfStringsDemo that creates an array containing three string objects then prints the strings in all lower case letters.length. public native void fastcalc(). } } } This program creates and populates the array in a single statement. The implementation of native is out of the scope of this course.18 Native Methods The native modifier is used only for methods and indicates that the body of the code is written in a language other than Java such as C or C++. i++) { System. Another reason is where greater performance is required. i < anArray. Native methods are often written for platform specific purposes such as accessing some item of hardware that the Java Virtual Machine is not aware of. result = fact(n-1) * n.19 Arrays of Objects Arrays can hold reference types as well as primitive types.} } if(n == 1) return 1. A native method ends with a semicolon rather than a code block. 5. class Recursion { public static void main(String args[]) { Factorial f = new Factorial().println(“Factorial of 3 is “+f.out. for (int i = 0. often encountered by new programmers. You create such an array in much the same way you create an array with primitive types. This brings us to a potential stumbling block. Here's a small program. return result. Consider this line of code: 107 .println(anArray[i]. "String Two". "String Three" }. } } 5. public class ArrayOfStringsDemo { public static void main(String[] args) { String[] anArray = { "String One".

j < cartoons[i].print(cartoons[i][j] + " "). "Fred". "Shaggy". After this line of code is executed. “Astro" }. which generates a NullPointerException: String[] anArray = new String[5]. } System.out. 5. "Barney". The program must explicitly create strings and put them in the array. "Rosie". Such a class is called a nested class and is illustrated here: 108 . for (int i = 0. { "Rubbles". "Fred". "Betty".20 Nested and Inner Classes You can define a class as a member of another class. for (int j = 1. It is empty. "Elroy". "Wilma". The names of the sub-arrays are cartoons[0]. cartoons[1].print(cartoons[i][0] + ": "). i++) { System. many beginners assume that the previous line of code creates the array and creates 5 empty strings in it. "Daphne" } }.println(). and so on. "Scooby Doo". "Velma".toLowerCase()). { "Scooby Doo Gang". j++) { System. public class ArrayOfArraysDemo { public static void main(String[] args) { String[][] cartoons = { { "Flintstones". { "Jetsons". "George". however. } } } Notice that the sub-arrays are all of different lengths. "Bam Bam" }.out. i++) { // ERROR: the following line gives a runtime error System. the array doesn't contain any strings yet. "Dino" }. "Jane". } Arrays of Arrays ArrayOfArraysDemo creates an array and uses an initializer to populate it with four sub-arrays. However.length. "Pebbles".String[] anArray = new String[5]. the array called anArray exists and has enough room to hold 5 string objects.println(anArray[i].length.length. for (int i = 0. This might seem obvious. "Judy". Thus they end up writing code like the following.out. i < cartoons. i < anArray.out.

like this: public class WireFrameModel { . 109 . class EnclosingClass { . The nested class is inside its enclosing class so that it has access to its enclosing class's members. The access specifiers restrict access to members for classes outside the enclosing class. } } You use nested classes to reflect and to enforce the relationship between two classes.y1. // other members of the WireFrameModel class static public class Line { // Represents a line from the point (x1. static class StaticNestedClass { . The definition of the WireFrameModel class with its nested Line class would look. y2.. Then. class ANestedClass { ..class EnclosingClass { .z2) in 3-dimensional space. It is fully consistent with the meaning of private and the other access specifiers. in outline. .Line. z2. y1.. the Line class would be referred to as WireFrameModel. A static nested class is called just that: a static nested class. outside of the class WireFrameModel... } } For example. } class InnerClass { . You should define a class within another class when the nested class makes sense only in the context of its enclosing class or when it relies on the enclosing class for its function. Like other members. However. that represents a single line..z1) // to the point (x2.. double x1. Line. .y2. For example. this special privilege isn't really special at all.. (Such models are used to represent three-dimensional objects in graphics programs. A nonstatic nested class is called an inner class. a nested class has a special privilege: It has unlimited access to its enclosing class's members. z1.. Of course. As a member of its enclosing class. double x2.) Suppose that the WireFrameModel class contains a static nested class. suppose a class named WireFrameModel represents a set of lines in threedimensional space.. a text cursor might make sense only in the context of a text component. this just follows the normal naming convention for static members of a class. a nested class can be declared static (or not). even if they are declared private.

. an inner class is associated with an instance of its enclosing class and has direct access to that object's instance variables and methods.. Consider the following classes: class EnclosingClass { . And like class methods. class InnerClass { . . Rather. To help further differentiate the terms nested class and inner class. 110 . The next figure illustrates this idea. A static nested class has full access to the members of the containing class. As with static methods and variables. The term nested class reflects the syntactic relationship between two classes. } } The interesting feature about the relationship between these two classes is not that InnerClass is syntactically defined within EnclosingClass. a static nested class is associated with its enclosing class. a Line object would be created with the constructor "new Line()". a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference. that is. even to the private members. When you compile the above class definition. syntactically. This can be another motivation for declaring a nested class. Outside the class. As with instance methods and variables. it's that an instance of InnerClass can exist only within an instance of EnclosingClass and that it has direct access to the instance variables and methods of its enclosing instance. "new WireFrameModel. the code for one class appears within the code of another.} // end class Line . the compiled Line class is stored in a separate file.Line()" would be used. In contrast.. which we call class methods and variables. since it lets you give one class access to the private members of another class without making those members generally available to other classes. Also. it cannot define any static members itself. it's useful to think about them in the following way. two class files will be created. Even though the definition of Line is nested inside WireFrameModel.. the term inner class reflects the relationship between objects that are instances of the two classes. The name of the class file for Line will be WireFrameModel$Line. because an inner class is associated with an instance. // other members of the WireFrameModel class } // end WireFrameModel Inside the WireframeModel class.class..

) The nested class object is permanently associated with the containing class object. This is actually rather rare. it might as well be static. and will hopefully convince you that non-static nested classes are really very natural. // A deck of cards for playing the game. Two copies of the nested class in different objects differ because the instance variables and methods they refer to are in different objects. A non-static nested class is generally used only inside the class in which it is nested.for non-static nested classes. private int pot. and it has complete access to the members of the containing class object. where variableName is a variable that refers to the object that contains the class. This is true for non-static nested classes. . From outside the containing class. the rule for deciding whether a nested class should be static or non-static is simple: If the class needs to use any instance variable or instance method.at least logically -. just as it is for any other non-static part of a class. . . make it non-static. This class might include a nested class to represent the players of the game. // The amount of money that has been bet. class Player { // Represents one of the players in this game. . . 111 . } // end class Player private Deck deck. the object "this" is used implicitly. This copy has access to all the instance methods and instance variables of the object. Looking at an example will help. Consider a class that represents poker games. and there it can be referred to by its simple name. Otherwise. . This structure of the PokerGame class could be: class PokerGame { // Represents a game of poker.Any non-static member of a class is not really part of the class itself (although its source code is contained in the class definition). In fact. you must first have an object that belongs to the containing class. The non-static members of a class specify what will be contained in objects that are created from that class. It's as if each object that belongs to the containing class has its own copy of the nested class. however.NestedClassName. a non-static nested class has to be referred to as variableName. The same is true -. In order to create an object that belongs to a non-static nested class. (When working inside the class.

then.) The Player object will have access to the deck and pot instance variables in the PokerGame object. Each PokerGame object has its own deck and pot and Players. That's the effect of making the Player class non-static. a new Player object would be created by saying "new Player()". Outer.Inner y = x. conceptually. this is rather rare. or the current this object is not an instance of the outer class. independent of a particular poker game.Player()". If Player were a static nested class. Inner x = new Inner().} // end class PokerGame If game is a variable of type PokerGame. however. just as for any other class. To define a non-static nested class either in a class or method scope: Place the class definition (for the nested class) inside another class definition (the outer class) or a method. playes of another poker game use the other game's deck and pot. containing a nested class Inner: Outer.Inner y = new Outer(). you can use: 112 . The following example creates the Outer instance on a separate line. If Inner is static.new Inner(). Outer x = new Outer(). A Player object represents a player of one particular poker game. on the other hand. (A Player object could be created outside the PokerGame class with an expression such as "new game. constructs an instance of Inner where Inner is a nested class defined in the current class. game contains its own copy of the Player class. Given a class. Write code in a non-static method of the outer class to construct an instance of the nested class. but it had to construct an instance of Outer first. Outer. Write code to construct an instance on a nested class where either no this object exists. it would represent the general idea of a poker player. The above creates an instance of Inner called y. Players of that poker game use the deck and pot for that game. Again. This is the most natural way for players to behave. In an an instance method of a PokerGame object.new Inner(). You must create an instance of the outer class first. You may encounter nested classes of both kinds in the Java platform API and be required to use them. the syntax in the second line is the one you use when you already have an instance of the outer class.

println(args[0]).out.length > 0) { }. if (args. So the Java runtime system does not pass the class name you invoke to the main method. The code inside the braces.length You test the length of the args array as follows. specify that the application display a lot of trace information. } } } System. it passes only the items on the command line that appear after the class name. like the Mac OS. consider the following statement. You can derive the number of command-line arguments with the array's length attribute: numberOfArgs = args. don't normally have a command line or command-line arguments.Outer. Arrays have lengths and you can access that length by referencing the variable arrayname.length > 0) { System. Consider using properties instead so that your programs fit more naturally into the environment.Inner I= new Outer. which is used to invoke a Java application: java diff file1 file2 The following simple application displays each of its command-line arguments on a line by itself: public class Echo { public static void main (String[] args) { 113 . now gets executed if and only if the length of the args array is greater than zero.println(args[0]) was wrapped in a conditional test. This is done using the command-line argument -verbose.length. System.21 Command-Line Arguments A Java application can accept any number of arguments from the command line. an application might allow the user to specify verbose mode--that is. Command-line arguments allow the user to affect the operation of an application for one invocation. For example.out. // This is the Hello program in Java class Hello { public static void main (String args[]) { if (args.Inner(). you always know the name of the application because it's the name of the class in which the main method is defined. Purity Tip: Programs that use command-line arguments are not 100% Pure Java because some systems. For example.println("Hello " + args[0]). In Java.out. 5. Rather.

MONDAY. An enumerated type is a type whose legal values consist of a fixed set of constants.22 Enumerated types Enumerated types is a new feature introduced in J2SE 5. Common examples include compass directions. You enter the words that are shown here in a different font: java Echo Drink Hot Java Drink Hot Java Note that the application displays each word--Drink. In the Java programming language. TUESDAY. Double. i++) System. and Saturday. If you want Drink. you would join them by enclosing them within double quotation marks.println(args[i]). which take the values North. if (args. This is because the space character separates command-line arguments. South. Tuesday. 5. and Java--on a line by itself.out. you would specify a days of the week enumerated type as: enum Days { SUNDAY.length > 0) firstArg = Integer. 114 . Thursday. which take the values Sunday. and Java to be interpreted as a single argument. java Echo "Drink Hot Java" Drink Hot Java Parsing Numeric Command-Line Arguments If your program needs to support a numeric command-line argument.length. East and West and days of the week. Float.parseInt(args[0]). Friday. it must convert a String argument that represents a number. Hot.for (int i = 0. THURSDAY. Wednesday. Hot. For example.0. WEDNESDAY. parseInt throws a NumberFormatException if the format of args[0] isn't valid. All of the Number classes--Integer. Monday. } } Here's an example of how to invoke the application. Here's a code snippet that converts a command-line argument to an int: int firstArg. i < args. to a number. such as "34". you define an enumerated type by using the enum keyword. and so on--have parseXXX methods that convert a String representing a number to an object of their type.

5559e7). //in meters mass. and the serial form is designed to withstand changes in the enum type. (1. //in kilograms double radius. 6.0518e6).869e+24.4397e6).27e+22. (5.FRIDAY. 2. private final private final Planet(double this. Planet is an enumerated type that represents the planets in the solar system. The set of constants is not required to stay fixed for all time.024e+26. Each enum constant is declared with values for the mass and radius parameters that are passed to the constructor when it is created. You should use enumerated types any time you need to represent a fixed set of constants. public enum MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE PLUTO Planet { (3. If you attempt to create a public constructor for an enum type. They have a static values method that returns an array containing all of the values of the enum type in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an enumerated type. (1. (8. command line flags. SATURDAY }. 2. 7. Note that the constructor for an enum type is implicitly private. A Planet has constant mass and radius properties. 6.37814e6).mass double mass. They are Comparable and Serializable.0268e7). rounding modes. 115 . These are the most important properties of enum types:       Printed values are informative. (5. They are typesafe. 3. Java programming language enumerated types are much more powerful than their counterparts in other languages.3972e6). That includes natural enumerated types such as the planets in our solar system. the days of the week. (4.1492e7).686e+25. and the suits in a deck of cards as well as sets where you know all possible values at compile time.   In the following example.4746e7). for example the choices on a menu. (1. implement interfaces. and so on.9e+27. They provide implementations of all the Object methods.688e+26. They exist in their own namespace. 6. and more. Notice that by convention the names of an enumerated type's values are spelled in uppercase letters. The enum declaration defines a class (called an enum type). 2. (6. You can provide methods and fields. the compiler displays an error message. double radius) { = mass.137e6).421e+23.976e+24. which are just glorified integers.303e+23. You can switch on an enumeration constant. 1.

552719 on URANUS is 158. p.107583 on VENUS is 158. } //universal gravitational constant (m3 kg-1 s-2) public static final double G = 6. } public double surfaceWeight(double otherMass) { return otherMass * surfaceGravity().000000 on MARS is 66.surfaceGravity().radius = radius. it's not possible for one enum type to extend another enum type. Planet has methods that allow you to retrieve the surface gravity and weight of an object on each planet. } public double radius() { return radius.279007 on JUPITER is 442. public double surfaceGravity() { return G * mass / (radius * radius). for (Planet p : Planet. p.printf("Your weight on %s is %f%n". } } In addition to its properties.parseDouble(args[0]).this.207413 on PLUTO is 11.703031 There's one limitation of enum types: although enum types are classes.397260 on NEPTUNE is 199.values()) { System.out. In other words.surfaceWeight(mass)).67300E-11. } } Here's the output: java Your Your Your Your Your Your Your Your Your Planet weight weight weight weight weight weight weight weight weight 175 on MERCURY is 66. you cannot define a hierarchy of enums. } public double mass() { return mass. 116 . double mass = earthWeight/EARTH. Enumerated types in switch statement An example of using enumerated type in switch statement.374842 on EARTH is 175. Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit): public static void main(String[] args) { double earthWeight = Double.847567 on SATURN is 186.

JUNE. 117 .out. NOVEMBER. MAY. MARCH. break.println("Number of Days = " + numDays). Managing memory explicitly is tedious and error prone. The Java platform allows you to create as many objects as you want (limited. int year = 2000. of course. SEPTEMBER.23 Garbage Collection Some object-oriented languages require that you keep track of all the objects you create and that you explicitly destroy them when they are no longer needed. The Java runtime environment deletes objects when it determines that they are no longer being used. case APRIL: case JUNE: case SEPTEMBER: case NOVEMBER: numDays = 30. APRIL. case FEBRUARY: if ( ((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0) ) numDays = 29. JULY. switch (month) { case JANUARY: case MARCH: case MAY: case JULY: case AUGUST: case OCTOBER: case DECEMBER: numDays = 31. and you don't have to worry about destroying them. } System. AUGUST. This process is called garbage collection. } 5. OCTOBER.FEBRUARY. DECEMBER } public static void main(String[] args) { Month month = Month. by what your system can handle). break.public class SwitchEnumDemo { public enum Month { JANUARY. else numDays = 28. break. FEBRUARY. default: numDays=0. break. int numDays = 0.

The runtime system allocates a class variable once per class. Finalization Before an object gets garbage-collected. Every time you create an object. The finalize method is a member of the Object class. You access class variables and methods through the class. the garbage collector gives the object an opportunity to clean up after itself through a call to the object's finalize method. In rare cases. such as native peers. Remember that a program can have multiple references to the same object. the new object gets a copy of every instance variable defined in its class. no matter how many instances exist of that class. A class method or class variable is associated with a particular class. you can explicitly drop an object reference by setting the variable to the special value null. in some situations. A class can override the finalize method to perform any finalization necessary for objects of that type.finalize as the last thing it does. although. that aren't under the control of the garbage collector. For instance. you might want to run the garbage collector after a section of code that creates a large amount of garbage or before a section of code that needs a lot of memory. which is the top of the Java platform's class hierarchy and a superclass of all classes. your implementation of the method should call super. References that are held in a variable are usually dropped when the variable goes out of scope. and constructors for the class.An object is eligible for garbage collection when there are no more references to that object. If you override finalize. A class uses member variables to contain state and uses methods to implement behavior. however. You access instance variables and methods through objects. An instance method or instance variable is associated with a particular object (an instance of a class). methods. all references to an object must be dropped before the object is eligible for garbage collection. a programmer might have to implement a finalize method to release resources. The garbage collector does its job automatically. This process is known as finalization. 118 . Most programmers don't have to worry about implementing the finalize method. Summary A class definition has two parts: a class declaration and a class body. Or. The class body contains member variables. The Garbage Collector The Java runtime environment has a garbage collector that periodically frees the memory used by objects that are no longer referenced. you may want to run the garbage collection explicitly by calling the gc method in the System class.

You can explicitly drop a reference by setting the variable holding the reference to null. in the member's declaration. An object is unused if the program holds no more references to it. Compile-time error at line 3.variableName The qualified name of a method looks like this: objectReference. The garbage collector automatically cleans up unused objects. An instance of an inner class can exist only within an instance of its enclosing class and has access to its enclosing class's members even if they are declared private. which must be accessed through an instance reference. A class defined within another class is called a nested class. Instances of a class get their own copy of each instance variable. a nested class can be declared static or not. You can assign the reference to a variable or use it directly. Compile-time error at line 2. Questions 1. Compile-time error at line 1. The qualified name of an instance variable looks like this: objectReference. Instance variables and methods that are accessible to code outside of the class that they are declared in can be referred to by using a qualified name. b. c. A class controls access to its instance variables and methods by using the Java platform’s access mechanism.member. The new operator returns a reference to the object that was created. You can control access to member variables and methods in the same way: by using an access specifier. A nonstatic nested class is called an inner class. such as private or public. class GRC7 {public void main(String[] args) {}} // 1 class GRC8 {public void main(String []args) {}} // 2 class GRC9 {public void main(String args[]) {}} // 3 What is the result of attempting to compile and run the above programs? a. Class variables are shared by all instance of a class and can be accessed through the class name. You create an object from a class by using the new operator and a constructor. 119 .methodName() Constructors initialize a new instance of a class and have the same name as the class.methodName(argumentList) or objectReference. Like other members of a class.

public static void main(String[] args) { System. class GRC1 {public static void main(String[] args) {}} // 1 class GRC2 {protected static void main(String[] args) {}} // 2 class GRC3 {private static void main(String[] args) {}} // 3 What is the result of attempting to compile each of the three class declarations and invoke each main method from the command line? a. Compile-time error at line 5. b. Prints: 00000null b. Run-time error g.out. static int x. d. System. f. } } // 1 // 2 // 3 // 4 // 5 What is the result of attempting to compile and run the program? a. d. e. An attempt to run GRC8 from the command line fails. Prints: 00000 c. f. Compile-time error at line 3. c. public static void main(String[] args) { int y. e.out. Prints: 0null 120 . Compile-time error at line 3. Compile-time error at line 1. f. b.out.d. None of the above 4. static char c.println(a+b+c+d+e+s). c. class GFM12 { Compile-time error at line 1. 3. Compile-time error at line 2. } } What is the result of attempting to compile and run the program? a. An attempt to run GRC1 from the command line fails. static int d. An attempt to run GRC2 from the command line fails.println("y="+y). Compile-time error at line 2. System. An attempt to run GRC7 from the command line fails. e. 2. An attempt to run GRC3 from the command line fails. class GFM13 { static byte a. static String s. Compile-time error at line 4. An attempt to run GRC9 from the command line fails.println("x="+x). static long e. static short b.

Prints: 0 Prints: null Compile-time error Run-time error None of the above 121 .d. h. e. g. f.

d. Prints: 0 Prints: 1 Compile-time error Run-time error None of the above 122 .5. } } What is the result of attempting to compile and run the program? a. b.} return i3.out. c. } public static void main(String[] args) { System. int i2) { int i3. if (i1 > 0) {i3 = i1 + i2.println(m1(1.2)). class GFM16 { static int m1 (int i1. e.

"+ m(b1)). class GRC10 { public static void main (String[] s) { System.double c. GFC301 pet2 = new GFC301("Cat"). class GFC215 { } static String m(float i) {return "float".} public String getName() {return name. Prints: A B C e.6. System. None of the above 8.} static String m(double i) {return "double". class GFC301 { private String name. Prints: float.} public static void main (String[] args) { int a1 = 1. Prints: CDE d.name = name. Prints: float. } } java GRC10 A B C D E F What is the result of attempting to compile and run the program using the specified command line? a. } public static void main (String[] args) { GFC301 pet1 = new GFC301("Dog").out.float b. Run-time error g.out. Prints: B C D f. Prints: BCD c. Compile-time error h. None of the above 7.} public static void m1(GFC301 r1. GFC301 r2) { r1. Prints: ABC b. Prints: double.print(s[1] + s[2] + s[3]).setName("Bird"). Run-time error i. Prints: double. long b1 = 2. Compile-time error f. } What is the result of attempting to compile and run the program? a.double e. Prints: C D E g.name = name. r2 = r1.float d.} public void setName(String name) {this. 123 . public GFC301(String name) {this.print(m(a1)+".

// 4 c = b + a. What is the result of attempting to compile and run the program? a.getName()).out.} } m1(pet1. e.println(pet1.Bird c." + pet2. d. // 3 a = c + a. Prints: Dog.Bird e. System. // 1 short b = 1. Compile-time error g. Prints: Bird. b. c. // 2 long c = 1. class Maroon { public static void main (String[] args) { int a = 1.Cat b. Prints: Bird. f.pet2). None of the above 9. Run-time error f.getName() + ".Cat d. 1 2 3 4 5 None of the above 124 . Prints: Dog. // 5 } } A compile-time error is generated at which line? a.

// 2 byte b1 = s1. h.1 b.10.1 d." + i2[0]). None of the above 11. e. // 7 byte b6 = 1. Run-time error f. // 4 byte b3 = 1. int[] i2) { int[] i3 = i1. 1 2 3 4 5 6 7 8 125 . m1(i1. } } What is the result of attempting to compile and run the program? a. // 8 } } Compile-time errors are generated at which lines? a. c. System.0. Compile-time error g. i2). f. Prints: 3. d. } public static void main (String[] args) { int[] i1 = {1}. // 1 final char c1 = 1. b. class GFC100 { public static void main(String[] args) { final short s1 = 1. class GFC304 { static void m1(int[] i1.3 e. // 6 byte b5 = 1.0d. // 3 byte b2 = c1.print(i1[0] + ". i2 = i3.3 c. Prints: 1. i2 = {3}. Prints: 1.out. i1 = i2. g. // 5 byte b4 = 1L. Prints: 3.

d. f. System.out. return c1. } static byte m2(final char c2) {return c2. b. } // 1 // 2 // 3 } What is the result of attempting to compile and run the program? a. Prints: 13 Prints: 4 Compile-time error at 1 Compile-time error at 2 Run-time error None of the above 126 .12. c. e.print(""+m1()+m2(c3)). class JSC201 { static byte m1() { final char c1 = '\u0001'.} public static void main(String[] args) { char c3 = '\u0003'.

127 .

To do this. so that PlaneCircle inherits the fields and methods of its superclass.1 Inheritance Basics Inheritance is the capability of a class to use the properties and methods of another class while adding its own functionality. Java uses the extends keyword to set the relationship between a child class and a parent class. double y) { double dx = x . 128 .sqrt(dx*dx + dy*dy). } } public class PlaneCircle extends Circle { // We automatically inherit the fields and methods of Circle. This is done by defining PlaneCircle as a subclass of Circle.0 centered at point 1. The concept of inheritance greatly enhances the ability to reuse code as well as making design a much simpler and cleaner process. For example. public double area() { return Math. class Circle { double radius. // // // // The area() method is inherited from Circle A new instance method that checks whether a point is inside the circle Note that it uses the inherited instance field radius public boolean isInside(double x.0 centered at point 0. Suppose. we need a new class.cy. You could create a generic employee class with states and actions that are common to all employees.0 in the Cartesian plane is different from the circle of radius 1.cx. a circle of radius 1.PI * radius * radius. // so we only have to put the new stuff here. commissioned and hourly employees. cy. // New instance fields that store the center point of the circle double cx. which we'll call PlaneCircle. Then more specific classes could be defined for salaried.2. The Circle is a simple class that distinguishes circle objects only by their radii. The generic class is known as the parent (or superclass or base class) and the specific classes as children (or subclasses or derived classes). We'd like to add the ability to represent the position of a circle without losing any of the existing functionality of the Circle class.Chapter 6 : Inheritance 6. // Distance from center double distance = Math. that we want to represent circles that have both a size and a position. instead. An example of where this could be useful is with an employee records system. Circle. dy = y .

isInside(60. forming a hierarchy of classes.60)) { System. that the item was not inherited at all. One might say.cy = 40. Note that constructors are not members and so are not inherited by subclasses. the following two declarations of class "MyClass" are equivalent: public class MyClass{ } public class MyClass extends Object { } As depicted in the following figure. Therefore. Normally.out. many classes derive from Object. when a class is defined in Java. the subclass might not have access to an inherited member variable or method.0.out. However. pc.println(“Point 60. 129 . } } } A subclass inherits all the member variables and methods from its superclass. defined in the java. which does have access to its enclosing class's private members.out.println(“Point 60.} // Pythagorean theorem return (distance < radius). then.radius = 10. For example. The Object class. pc.area()). defines and implements behavior that every class needs. // Returns true or false public static void main(String args[]) { PlaneCircle pc=new PlaneCircle(). System. a subclass cannot access a private member inherited from its superclass. pc.60 is outside the circle“). and so on.0. } else { System.0.60) is within the circle if(pc.lang package.cx = 50.println(“Area of the circle :” + pc. //check whether a point (60. This becomes important when using an inner class.60 is inside the circle “). But the item is inherited. the inheritance from the Object class is implicit. many classes derive from those classes.

} Using superclass variable to access subclass object A superclass variable upwards in the hierarchy of Inheritance till the Object class can be used to used to assign the subclass object. A subclass derives from another class. the singly rooted hierarchy (with Object as the ultimate ancestor of all classes) and Java interfaces solves most problems that are commonly solved using multiple inheritance in C++. In particular. The overall design of Java supports the solution of problems commonly solved with multiple inheritance in other ways. The term superclass refers to a class's direct ancestor or to any of its ascendant classes. 130 . Classes near the bottom of the hierarchy provide more specialized behavior. For example. Object rd = new RedDrawf(). Star rd = new RedDrawf(). Example of Multi-level Inheritance public class AstronomicalObject { double magnitude. Every class has one and only one immediate superclass. } public class RedDwarf extends Star { String subtype.At the top of the hierarchy. Java was designed without multiple inheritance. in the above code the object of RedDwarf can be created as follows: RedDwarf rd = new RedDrawf(). } public class Star extends AstronomicalObject { double surfaceTemperature. Object is the most general of all classes. AstronomicalObject rd = new RedDrawf().

println("Meal()"). the compiler will automatically synthesize a default constructor.out.println("Bread()").out.6.println("PortableLunch()"). } } class Lettuce { Lettuce() { System. it’s essential that all constructors get called.out. and polymorphism on the order of construction: // Sandwich.java // Order of constructor calls class Meal { Meal() { System.println("Lunch()").println("Cheese()"). } } class Lunch extends Meal { Lunch() { System.println("Lettuce()"). A derived class has access to its own members only. otherwise the entire object wouldn’t be constructed properly. Only the base-class constructor has the proper knowledge and access to initialize its own elements.out.} } class PortableLunch extends Lunch { PortableLunch() { System. That’s why the compiler enforces a constructor call for every portion of a derived class. This makes sense because the constructor has a special job: to see that the object is built properly. inheritance. chaining upward so that a constructor for every base class is called. (In the case where a class has no constructors. It will silently call the default constructor if you don’t explicitly call a base-class constructor in the derived-class constructor body. } } class Bread { Bread() { System.) Let’s take a look at an example that shows the effects of composition.out. the compiler will complain. and not to those of the base class (whose members are typically private). If there is no default constructor.out. Therefore. } } 131 .2 Understanding how Constructors are called A constructor for the base class is always called in the constructor for a derived class. } } class Cheese { Cheese() { System.

etc. you know all about the base class and can access any public and protected members of the base class. 3.out. The body of the derived-class constructor is called. The important class is Sandwich.class Sandwich extends PortableLunch { Bread b. This means that you must be able to assume that all the members of the base class are valid when you’re in the derived class. This step is repeated recursively such that the root of the hierarchy is constructed first. Lettuce l. followed by the next-derived class. The base-class constructor is called. you must be able to assume that all members that you use have been built. and each class has a constructor that announces itself. if you count the implicit inheritance from Object) and three member objects. c = new Cheese(). In a normal method. Inside the constructor. so all the members of all parts of the object have been built. until the most-derived class is reached. When you inherit. Sandwich() { b = new Bread(). which reflects three levels of inheritance (four. Then when you’re in the derived-class constructor.. } public static void main(String[] args) { new Sandwich(). l = new Lettuce(). System. The order of the constructor calls is important. 2. Cheese c. The only way to guarantee this is for the base-class constructor to be called first. the output is: Meal() Lunch() PortableLunch() Bread() Cheese() Lettuce() Sandwich() This means that the order of constructor calls for a complex object is as follows: 1.println("Sandwich()"). however. When a Sandwich object is created in main( ). } } This example creates a complex class out of other classes. construction has already taken place. all the members you can 132 . Member initializers are called in the order of declaration.

//============ Constructor public Point() { m_x = 10. You want to call a parent constructor which has parameters (the default construct has no parameters). and l in the example above). there is no need to make a call to it because it will be supplied automatically. If you are satisfied with the default constructor in the superclass.g. or you can do it explicitly. An object has the fields of its own class plus all fields of its parent class. therefore all constructors must be called! The Java compiler automatically inserts the necessary constructor calls in the process of constructor chaining. you should initialize all member objects (that is.access in the base class have been initialized. } } The following is the equivalent of the constuctor above. you will help ensure that all base class members and member objects of the current object have been initialized. // Calls the constructor of Object class m_x = 10. m_y = 20. Calling the constructor for the superclass must be the first statement in the body of a constructor. If you follow this practice. It's necessary to initialize all fields. The Java compiler inserts a call to the parent constructor (super) if you don't have a constructor call as the first statement of you constructor. “Knowing that all members are valid” inside the constructor is also the reason that. objects placed in the class using composition) at their point of definition in the class (e. } Normally. whenever possible. grandparent class. c. m_y = 20. public class Point { int m_x. but there are two cases where this is necessary: • Passing parameters. you don't explicitly write the constructor for your parent class.: b. all the way up to the root class Object. //============ Constructor (same as in above example) public Point() { super(). int m_y. 133 . Use of super keyword You can also use super within a constructor to invoke a superclass's constructor.

// If any constructor is defined. // constructor without parameters 134 . Parent(int x) { _x = x. } } In the example above. } } // constructor ////////////////// class that must call super in constructor class Child extends Parent { int _y. class Parent { int _x. // If any constructor is defined. so the compiler will insert a call to the parameterless constructor of the parent. the compiler doesn't // automatically create a default parameterless constructor. the compiler doesn't // automatically create a default parameterless constructor. Child(int y) { // WRONG. Parent() { this(0). } } // constructor with parameter // constructor without parameters A better way to define the parameterless constructor is to call the parameterized constructor so that any changes that are made only have to be made in one constructor. Example of class without parameterless constructor /////////////////// class without a parameterless constructor. _y = y. Parent(int x) { _x = x. class Parent { int _x. } Parent() { _x = 0. /////////////////// class without a parameterless constructor.• No parameterless constructor. but there is no parameterless parent constructor! Therefore this produces a compilation error. There is no parent constructor with no parameters. This problem can be solved as follows : Parent class can define a parameterless constructor. there is no explicit call to a constructor in the first line of constructor. needs explicit call to super.

if you include a method definition that has the same name and exactly the same number and types of parameters as a method already defined in the base class. } } 6. this. Sometimes.height = height. until the Object class is finally reached. Circle(double radius) { this. Circle(double radius) { this. A subclass inherits methods from a superclass. etc.radius = radius. this new definition replaces the old definition of the method. //radius is inherited Cylinder(double height. This is referred to as method overriding.radius=radius. class Circle { //declaring the instance variable protected double radius. class Circle { double radius. } public static void main(String args[]) { Cylinder obj = new Cylinder(30. double radius) { super (radius). Example of passing parameters to the base class constructor.} } Note that each of these constructors implicitly calls the parameterless constructor for its parent class. it is necessary for the subclass to modify the methods defined in the superclass. } // other method definitions here public double getArea() { 135 .3 Overriding Methods In a derived class.40). } } class Cylinder extends Circle { double height. The following example demonstrates method overriding.

all classes are descendents of the Object class. Cylinder myCylinder. The next step is to define a subclass to override the getArea() method in the Circle class. if not all. the new definition of the method is called and not the old definition from the superclass(Circle). The Cylinder class is defined below. System.getArea()). }//this method returns the area of the circle }// end of class circle When the getArea method is invoked from an instance of the Circle class. while the getArea method in the Cylinder class computes the surface area of a cylinder.double length) { super(radius). The getArea() method in the Circle class computes the area of a circle.length = length. For example.getArea(). } //this method returns the cylinder surface area public static void main(String args[]) { Circle myCircle.getArea()+2*Math.out. } }// end of class Cylinder When the overriden method (getArea) is invoked for an object of the Cylinder class.println(“Area of circle :”+ myCircle.println(“Surface area of cylinder :” + myCylinder.PI*radius*radius. 136 .2. which returns a String object containing the name of the object's class and its hash code. The ability of a subclass to override a method in its superclass allows a class to inherit from a superclass whose behavior is "close enough" and then override methods as needed. Object contains the toString method. the method returns the area of the circle. class Cylinder extends Circle { //declaring the instance variable protected double length.20.50). System.20). } // other method definitions here public double getArea() { // method overriden here return 2*super.PI*radius*length. myCircle = new Circle(1. Cylinder(double radius.out. The derived class will be the Cylinder class. classes will want to override this method and print out something meaningful for that class. myCylinder = new Cylinder(1. this. Most.return Math.

Consider this class. Also. } } Now. For example. For example. super. you don't want to completely override a method. System. Calling the Overridden Method Sometimes. } } The toString() method is called implicitly when you try to print the object. Superclass: public class Superclass { public boolean aVariable. here's a subclass. The overriding method can have a different throws clause as long as it doesn't declare any types not declared by the throws clause in the overridden method. The return type. you want to add more functionality to it. e1.public class Employee { private String name. called Subclass. simply call the overridden method using the super keyword. // overrides Object's toString method public String toString() { return name. that overrides aMethod.out. and number and type of the parameters for the overriding method must match those in the overridden method. public class Subclass extends Superclass { public void aMethod() { //overrides aMethod in Superclass 137 . Rather. method name.overriddenMethodName(). } public static void main(String args[]) { Employee e1 = new Employee(). public void aMethod() { aVariable = true.println(e1).name = “John Smith”. a protected method in the superclass can be made public but not private. the access specifier for the overriding method can allow more access than the overridden method. To do this. but not less.

} public void override() { System.println("The hide method in Animal. super.out.println("The override method in Cat. keyword cannot be used in a static reference. is called Cat: public class Cat extends Animal { public static void hide() { System. final methods cannot be overridden). } public void override() { System. a subclass of Animal. } } The Cat class overrides the instance method in Animal called override and hides the class method in Animal called hide.aMethod(). } } The second class.println("The override method in Animal. These are discussed later. } public static void main(String[] args) { Cat myCat = new Cat().println("The hide method in Cat. In other words.").out. The main method in this class creates an instance of Cat. Methods a Subclass Cannot Override A subclass cannot override methods that are declared final in the superclass (by definition.out. a subclass cannot override a class method. which contains one instance method and one class method: public class Animal { public static void hide() { System."). This example contains two classes. myAnimal.override(). A subclass can hide a static method in the superclass by declaring a static method in the subclass with the same signature as the static method in the superclass. casts it 138 . a subclass cannot override methods that are declared static in the superclass. Also.hide(). System.} } super aVariable = false. Let's look at an example to see why. myAnimal.println(aVariable)."). The first is Animal.out. Animal myAnimal = (Animal)myCat.").out.

to a Animal reference. the runtime system invokes the hide method defined in Animal. It is a mechanism by which a call to an overridden function is resolved at run time. and then calls both the hide and the override methods on the instance.out.4 Dynamic Method Dispatch Dynamic Inheritance is the ability of an object to inherit classes at runtime and provides several key abilities. the runtime system invokes the override method defined in Cat. the runtime system invokes the method defined in the compile-time type of the reference on which the method is called. For class methods. Thus. Thus.out. the compile-time type of myAnimal is Animal. In the example. In the example. The override method in Cat. An instance method cannot override a static method. the runtime system invokes the method defined in the runtime type of the reference on which the method is called. rather than compile time (run-time polymorphism). } } class C extends A { // override callme void callme() { System. 6. } } class Dispatch { public static void main (String args [] ) { 139 .out. The output from this program is as follows: The hide method in Animal. and a static method cannot hide an instance method. It is the type of the object being referred to (not the type of of the reference variable) that determines which version of an overridden method will be executed class A { void callme() { System. For instance methods.println(“Inside B’s callme method”). The principle is a superclass reference variable can refer to a subclass object.println(“Inside A’s callme method”).println(“Inside C’s callme method”). } } class B extends A { //override callme void callme() { System. and the version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked is the one in the superclass. the runtime type of myAnimal is Cat.

r. an annotation can indicate that a particular method or class should be overridden in a subclass or that certain compiler error messages shouldn't be printed. annotations provide a way for programmers to instruct the compiler on how to handle certain situations.A B C A a = new A().callme(). Annotations use the form @annotation and can be applied to methods or classes. r = b. //object of type A //object of type B // object of type C // reference variable of type a // r refers to an A object //calls A’s version of callme // r refers to B object //calls B’s version of callme //refers to C object //calls B’s version of callme r = a.callme(). For example: @Override class Cat extends Pet { } or @Override void feedTheDog() { } The following example illustrates all three built-in annotation types.callme(). r. r. } @Deprecated static void deprecatedMethod() { } } 140 . using methods: import java.util. c = new C(). r. r = c. There are three useful annotations built-in to release 5.5 Annotations Introduced in J2SE 5. class Food {} class Hay extends Food {} class Animal { Food getPreferredFood() { return null. b = new B(). For example. } } 6.List.0.0 that will be discussed.

java.suppressed raw. not overridden //Notice the return type is different //(covariant return type).SuppressWarnings 141 .Override The @Override annotation indicates that a method defined in the current class must override a method is one of its superclasses.lang.add(new Horse()). } } java. If a method marked with @Override does not override the same method in one of its superclasses.lang. Hay getPreferredFood() { return new Hay().suppressed Animal. As of J2SE 5.lang. Invoking or overriding the deprecatedMethod method will generate a compile-time warning. } @SuppressWarnings({"deprecation". Note that this method is returning a different type (Hay) than the superclass (Food) — this practice is called covariant return types. the compiler will generate an error message. unless that warning is suppressed in the subclass. the deprecatedMethod in the Animal class is marked with the deprecated annotation. In the preceding example. Note: The @deprecated tag used by the Javadoc tool achieves the same result as @Deprecation. the override annotation is used to indicate that the getPreferredFood method in the Horse class is overriding the getPreferredFood method in the Animal class. "unchecked"}) void useDeprecatedMethod(List raw) { //deprecation warning . //unchecked warning . } @Override //compiler error if getPreferredFood //overloaded.deprecateMethod().class Horse extends Animal { Horse() { return. TM In the preceding example. the compiler-based @Deprecation annotation replaces the Javadoc @deprecation tag.0.Deprecated The @Deprecated annotation indicates that the marked method should no longer be used. java.

using the SuppressWarnings annotation on the entire Horse class is not recommended because genuine errors in the code might be hidden.0. Consider the following superclass and subclass pair: class Super { Number aNumber. // hides x in superclass void methodA() { 142 . One interesting feature of Java member variables is that a class can access a hidden member variable through its superclass.6 Hiding Member Variables Member variables defined in the subclass hide member variables that have the same name in the superclass. } class Subbie extends Super { Float aNumber. It is strongly recommended that you suppressed warnings only where necessary. For example. Another example of variable hiding. class SuperA { int x = 10. } The aNumber variable in Subbie hides aNumber in Super. In the preceding example.0 and some Java compiler implementations may suppress compiler warnings.The @SuppressWarnings annotation indicates that the named compiler warnings should be suppressed. 6. Note: This annotation can be used as of release 5. but this feature won't be fully implemented in javac until release 6. But you can access Super's aNumber from Subbie with super.aNumber super keyword allows a method to refer to hidden variables. } class SubA extends SuperA { int x = 20. the useDeprecatedMethod method in the Horse class uses the suppress warnings annotation to suppress both the unchecked and deprecation warnings that would otherwise occur.

which represents an abstract concept and should not be instantiated. should not be instantiated.java:6: class AbstractTest is an abstract class. is called an abstract class.methodA(). An abstract class is a class that can only be subclassed-it cannot be instantiated. Take. } If you attempt to instantiate an abstract class.7 Abstract Classes Sometimes. It doesn't make sense for an instance of food to exist. } public static void main(String args[]) { new SubA().out.x). 143 . but it doesn't make sense to create a generic number object. the Number class in the java. Similarly in object-oriented programming. System.out. a class that you define represents an abstract concept and. For example. new AbstractTest(). the Number class makes sense only as a superclass to classes like Integer and Float. To declare that your class is an abstract class.println(“ x in SubA :” + x). use the keyword abstract before the class keyword in your class declaration: abstract class Number { . with the syntax ((Superclass)object). A class such as Number. apple. ^ 1 error Abstract class can contain static methods.name. System. It can't be instantiated. Food represents the abstract concept of things that we all can eat. and chocolate. It makes sense to model numbers in a program.println(“ x in SuperA :” + ((SuperA)this).lang package represents the abstract concept of numbers. Instead. as such.println(“ x in SuperA :” + super.System. both of which implement specific kinds of numbers. . for example. } } You can access a hidden variable by casting the object to its superclass. food in the real world.x). Have you ever seen an instance of food? No. . the compiler displays an error similar to the following and refuses to compile your program: AbstractTest. you may want to model an abstract concept without being able to create an instance of it. 6. What you see instead are instances of carrot.out.

out. thereby providing its subclasses with the method declarations for all of the methods necessary to implement that programming interface. methods with no implementation. and so on. GraphicObject also declares abstract methods for methods. The graphics objects cannot share these types of states or behavior.println("Not equal").println("Equal"). . that need to be implemented by all subclasses. int y = 1. resize. but are implemented in entirely different ways (no default implementation in the superclass makes sense). if (x == y) System. such as the current position and the moveTo method. such as draw. bounding box) and behavior (move. you can draw circles. void moveTo(int newX.public abstract class test { public static void main(String [] args) { int x = 3. int newY) { 144 . y. that is. the abstract class can leave some or all of the implementation details of those methods up to its subclasses. else System. Each of these graphic objects share certain states (position. Let's look at an example of when you might want to create an abstract class with an abstract method in it.out. rectangles. draw). On the other hand. GraphicObject. . lines. In this way. This is a perfect situation for an abstract superclass. all GraphicObjects must know how to draw themselves. Bezier curves. the graphic objects are also substantially different in many ways: drawing a circle is quite different from drawing a rectangle.8 Abstract Methods An abstract class may contain abstract methods. However. First you would declare an abstract class. However. they just differ in how they are drawn. In an object-oriented drawing application. } } 6. You can take advantage of these similarities and declare them all to inherit from the same parent object--GraphicObject. to provide member variables and methods that were wholly shared by all subclasses. The GraphicObject class would look something like this: abstract class GraphicObject { int x. . an abstract class can define a complete programming interface.

would have to provide an implementation for the draw method. . A subclass must override methods that are declared abstract in the superclass. } } An abstract class is not required to have an abstract method in it. } //Accessor // implementation abstract methods.r = r. // semicolon instead of body. } } class Rectangle extends GraphicObject { void draw() { . // Instance data 145 . } abstract void draw(). . .} . protected double r. // Instance data public Circle(double r) { this. or the subclass itself must be abstract. } //Constructor public double getRadius() { return r. An abstract method cannot be static. } class Circle extends Shape { public static final double PI = 3. synchronized or a final method. public abstract class Shape { public abstract double area(). // Abstract methods: note public abstract double circumference(). } public double circumference() { return 2*PI*r. h. But any class that has an abstract method in it or that does not provide an implementation for any abstract methods declared in its superclasses must be declared as an abstract class. such as Circle and Rectangle. public double area() { return PI*r*r. Each non-abstract subclass of GraphicObject. .14. class Circle extends GraphicObject { void draw() { . } } class Rectangle extends Shape { protected double w. . .

There are (at least) two reasons why you might want to do this: to increase system security by preventing system subversion. } public double getWidth() { return w. } } class ShapeExample { public static void main(String args[]) { Shape[] shapes = new Shape[3].h = h.0. } public double circumference() { return 2*(w + h). Security: One mechanism that hackers use to subvert systems is to create a subclass of a class and then substitute their class for the original. inconsistent. 3.public Rectangle(double w. double total_area = 0. or unpredictable properties. The String class in the java.0).area(). for(int i = 0. this. // Create an array to hold shapes shapes[0] = new Circle(2.0).lang package is a final class for just this reason.length. This ensures that all strings have no strange. possibly causing damage or getting into private information. the compiler prints an error message and refuses to compile your program. This class is so vital to the operation of the compiler and the interpreter that the Java system must guarantee that whenever a method or object uses a String it gets exactly a java. undesirable. In addition.lang. The subclass looks and feels like the original class but does vastly different things. // Compute the area of the shapes } } 6. // Fill in the array shapes[1] = new Rectangle(1. } public double area() { return w*h. you can declare your class to be final and thereby prevent any subclasses from being created. the bytecode verifier ensures that the subversion is not 146 . double h) { this.w = w.0. If you try to compile a subclass of a final class. i < shapes. that is. 2. that your class cannot be subclassed. To prevent this kind of subversion.String and not some other string.9 Final Classes You can declare that your class is final. i++) total_area += shapes[i]. and for reasons of good object-oriented design.0). shapes[2] = new Rectangle(4. } public double getHeight() { return h.

conceptually. . To specify that your class is final. your class should have no subclasses. SmallBrain x = new SmallBrain(). For example. n.i = 40. n. if you wanted to declare your (perfect) ChessAlgorithm class as final.f().java:6: Can't subclass final classes: class ChessAlgorithm class BetterChessAlgorithm extends ChessAlgorithm { ^ 1 error Another example of final class class SmallBrain {} final class Dinosaur { int i = 7. its declaration should look like this: final class ChessAlgorithm { . .taking place at the bytecode level.j++. Design: You may also wish to declare a class as final for object-oriented design reasons. void f() {} } // class Further extends Dinosaur {} // error: Cannot extend final class 'Dinosaur' public class Jurassic { public static void main(String[] args) { Dinosaur n = new Dinosaur(). } } 147 . int j = 1. It does this by checking to make sure that a class is not a subclass of a final class. use the keyword final before the class keyword in your class declaration. n. You may think that your class is "perfect" or that. } Any subsequent attempts to subclass ChessAlgorithm will result in a compiler error such as the following: Chess.

g not final g.spin(). // OK -. } // void f(final int i) { i++. } public static void main(String[] args) { FinalArguments bf = new FinalArguments(). bf. } } 148 . the Object class does this.spin(). you might want instead to make the nextMove method final: class ChessAlgorithm { .. bf.with(null). You might wish to make a method final if it has an implementation that should not be changed and it is critical to the consistent state of the object. instead of making your ChessAlgorithm class final. } // Can't change // You can only read from a final primitive: int g(final int i) { return i + 1.without(null). } Final methods cannot be abstract methods. some of its methods are final and some are not.g is final g. . As just shown. final void nextMove(ChessPiece pieceMoved. } . For example. } void without(Gizmo g) { g = new Gizmo(). All methods of final class are implicitly final. BoardLocation newLocation) { .. . .6.10 Final Methods Does creating a final class seem heavy-handed for your needs? Do you really just want to protect some of your class's methods from being overridden? You can use the final keyword in a method declaration to indicate to the compiler that the method cannot be overridden by subclasses. Final Arguments class Gizmo { public void spin() {} } public class FinalArguments { void with(final Gizmo g) { // g = new Gizmo(). . // Illegal -.

for example. If you are not using packages. The members with no access specifier are of the type “package private”.12 Anonymous Inner Class Anonymous classes are classes that don’t have a name (hence the term anonymous). If the anonymous class implements an interface.11 Access control and Inheritance When you are creating a subclass make sure that the super class is present in the same package. you will have to import the package using import statement discussed in the next chapter. as part of the new statement. Because they don’t have a name. 149 . so they have the same privileges and limitations of nonstatic inner classes declared inside a method. If the anonymous class extends another class. like any other regular class. 6. their declaration must be given at creation time. That requires yet another form of the new statement. and not one instance of several different anonymous classes. there is no way to refer to them. override its methods.If a method is not final it can be overridden in the subclass. creates several instances of the same anonymous class. The private members in the base class are not inherited in the subclass. Notice that the declaration of the anonymous class is made at compile time. If not. its body can access the class’s members. If you want to use them outside the package declare them as public. as follows: new <class or interface> <class’ body> This form of the new statement declares a new anonymous class that extends a given class. Hence private methods in the base class are not overridden even though there is a method with the same name and same signature in the subclass. For this reason. and the instantiation at runtime. Technically. Hence if the classes are of package type then they cannot be used outside the package. That means that a new statement inside a for loop. Hence they can be used only by the classes in that package or by the classes in the unnamed package. If the base class is in the different package import the package and you can use the protected members. The protected members are inherited by the subclasses. its body must implement the interface’s methods. As seen above the object of the super class can use dynamic method 6. anonymous classes are considered nonstatic inner classes. and so on. It also creates a new instance of that class and returns it as the result of the statement. then take care to save the subclass in the same directory as the baseclass as the directory acts as an unnamed package.

150 . For example the following line causes the method to return an object which is an instance of an anonymous nested class: return new SomeClass() { /*body of the anonymous class goes here*/ }.: return new SomeClass(12) { /*body of the anonymous class goes here*/ }. These classes cannot define a constructor. maybe because the needed class is too simple or because it's used only inside a single method. An anonymous nested class must either implement an interface or extend a class. if you want to use a non-default constructor instead. passing an instance of the anonymous nested class: someMethod(new SomeClass() { /*body of the anonymous class goes here*/ }). the default constructor of that class is called." at the end. To define. which happens to contain a class definition. but the implements or extends keywords are not used. In both cases SomeClass() is not the name of the anonymous class (anonymous means it has no name) rather is it the name of the class that you are extending or the interface you are implementing. } Only final members of the outer class can be accessed in the methods of the anonymous inner class. You might like to think of an anonymous nested class as part of a really long new statement. an anonymous nested class that implements a specified interface: An anonymous nested class is defined where is it instantiated (in a method). Anonymous classes are particularly useful for quickly creating event handlers in Swing applications. If SomeClass() is a class. you supply arguments e. as they do not have a name that you can use to declare the constructor method. will call the SomeClass constructor which takes an int. Examples: public MyClass makeObj(final String name) { return new SubClassOfMyClass() { public String toString() { return "My name is "+name. } }. The following example calls someMethod(). but that doesn’t justify creating a whole new class. in method scope.Anonymous classes are great when you need to perform some task that needs an object. and which is why it has a ".g.

public Object makeObj(String name) { final String objName = "My name is " + name.println(c2). } } class CloneExample { public static void main(String args[]) throws CloneNotSupportedException { Car c1 = new Car(“Red”). The clone method of class Object will only clone an object whose class indicates that it is willing for its instances to be cloned. It then initializes each of the new object's fields by assigning it the same value as the corresponding field in this object. } 6. No constructor is called. System. } public String toString() { return color + “Colored Car”.println(c1). A class indicates that its instances can be cloned by declaring that it implements the Cloneable interface. } }.color = color. An example of cloning an object: class Car extends Cloneable { String color. Car c2 = (Car)c1.out.out. Car(String color) { this. System.clone(). } } 151 .13 The Object class Methods of Object class protected native Object clone() throws CloneNotSupportedException Creates a new object of the same class as this object. return new Object() { public String toString() { return objName.

for any reference values x and y. The equals method for class Object implements the most discriminating possible equivalence relation on objects.equals(x) should return true. public final native Class getClass() Returns the runtime class of an object.Hashtable. It is symmetric: for any reference values x and y.equals(y) returns true and y. The equals method implements an equivalence relation:      It is reflexive: for any reference value x. but is otherwise ignored. The general contract of hashCode is:   Whenever it is invoked on the same object more than once during an execution of a Java application. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup. x. this method returns true if and only if x and y refer to the same object (x==y has the value true). the hashCode method must consistently return the same integer. y. public final native void notify() 152 . protected void finalize() throws Throwable Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. It is transitive: for any reference values x. multiple invocations of x. The finalize method in Object does nothing.equals(x) returns true.equals(z) returns true.public boolean equals(Object obj) Compares two Objects for equality. public native int hashCode() Returns a hash code value for the object. This integer need not remain consistent from one execution of an application to another execution of the same application. This method is supported for the benefit of hashtables such as those provided by java. x.equals(y) consistently return true or consistently return false. It is consistent: for any reference values x and y. that is. x. For any reference value x. if x. If two objects are equal according to the equals method. and z.equals(null) should return false. then calling the hashCode method on each of the two objects must produce the same integer result. then x.util.equals(z) should return true. Any exception thrown by the finalize method causes the finalization of this object to be halted.equals(y) should return true if and only if y.

See the notify method for a description of the ways in which a thread can become the owner of a monitor. 153 . This method should only be called by a thread that is the owner of this object's monitor. For objects of type Class. In general. The current thread must own this object's monitor.Wakes up a single thread that is waiting on this object's monitor. It is recommended that all subclasses override this method. Only one thread at a time can own an object's monitor. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance. public final native void notifyAll() Wakes up all threads that are waiting on this object's monitor. This method should only be called by a thread that is the owner of this object's monitor. the toString method returns a string that "textually represents" this object. public final void wait() throws InterruptedException Waits to be notified by another thread of a change in this object. by executing a synchronized static method of that class. The result should be a concise but informative representation that is easy for a person to read. See the notify method for a description of the ways in which a thread can become the owner of a monitor. and the unsigned hexadecimal representation of the hash code of the object. A thread becomes the owner of the object's monitor in one of three ways:    By executing a synchronized instance method of that object. public String toString() Returns a string representation of the object. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution. A thread waits on an object's monitor by calling one of the wait methods. the at-sign character `@'. This method should only be called by a thread that is the owner of this object's monitor. A thread waits on an object's monitor by calling one of the wait methods. By executing the body of a synchronized statement that synchronizes on the object.

Summary 154 . The thread then waits until it can re-obtain ownership of the monitor and resumes execution. The thread then waits until it can re-obtain ownership of the monitor and resumes execution This method should only be called by a thread that is the owner of this object's monitor. The thread releases ownership of this monitor and waits until either of the following two conditions has occurred:   Another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. specified by the timeout argument in milliseconds. public final void wait(long timeout.public final native void wait(long timeout) throws InterruptedException Waits to be notified by another thread of a change in this object. The timeout period. The current thread must own this object's monitor. This method should only be called by a thread that is the owner of this object's monitor. The thread releases ownership of this monitor and waits until either of the following two conditions has occurred:   Another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. See the notify method for a description of the ways in which a thread can become the owner of a monitor. but it allows finer control over the amount of time to wait for a notification before giving up. The timeout period. The current thread must own this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor. has elapsed. int nanos) throws InterruptedException Waits to be notified by another thread of a change in this object. This method is similar to the wait method of one argument. specified by timeout milliseconds plus nanos nanoseconds arguments. has elapsed.

When an existing class is extended to define a new class. f.true. abstract b. An abstract class can contain abstract methods — methods that are declared but not implemented.false true. wait. boolean b1 = color1 instanceof Color.true false.false false. or it can hide variables or methods that it inherits.false. g. System. Inheritance provides a formal mechanism for code reuse. All classes are descendants from this class and inherit methods from it.true i.true. The subclass inherits all of the variables and all of the methods defined in the superclass and its superclasses.out.Extending an existing class often provides an easy way to create a new type.print(b1+". Compile-time error k. notify. false. Similarly. } } What is the result of attempting to compile and run the program? a. A subclass can override methods that it inherits.false true.true true. Except for the Object class. b. The Object class is the top of the class hierarchy. boolean b2 = color1 instanceof Blue.true. true. Questions 1. final c. Which of the following modifiers can be applied to the declaration of a field? a. but not identical to the features needed in the new type. Red color2 = new Red(). You can prevent a class from being subclassed by using the final keyword in the class's declaration.false. equals. and notifyAll. None of the above 2. boolean b3 = color2 instanceof Blue. class Color {} class Red extends Color {} class Blue extends Color {} class A { public static void main (String[] args) { Color color1 = new Red().false false.true e. you can prevent a method from being overridden by subclasses by declaring it as a final method."+b3). A class inherits member variables and methods from all its superclasses. clone. An abstract class can only be subclassed. This is primarily true when an existing class creates a type whose features are close to. whether direct or indirect. private d. Subclasses provide the implementations for abstract methods. Run-time error j."+b2+". protected 155 . Useful methods inherited from Object include toString. h. getClass. c.true.false. the existing class is often called the superclass and the new class is often called the subclass. d. a class has exactly one direct superclass.false. it cannot be instantiated.

a3[0] = a3[1] = a3[2] = a2. A11[][][] a3 = new A11[3][][]. An abstract class can not extend a concrete class. Compile-time error at 1. f. a2[0] = a2[1] = a1.out. 2 c. and suppose that all of the declarations are contained in one file named Basics. 5.e. class A11 {public String toString() {return "A11". d. a.print(a3[2][1][0]). A11[][] a2 = new A11[2][]. b. c. 4 e. The compiler attempts to create a default constructor for class A. An abstract class can be instantiated. Compile-time errors are generated at which lines? a. A local class can be declared abstract. An anonymous class can be declared abstract. } // // // // // // // 1 2 3 4 5 6 7 156 . Compile-time error at 2 4. e. 3 d. System.java. class A {A(int i) {}} class B extends A {} // 1 // 2 Which of the following statements are true? a. 1 b. b. c. An abstract class is implicitly final.}} } class A12 { public static void main(String[] arg) { A11[] a1 = new A11[1]. Which of the follow statements is true. The compiler attempts to create a default constructor for class B. d. An abstract class must declare at least one abstract method. a1[0] = new A11(). public 3. public class Basics {} class Basics1 {} protected class Basics2 {} private class Basics3 {} Class Basics4 {} // // // // // 1 2 3 4 5 Suppose these are top-level class declarations and not nested class declarations. 5 6.

Prints: null Prints: A11 Compile-time error at 1. b. Compile-time error at 5. h. Compile-time error at 4. Compile-time error at 2. Compile-time error at 3. f. Run-time error None of the above 157 . d. k. e. i. Compile-time error at 7. j. g. Compile-time error at 6.What is the result of attempting to compile and run the program? a. c.

because the package creates a new namespace. You also write an interface. Definition: A package is a collection of related classes and interfaces providing access protection and namespace management. 158 . and so on. . .lang. } //in the Rectangle. and points. and to control access. } //in the Circle.1 Packages To make classes easier to find and to use. too.java file public class Rectangle extends Graphic implements Draggable { .Chapter 7 : Packages and Interfaces 7. .java file public interface Draggable { . that classes implement if they can be dragged with the mouse by the user: //in the Graphic. programmers bundle groups of related classes and interfaces into packages. . The classes and interfaces that are part of the Java platform are members of various packages that bundle classes by function: fundamental classes are in java. Suppose that you write a group of classes that represent a collection of graphic objects. . such as circles. You can put your classes and interfaces in packages. You and other programmers know where to find classes and interfaces that provide graphics-related functions. to avoid naming conflicts. rectangles. .java file public abstract class Graphic { .java file public class Circle extends Graphic implements Draggable { . Draggable. .io. . The names of your classes wont conflict with class names in other packages. lines. } You should bundle these classes and the interface in a package for several reasons: • • • You and other programmers can easily determine that these classes and interfaces are related. classes for reading and writing (input and output) are in java. } //in the Draggable. Let's look at a set of classes and examine why you might want to put them in a package.

java package packagetest. However.println("Hello World"). class ClassB { static void greet() { System. This helps avoid potential name space collisions. If the package declaration is not given.java (case matters) and they must be in a directory named packagetest. While the Java Language specification does not put a limit on the length of a package name. Package names are identifiers . public class HelloWorld { public static void main(String[] args) { System. //ClassA. The unnamed package is often used when creating classes for small applications.out. 159 . from root through file name. } } //ClassB.greet(). } } Note that these source files must be named ClassA. then the class in the source file is placed in the unnamed package. Package declarations Each file must have a package declaration which precedes all non-comment code.println("Hi").out. For example. Another example of creating a package package world. be limited to 1024 characters total. here are two files in the packagetest directory. it does recommend that package names be used as directory names. It is recommended to use package names of a dozen characters or less. UNIX operating systems typically require that the full path to a file.You can allow classes within the package to have unrestricted access to one another yet still restrict access for classes outside the package. package names start with a lowercase letter. Conventionally.such as one named after the application. for larger projects all code should be placed in a named package .they can use mixed case and be of any length. class ClassA { public static void main(String[] args) { ClassB. The package name must be the same as the enclosing directory.java package packagetest.java and ClassB.

you must be outside the packagetest directory.. We use .java javac packagetest/ClassA.lang.C:\. you will get the following error: Exception in thread "main" java. but not in the java command. (dot) and . To compile the classes: javac packagetest/ClassB.ClassLoader. Generally use a forward slash ("/") because it is used more commonly than the backslash in other places as well. you may be familiar with .defineClass0(Native Method) at java. for the parent directory.java Compiling and running packages from a command line To compile the above example. we just go to the world directory and type the command: C:\world>javac HelloWorld.} } Create a folder world in c: drive and save the class file as HelloWorld.NoClassDefFoundError: HelloWorld (wrong name: world/HelloWorld) at java. On the command prompt type this set CLASSPATH=. In our CLASSPATH we include this for convenient reason.ClassA or java packagetest/ClassA In windows the "/" can be replaced by the "\" in the javac command.. (semicolon) to separate the directory location in case we keep class files in many places. as an alias for the current directory and . java packagetest.defineClass(ClassLoader.lang. (dot dot). When compiling HelloWorld class. we use .java:442) C:\world>java HelloWorld 160 ..lang. (dot) and C:\ directory. .java To run the main program in ClassA. Also. If you used to play around with DOS or UNIX.java If you try to run this HelloWorld using java HelloWorld. Java will find our class file not only from C: directory but from the current directory as well. We set the CLASSPATH to point to 2 places.ClassLoader. Setting up the CLASSPATH If the HelloWorld class is saved as described above the classpath can be set as follows.

Within the "vis" package may be several more nested packages to do data management.Launcher$AppClassLoader.net.loadClass(ClassLoader.lang.loadClass(ClassLoader.run(URLClassLoader.URLClassLoader.java:248) at java.at java.java:101) at java.loadClass(Launcher.security.renderer. the examples in this book have referred to types by their simple names. we have to tell JVM about its fully-qualified class name (world. To use a public package member from outside its package. separated by dots. and so forth. If we want to run it.defineClass(SecureClassLoader. etc.AccessController.java:290) at sun.java:216) at java.URLClassLoader$1.misc.ClassLoader. to create nested packages.URLClassLoader.java:286) at java. You can use a package member's simple name if the code you are writing is in the same package as that member or if that member has been imported.net.java:197) at java. rendering. Circle etc. class MyClass { } 7. such as Rectangle. you must do one or more of the following: • • • Refer to the member by its long (qualified) name Import the package member Import the member's entire package Referring to a Package Member by Name So far. there may be a project "abc" package in which are found several nested packages for "vis" work.vis.URLClassLoader.lang. For instance.doPrivileged(Native Method) at java.net.HelloWorld) instead of its plain class name (HelloWorld).defineClass(URLClassLoader.access$1(URLClassLoader. 161 . "database" work.java:191) at java. This is useful for creating a hierarchy of packages. C:\world>java world. package abc.ClassLoader.security.2 Using package members Only public package members are accessible outside the package in which they are defined.SecureClassLoader.HelloWorld C:\world>Hello World Note: fully-qualified class name is the name of the java class that includes its package name Nesting packages Package declarations may be a string of names.findClass(URLClassLoader.java:247) The reason is right now the HelloWorld class belongs to the package world.net.

Also. you must use the member's qualified name. which includes the package name. But you'd likely get annoyed if you had to write packagetest.*. Importing a Package Member To import a specific member into the current file. Now you can refer to any class or interface in the graphics package by its short name: ClassA obj = new ClassA().ClassA. You'll find that using long names is okay for one-shot uses. if you are trying to use a member from a different package and that package has not been imported. put an import statement at the beginning of your file before any class or interface definitions but after the package statement.ClassA again and again. use the import statement with the asterisk (*) wildcard character: import packagetest. ClassB objB = new ClassB(). It cannot be used to match a subset of the classes in a package.ClassA(). Importing an Entire Package To import all the types contained in a particular package. you can just import the member instead.ClassA You could use this long name to create an instance of packagetest. This approach works well if you use just a few members from the packagetest package. as shown here. your code would get messy and difficult to read. The asterisk in the import statement can be used only to specify all the classes within a package. packagetest. the following does not match all the classes in the packagetest package that begin with C: 162 . if there is one. But if you use many types from a package. you can import the entire package. Now you can refer to the ClassA class by its simple name: ClassA obj = new ClassA(). For example. In such cases. This is the qualified name for the ClassA class declared in the packagetest package in the previous example: packagetest. Here's how you would import the ClassA class from the packagetest package created in the previous section: import packagetest.ClassA obj = new packagetest.However.

it generates a compiler error.ClassB class contained useful inner classes. With the import statement. Also there is no need to import the classes in the same package.ClassB. For your convenience.import packagetest. Note: Another.lang package Note: Packages aren't hierarchical. For example. You must always refer to it as either java. you have to be more specific and use the member's qualified name to indicate exactly which Rectangle class you want: graphics. // does not work Instead. For example.awt package also contains a Rectangle class. For example.C*. If both graphics and java. import statement and class definition they should be written only in the same given order.Pattern or (if you import java.Pattern. like ClassB. less common form of import allows you to import only a class and its public inner classes. the Java compiler automatically imports three entire packages:   The default package (the package with no name) The java.util.* doesn't let you refer to the Pattern class as regex. you generally import only a single package member or an entire package.regex.util. Disambiguating a Name If by some chance a member in one package shares the same name with a member in another package and both packages are imported.regex.Square.util.*) simply Pattern.*. importing java. In such a situation. you could import ClassB and its inner classes this way: import packagetest. Avoid duplicating import statement. 163 . you must refer to each member by its qualified name.Rectangle rect. lets consider that you have created this package package graphics. Don’t import unnecessary classes. the following is ambiguous: Rectangle rect.Rectangle and ClassB. class Rectangle { } The java. If a class contains package declaration. if the packagetest.awt have been imported.

This means that a programmer creates something that obliges other programmers to follow a set of conditions. Note that one can extend an interface (to get a new interface) just as you can extend a class. public class { . } All instance methods are implicitly public and abstract. Member declarations in an interface disallow the use of some declaration modifiers. For example public interface Comparable { boolean less(Object m). . . There is no code at all associated with an interface. Also.7. In Java an interface is similar to an abstract class in that its members are not implemented. } greaterEqual(Object m){ . } greater(Object m){ .) There are almost no disadvantages to multiple inheritance of interface (small name conflict problems are one exception). . } 164 . . you may not use the private and protected specifiers when declaring members of an interface. boolean lessEqual(Object m). you cannot use transient. An interface creates a protocol that classes may implement. . The interfaces themselves need not be public and several interfaces in the standard libraries are not public and thus used only internally. boolean greater(Object m). (Classes do not. but are discouraged from doing so as the marking is considered obsolete practice. .3 Interfaces Interfaces are part of what is known as “programming by contract”. and final. The Polynomial class that implements Comparable will need to implement all of the functions declared in the interface. . } . One can actually extend several interfaces. . static. . . boolean boolean boolean boolean Polynomial implements Comparable less(Object m){ . . In interfaces. You can mark them as such. } lessEqual(Object m){ . } Polynomial multiply(Polynomial P){ . volatile. . or synchronized in a member declaration in an interface. boolean greaterEqual(Object m). _none_ of the methods are implemented. Interfaces are also considered to be the way Java gains some of the benefits of multiple inheritance without the drawbacks. . Interfaces thus enjoy the benefits of multiple inheritance. All constant values defined in an interface are implicitly public. .

} While the code changes are fairly minor -. Also. the Driver has knowledge only of the methods and variables defined in the Vehicle interface.. Class Car will implement the interface by providing a start() method. } class Car implements Vehicle{ // Required to implement Vehicle public void start(){ . Using the second implementation.. The usefulness of interfaces goes far beyond simply publishing protocols for other programmers. The Driver object requires knowledge of the Car object and has access to all public methods and variables contained within that object. A class that implements an interface must provide bodies for all methods of that interface. interface Vehicle { // All vehicle implementations must implement the start //method public void start().changing the references from Car to Vehicle -. Consider the simple example of a class Car that implements interface Vehicle. the two objects are said to be tightly coupled. the following implementation could be used: class Driver{ public Vehicle getVehicle( Vehicle c) { } .. but it forever links the Driver object with that of the Car. To code the Driver object using interfaces. Any other public methods and data contained in the specific implementation of the Vehicle interface are hidden from the user of the Vehicle object. The Driver object can be written without interfaces. Interface Vehicle has a single method called start(). This code example satisfies the functional requirements of the system.the effects on the development cycle are considerable. as follows: class Driver { public Car getCar( Car c){ . It is best to avoid such tight coupling of code because it increases dependencies and reduces flexibility. It is the Driver's job to start the Car and bring it to the restaurant patron.. an abstract class can choose to implement part of an interface leaving the rest for non-abstract subclasses. } } Having laid the foundations of the Car object. 165 . Other functionality in the Car class has been left out for the sake of clarity. we can create another object called Driver. In this situation...A class may choose to implement any number of interfaces. } } The Driver object has a method called getCar that returns a Car object.

m1". That guarantees that objects instantiated from concrete classes possess implementation code for all the operations of each type specified in the implements clause. and has therefore eliminated the possibility that developers will use undesirable methods. } private String p() { return "Base. } } public class Derived extends Base implements Foo { public String m1() { return "Derived.m3()". } public String m2( String s ) { return "Base.m2(" + s + ")".p()". Consider the following interface and class definitions: interface Foo { String m3().m1()". } public class Base { public String m1() { return "Base. } } 166 .This simple code change has ensured the proper concealment of information and implementation from other objects. Defining object types with interfaces The Java interface keyword declares a type and the implements keyword guarantees that a class either implements or defers the implementation of all operations for each type specified in the implements clause. } public String m3() { return "Derived.

Thus you achieve multiple type inheritance: type Derived subtypes type Base and type Foo. // REJECT The first statement attaches a type Derived variable to a type Derived object-creation expression. The additional implements Foo clause means type Derived also subtypes Foo. Foo foo = derived. Foo. Base base = derived. Derived derived = new Derived(). // REJECT // REJECT Section 1 calls method m3() through three different reference variable types. System. // call m3() System.println( base.Interface Foo declares a new type.out. Implementing multiple inheritance in Java If you want to write something similar to: 167 . the type-checker rejects the second statement in Section 2 since type Foo does not possess operation m1().out.m3() ).out.println( base. System. The definition of class Derived differs from before only by the addition of the implements Foo clause. Note that these conformance checks consider the variable type. The second statement attaches a variable of type Foo to the created object.println( foo.println( derived. Remarkably. Since type Base does not possess operation m3(). The third statement similarly passes type-checking. In the rejected statements. the type-checker rejects the section's third statement.out.m3() ). with a single operation. even though foo and base point to the same object.m1() ). The typechecker rejects the fourth statement since Foo does not subtype Base.out.m3() ). System. Now let's take a look at method invocation via the different variable types. and that object has implementation for both the m1() and m3() methods. Derived derived = new Derived(). foo = base. Base base = derived. Let's examine the ramifications of these type definitions. The type-checker enforces conformance between the type Derived variable and the type Foo variable by verifying that Derived actually subtypes Foo. the three variables remain attached to the same object for every method call. not the attached object type. // call m1() System. Foo foo = derived.println( foo.out. m3().m1() ). Similarly. the type-checker overrules the underlying Derived object's ability to perform the specified method call by enforcing variable type conformance. Incompatible variable types prevent this attempt to attach a variable to the very object to which it is already attached.m1() ).println( derived. System.

but cannot implement default behavior. On the other hand. Inheriting implementation from more than one superclass . For example: interface File { 168 . you would have everything necessary to define and implement an Employee class.multiple implementation inheritance is not a feature of Java. If you could only put them together. } You can create an Employee class like this : public class Employee implements PersonLike. An Interface can only declare constants and instance methods.) In Java. Subinterfaces One interface may be described as a subinterface of another if it extends its properties (i. An abstract class can have instance methods that implement a default behavior.e. } and the EmployeeLike interface is: public interface EmployeeLike { float getSalary(). contains additional methods.EmploymentLike { //details omitted } Difference between an Interface and an Abstract class An Abstract class declares have at least one instance method that is declared abstract which will be implemented by the subclasses. Java allows a class to have a single superclass and no more. Java supports multiple interface inheritance. java. Person is a concrete class that represents a person. a class can implement multiple interfaces.Date getHireDate(). implicitly inheriting all of the super-interface operations. Suppose the PersonLike interface is: public interface PersonLike { String getName(). int getAge(). while Employment is another concrete class that represents the details of a person who is employed. In other words. each subinterface must be explicitly listed as extending one or more other interfaces..util. Employment { // detail omitted } Here.//this code will give compile time error public class Employee extends Person.

add the static keyword to the import statement as follows: import static java. double logarithm = log (number). and NORTH without all the extra typing.PI * radius * radius. but if constants from another class are used extensively. respectively. With static imports. then the static import feature will reduce the code and also make it easier to read. In addition to the constants. Wildcards also work in the import static statement: import static java.0. contain static constants that are used within the class and are also useful outside the class. Prior to Java version 5.Math class contains the constants PI and E for pi and e. 169 . in your code. } 7.PI is probably easier. you can use just PI.Math. instead of double area = Math.PI. Then in the code body you can use double area = PI * radius * radius. For example. To use static imports. Math. etc.4 Static Import Many classes.lang.lang. the only way to access those constants was by fully spelling out the names Math. For example.PI.lang. the java. } interface ReadWriteFile extends ReadableFile. } interface WritableFile extends File { public void writeByte(byte b). including many in the Java core libraries. all the many static methods in the Math class are also available when you use the wildcard static import line above.*.Math.E. E.public void open(String name).NORTH. BorderLayout. } interface ReadableFile extends File { public byte readByte(). simply typing the Math. public void close(). For occasional use. WritableFile { public void seek(int position).

placing the MyConstants class name wherever these constants appear can be tedious and also makes the code less readable.1 * MyConstants.: public class MyConstants { final static double ALPHA = 1. static final double OMEGA = 901. a trick for avoiding the need to write the class name for static constants was to create an interface whose only purpose is to hold constants.instead of double logarithm = Math.0 + OMEGA).OMEGA However.1.ALPHA)/(1. whcih is far more readable.1*ALPHA)/(1.0 } Then in your other classes. The first option is to create a utility class that holds the constants. you would refer to these constants with MyConstants. For example. public interface MyConstantsImpl { static final double ALPHA = 1. 170 . Then a method in the class that implements MyConstantsImpl could use the constants in an equation without the class reference: x = (3.ALPHA MyConstants. especially in a formula like x = (3.0 + MyConstants. This will not interfere with the class design since there is no limit to the number of interfaces that a class can implement. Interfaces with Constants Only Before the static import became available. The methods in the program will then refer to the constants simply with ALPHA and OMEGA. An alternative is to put the constants into an interface.g.log (number). say that you need the constants ALPHA and OMEGA for several different programs.0 } Any class that needs these constants can implement MyConstantsImpl. e. final static double OMEGA = 901.OMEGA).1.

171 . Use a class instead and then statically import the class. violates the object-oriented design of the language. and static initializers within the declaration. So what does FP-strict actually mean? Consider the following example: public strictfp class FpDemo3 { public static void main(String[] args) { double d = 8e+307. and method declarations. In practical terms.This technique. constructors. however. That is. you are not really implementing anything. An expression is FP-strict if it occurs anywhere within one of these FP-strict declarations. then the class." If a class. interface. any expression that occurs within the class or method is an FP-strict expression.5 strictfp The keyword "strictfp" is used to control certain aspects of floating-point arithmetic. So constants-only interfaces are ill advised and considered bad programming style . You can use strictfp as a modifier of class. methods. interfaces. Methods within interfaces cannot be declared using strictfp because this is an implementation rather than an interface property. they are FP-strict only if their defining class is FP-strict. or method is declared using strictfp. Because constructors cannot be declared using strictfp. interface. this means that if a class or method is declared with strictfp. You would not think of a class that implements MyConstantsImpl as a MyConstants object in the sense of taking on an identifiable behavior of an interface. or method is FP-strict. So too are all classes. instance initializers. variable initializers. 7. like this: // legal uses of strictfp strictfp interface A {} public strictfp class FpDemo1 { strictfp void f() {} } You cannot use strictfp on constructors or methods within interfaces: // illegal uses of strictfp interface A { strictfp void f(). or if it is a compile-time constant expression. interface. } public class FpDemo2 { strictfp FpDemo2() {} } The strictfp keyword is used to designate an expression as "FP-strict.

interface I1 {} interface I2 {} class Base implements I1 {} class Sub extends Base implements I2 {} class Red { public static void main(String args[]) { 172 .MAX_VALUE) is approximately 1. The static import is a new concept of J2SE 5. this could keep the expression from overflowing.5 != 4.5) strictfp is important because its use guarantees common behavior across different Java implementations. in effect. In the FpDemo3 example. They are also helpful while using multiple inheritance.5).0.println(2.8e+308.System.2e+308. When the first part of the expression is evaluated.0 * d) * 0. In the FpDemo3 example.MAX_VALUE. An implementation is not required to do this.0 * d * 0. use FP-strict rules everywhere. System. and produce a final result that is within range.5 produces a final value for the expression of 1. which is less than Double.0 * d).5 because the Java programming language guarantees a left-to-right order of evaluation. the first expression is evaluated as: (4. By contrast.MAX_VALUE. if the expression is not FP-strict. Summary Packages are important as they act as a namespace. in that: (4. Interfaces are used as a programming discipline. It helps you to use the class members without using the class name.0 * d) * 0. Questions 1.6e+308.out. This is true even though the later multiplication by 0.println(4.out. They help to avoid conflict in classes and you can group the related classes together as a single package. you can know that the floating-point arithmetic in your application behaves the same when you move your application to a different Java implementation or hardware platform. the implementation is required to evaluate the whole expression as resulting in positive infinity (which the program prints as "Infinity"). In other words. which is larger than Double. it can. Note that multiplication in this example is not associative. } } The maximum value of a double (Double. Because the expression is FP-strict. the result is 32e+307 or 3. an implementation is allowed to use an extended exponent range to represent intermediate results.0 * (d * 0.

d. b. I2 i2 = s1. I1 i1 = s1. Base base = s1. 1 2 3 4 None of the above 173 . e. // // // // 1 2 3 4 A compile-time error is generated at which line? a.} } Sub s1 = new Sub(). c. Sub s2 = (Sub)base.

m1.} private void m3() {System.m1(). Compile-time error at 2.m3(). e. // 4 }} Assume that the code appears in a single file named A. // 1 a. A. A.m1. public class A { public void m1() {System.m4.} protected void m2() {System.print("A. ").out.java.m2.m2(). f.dan.chisholm. c.m4. Prints: A. Compile-time error at 4. "). A.print("A. "). d.} void m4() {System.out.out. What is the result of attempting to compile and run the program? a.m3. ").print("A. None of the above 174 . // 2 a. Compile-time error at 1.print("A.out.m3. Compile-time error at 3.} } class B { public static void main(String[] args) { A a = new A(). a.2. package com.m4(). // 3 a.m2. b.

" Many kinds of errors can cause exceptions--problems ranging from serious hardware errors. including its type and the state of the program when the error occurred. Java programs have the following advantages over traditional error management techniques: • • • Advantage 1: Separating Error Handling Code from "Regular" Code Advantage 2: Propagating Errors Up the Call Stack Advantage 3: Grouping Error Types and Error Differentiation Advantage 1: Separating Error Handling Code from "Regular" Code In pseudo-code. your function might look something like this: readFile { 175 . the method creates an exception object and hands it off to the runtime system. In Java terminology.1 What is an Exception? The Java language uses exceptions to provide error-handling capabilities for its programs. When such an error occurs within a Java method. beginning with the method in which the error occurred. The exception handler chosen is said to catch the exception. By using exceptions to manage errors. If the runtime system exhaustively searches all of the methods on the call stack without finding an appropriate exception handler. Thus the exception bubbles up through the call stack until an appropriate handler is found and one of the calling methods handles the exception. The term exception is shorthand for the phrase "exceptional event. An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. The exception object contains information about the exception. such as a hard disk crash. After a method throws an exception. the runtime system (and consequently the Java program) terminates. The set of possible "someones" to handle the exception is the set of methods in the call stack of the method where the error occurred. the runtime system leaps into action to find someone to handle the exception. An exception handler is considered appropriate if the type of the exception thrown is the same as the type of exception handled by the handler. The runtime system is then responsible for finding some code to handle the error. The runtime system searches backwards through the call stack. creating an exception object and handing it to the runtime system is called throwing an exception. until it finds a method that contains an appropriate exception handler.Chapter 8 : Assertions and Exception handling 8. such as trying to access an out-of-bounds array element. to simple programming errors.

} } else { errorCode = -3. reporting. if (readFailed) { errorCode = -1. but it ignores all of these potential errors: • • • • • What happens if the file can't be opened? What happens if the length of the file can't be determined? What happens if enough memory can't be allocated? What happens if the read fails? What happens if the file can't be closed? To answer these questions within your read_file function. if (gotTheFileLength) { allocate that much memory. if (gotEnoughMemory) { read the file into memory. } return errorCode. } } else { errorCode = -5. At first glance this function seems simple enough. read the file into memory. 176 . And worse yet. determine its size. if (theFileDidntClose && errorCode == 0) { errorCode = -4. Your function would end up looking something like this: errorCodeType readFile { initialize errorCode = 0. the logical flow of the code has also been lost in the clutter. } else { errorCode = errorCode and -4. } close the file. reporting and handling. open the file.} open the file. allocate that much memory. and returning that the original 7 lines of code are lost in the clutter. you'd have to add a lot of code to do error detection. } } else { errorCode = -2. close the file. } There's so much error detection. if (theFileIsOpen) { determine the length of the file.

} method3 { call readFile. } } Advantage 2: Propagating Errors Up the Call Stack A second advantage of exceptions is the ability to propagate error reporting up the call stack of methods. If your read_file function used exceptions instead of traditional error management techniques. } catch (fileCloseFailed) { doSomething. well. } catch (readFailed) { doSomething. method1 { call method2. Exceptions enable you to write the main flow of your code and deal with the. } catch (sizeDeterminationFailed) { doSomething. exceptional cases elsewhere. determine its size. read the file into memory. } catch (memoryAllocationFailed) { doSomething.making it difficult to tell if the code is doing the right thing: Is the file really being closed if the function fails to allocate enough memory? It's even more difficult to ensure that the code continues to do the right thing after you modify the function three months after writing it. } 177 . allocate that much memory. which finally calls readFile. which calls method3. it would look something like this: readFile { try { open the file. } method2 { call method3. } catch (fileOpenFailed) { doSomething. Java provides an elegant solution to the problem of error management: exceptions. close the file. Suppose that the readFile method is the fourth method in a series of nested method calls made by your main program: method1 calls method2. Many programmers "solve" this problem by simply ignoring it--errors are "reported" when their programs crash.

} errorCodeType method2 { errorCodeType error. else proceed. method1 { errorCodeType error. if (error) return error. if (error) return error. Thus only the methods that care about errors have to worry about detecting errors. } catch (exception) { doErrorProcessing. error = call method3. A Java method can "duck" any exceptions thrown within it. Traditional error notification techniques force method2 and method3 to propagate the error codes returned by readFile up the call stack until the error codes finally reach method1-the only method that is interested in them. if (error) doErrorProcessing. method1 { try { call method2. } 178 . } method3 throws exception { call readFile. else proceed. } errorCodeType method3 { errorCodeType error. error = call readFile.Suppose also that method1 is the only method interested in the errors that occur within readFile. error = call method2. else proceed. thereby allowing a method further up the call stack to catch it. } The Java runtime system searches backwards through the call stack to find any methods that are interested in handling a particular exception. } } method2 throws exception { call method3.

Advantage 3: Grouping Error Types and Error Differentiation Often exceptions fall into categories or groups. to catch all array exceptions regardless of their specific type. Each "leaf" class (a class with no subclasses) represents a specific type of exception and each "node" class (a class with one or more subclasses) represents a group of related exceptions. as you can see from the pseudo-code. A method can catch an exception based on its group or general type by specifying any of the exception's superclasses in the catch statement. so that the callers can intelligently and consciously decide what to do about those exceptions. an exception handler that handles only invalid index exceptions has a catch statement like this: catch (InvalidIndexException e) { . InvalidIndexException. you can create subclasses of the Throwable class and subclasses of your subclasses. Note again the difference in the bloat factor and code obfuscation factor of these two error management techniques. Java exceptions must be instances of Throwable or any Throwable descendant. Any checked exceptions that can be thrown within a method are part of that method's public programming interface and must be specified in the throws clause of the method. ElementTypeException. The code that uses exceptions is more compact and easier to understand.However. an exception handler would specify an ArrayException argument: ArrayException catch (ArrayException e) { . ducking an exception does require some effort on the part of the "middleman" methods. ArrayException is a subclass of Exception (a subclass of Throwable) and has three subclasses. . Thus a method informs its callers about the exceptions that it can throw. . . For example. } is a node class and represents any error that can occur when manipulating an array object. For example. One way a method can catch exceptions is to catch only those that are instances of a leaf class. and NoSuchElementException are all leaf classes. As for other Java classes. including those errors specifically represented by one of its subclasses. . 179 . Each one represents a specific type of error that can occur when manipulating an array.

Checked exceptions are exceptions that are not runtime exceptions and are checked by the compiler. and indexing exceptions (such as attempting to access an array element through an index that is too large or too small).2 Types of Exceptions All exception classes are the subclass of java. 8. runtime exceptions.} This handler would catch all array exceptions including InvalidIndexException. to name a few. You can find out precisely which type of exception occurred by querying the exception handler parameter e. and NoSuchElementException. although you can. . Runtime exceptions can occur anywhere in a program and in a typical program can be very numerous. } Exception handlers that are too general. pointer exceptions (such as trying to access an object through a null reference). Thus the compiler does not require that you catch or specify runtime exceptions. can make your code more error prone by catching and handling exceptions that you didn't anticipate and therefore are not correctly handled within the handler. and exceptions of your own creation. You could even set up an exception handler that handles any Exception with this handler: catch (Exception e) { . ElementTypeException.lang. such as the one shown here. The cost of checking for runtime exceptions often exceeds the benefit of catching or specifying them. Java has different types of exceptions. the compiler checks that these exceptions are caught or specified.Throwable class. The Throwable Class and Its Subclasses 180 . This includes arithmetic exceptions (such as when dividing by zero). Runtime exceptions are those exceptions that occur within the Java runtime system. including I/O Exceptions. .

These descendants indicate various types of exceptions that can occur. An example of a runtime exception is NullPointerException. Thus the compiler does not require that you catch or specify runtime exceptions. A NullPointerException can occur anywhere a program tries to dereference a reference to an object. Errors When a dynamic linking failure or some other "hard" failure in the virtual machine occurs. it's unlikely that typical Java programs will ever throw Errors either. which occurs when a method tries to access a member of an object through a null reference. when is it ever good to avoid documenting a method's behavior? The answer is "hardly ever. a method is not required to specify that it throws RuntimeExceptions. IllegalAccessException signals that a particular method could not be found. Typical Java programs should not catch Errors. the virtual machine throws an Error.Throwable has two direct descendants: Error and Exception. One Exception subclass is RuntimeException. and NegativeArraySizeException indicates that a program attempted to create an array with a negative size. you get the ability to throw an exception without specifying that you do so. The cost of checking for the exception often outweighs the benefit of catching it. Runtime exceptions can occur anywhere in a program and in a typical program can be very numerous. In other words. Exceptions Most programs throw and catch objects that derive from the Exception class. What does it cost you if you throw a RuntimeException or create a subclass of RuntimeException just because you don't want to deal with specifying it? Simply. The Exception class has many descendants defined in the Java packages." 181 . You can create your own RuntimeException subclasses. it is a way to avoid documenting the exceptions that a method can throw. In addition. the cost of checking for runtime exceptions exceeds the benefit of catching or specifying them. The Java packages define several RuntimeException classes. Runtime Exceptions The RuntimeException class represents exceptions that occur within the Java virtual machine (during runtime). You can catch these exceptions just like other exceptions. When is this good? Well. However. Typically. although you can. For example.

You could put each statement that might potentially throw an exception within its own try statement.println("Value at: " + i + " = " + victor. Next. that exception is handled by the appropriate exception handler associated with this try statement. } The try statement governs the statements enclosed within it and defines the scope of any exception handlers associated with it.txt"). and provide separate exception handlers for each try. Or you could put all of the statements within a single try statement and associate multiple handlers with it.true). Use the finally block to close files or release other system resources. i < size. A try statement must be accompanied by at least one catch block or one finally block. In general. In other words.println("Entering try statement"). for (int i = 0. a try block looks like this: try { Java statements } The segment of code labelled Java statements is composed of one or more legal Java statements that could throw an exception. PrintWriter out = null. The try Block The first step in constructing an exception handler is to enclose the statements that might throw an exception within a try block.8. you associate exception handlers with a try block by providing one or more catch blocks directly after the try block. 182 . if an exception occurs within the try statement. i++) out. Java's finally block provides a mechanism that allows your method to clean up after itself regardless of what happens within the try block.out.3 Catching and Handling Exceptions The first step in writing an exception handler is to enclose the statements that might throw an exception within a try block. out = new PrintWriter(new FileWriter("OutFile. try { System. The following listing uses one try statement for the entire method because the code tends to be easier to read.elementAt(i)). The try block is said to govern the statements enclosed within it and defines the scope of any exception handlers (established by subsequent catch blocks) associated with it.

The argument type. . The catch block contains a series of legal Java statements. . . the catch statement requires a single formal argument. declares the type of exception that the handler can handle and must be the name of a class that inherits from the Throwable class defined in the java.getMessage()). .println("Caught ArrayIndexOutOfBoundsException:" + e.The catch Block(s) The try statement defines the scope of its associated exception handlers. .getMessage()). . . The runtime system invokes the exception handler when the handler is the first one in the call stack whose type matches that of the exception thrown. You associate exception handlers with a try statement by providing one or more catch blocks directly after the try block: try { . } catch ( . ) { ) { There can be no intervening code between the end of the try statement and the beginning of the first catch statement. . try { .println("Caught IOException: "+e. . When Java programs throw an exception they are really just throwing an object. . } catch ( . SomeThrowableObject. These statements are executed if and when the exception handler is invoked. .err. . The argument to the catch statement looks like an argument declaration for a method.err. } catch (ArrayIndexOutOfBoundsException e) { System. } . If the superclass catch block is written first then the catch block of subclass becomes unreachable and gives compile-time error. } When you have to write multiple catch blocks and the exception classes in the blocks are related to each other then take care to write the catch block for the subclass first and then the catch block for the superclass.lang package. . . } catch (IOException e) { System. . . and only objects that derive from Throwable can be thrown. An example of using multiple catch blocks 183 . The general form of Java's catch statement is: catch (SomeThrowableObject variableName) { Java statements } As you can see.

println ("After try/catch blocks. } catch (ArrayIndexOutOfBoundsException e) { System.err. Also. You do this by enclosing the cleanup code within a finally block.out. Your exception handler can be written to handle any class that inherits from Throwable.class MultiCatch { public static void main (String args[]) { try { int a = args. The Java language allows you to write general exception handlers that handle multiple types of exceptions. An exception handler that handles both types of exceptions looks like this: try { ."). .println("a = " + a). } catch (Exception e) { System. } } Catching Multiple Exception Types with One Handler Each handles only one type of exception.length.println ("Divide by 0:" + e). c[42] = 99. } Handlers that can catch most or all exceptions are typically useless for error recovery because the handler has to determine what type of exception occurred anyway to determine the best recovery strategy.getMessage()). exception handlers that are too general can make code more error prone by catching and handling exceptions that weren't anticipated by the programmer and for which the handler was not intended. 184 . .out. } System.println("Exception caught:"+e.out. int c[] ={ 1 }. } catch (ArithmeticException e) { System.println ("Array Index oob:" + e). System. int b = 42 / a . The finally Block The final step in setting up an exception handler is providing a mechanism for cleaning up the state of the method before (possibly) allowing control to be passed to a different part of the program. The closest common ancester of IOException and ArrayIndexOutOfBoundsException is the Exception class.out.

println(elements[i]. finally { if (out != null) { System.err.out.length. getMessage is a method provided by the Throwable class that prints additional information about the error that occurred. n = elements.println("Closing PrintWriter"). i++) { System. } } Nested try statements 185 . You access the instance variables and methods of exceptions in the same manner that you access the instance variables and methods of other objects. the code within the finally block will be executed.getMethodName() + "()"). You can display this description in a println() statement by simply passing the exception as an argument. } } Displaying a description of an exception Throwable overrides the toString() so that it returns a string containing a description of the exception. } else { System.getLineNumber() + ">> " + elements[i]. A stack trace is a useful debugging tool that you'll normally take advantage of when an exception has been thrown.out.close(). This is the finally block for the writeList method. The Throwable class also implements two methods for filling in and printing the contents of the execution stack when the exception occurred. Accessing Stack Trace Information Definition: A stack trace provides information on the execution history of the current thread and lists the names of the classes and methods that were called at the point when the exception occurred.The runtime system always executes the statements within the finally block regardless of what happens within the try block. Regardless of whether control exits the writeList method's try block due to one of the three scenarios listed previously. It cleans up and closes the PrintWriter. out.getStackTrace(). for (int i = 0.println("PrintWriter not open").getFileName() + ":" + elements[i]. i < n. The following code shows how to call the getStackTrace method on the exception object: catch (Exception cause) { StackTraceElement elements[] = cause.

//generate an out of bound exception } } catch (ArrayIndexOutOfBoundsException e) { System. } } catch (ArithmeticException e) { 186 .length. // division by zero /* if two command line arg is used . then a divide-by-zero exception will be generated by the following code*/ if (a == 1) a = a / (a – a).out. If an inner try statement does not have a catch handler for a particular exception. You can enclose a call to a method within a try block. /* if no command-line args are present the following statement will generate a divide-by-zero exception*/ int b = 42 / a. or until the entire nested try statements are exhausted. In this case.println(e). class NestTry { public static void main (String args[]) { try { int a = args. then generate an out of bounds exception . try //nested try block { /* if one command line arg is used . which calls the method. Nesting of try statements can occur in less obvious ways when method calls are involved.println(“a = “ + a). the try statement within the method is still nested inside the outer try block. System. If no catch statement matches. //An Example of nested try statements. the context of that exception is pushed on the stack.*/ if( a = 2 ) { int c [] = { 1 }. the stack is unwound and the next try statement’s catch handlers are inspected for a match. Inside that method is another try statement. c[ 42 ] = 99.out. then the Java runtime system will handle the exception. This continues until one of the catch statements succeeds.Each time a try statement is entered.

lang.out. null). In the Java system. throw new Integer(4). setObjectAt(size . If you attempt to throw an object that is not throwable.1.1).Throwable. Sample outputs: 1) C:\> java NestTry Divide by zero.println(“Divide by zero”).util package. obj = objectAt(size . throwable objects are instances of any subclass of the Throwable class. the compiler refuses to compile your program and displays an error message similar to the following: testing. return obj.java:10: Cannot throw class java. public Object pop() throws EmptyStackException { Object obj. it must be a subclass of class java. Here's an example of a throw statement: throw someThrowableObject. size--.lang.} } } System. 8. } The EmptyStackException class is defined in the java. 187 . The throw statement requires a single argument: a throwable object. 2) C:\> java NestTry One a = 1 divide by zero 3) C:\> java NestTry One Two a = 2 Array index out of bounds. if (size == 0) throw new EmptyStackException().Integer.4 The throw Statement All Java methods use the throw statement to throw an exception.

println("Caught inside demoproc. throw new RuntimeException("demo").out. } finally { System. } finally { System. static void procA() { try { System.out. throw e. class FinallyDemo { // Through an exception out of the method. } } // Return from within a try block.println("inside procA").out.println("Recaught " ).out. } catch(NullPointerException e) { System.println("inside procB"). return.out. Recaught One more example using finally.println("procB's finally"). class ThrowDemo { static void demoproc() { try { throw new NullPointerException("demo").").out. static void procB() { try { System.println("procA's finally"). // re-throw the exception } } public static void main(String args[]) { try { demoproc(). } } } The resulting output is Caught inside demoproc.// Demonstrate throw. } } 188 . } catch(NullPointerException e) { System.

out. 189 .println("procC's finally"). A method can catch an exception by providing an exception handler i.5 The throws Clause The declaration of the pop method contains this clause: throws EmptyStackException The throws clause specifies that the method can throw an EmptyStackException. static void procC() { try { System. } catch (Exception e) { System.out. } } public static void main(String args[]) { try { procA(). } } The resulting Output is: inside procA procA's finally Exception caught inside procB procB's finally inside procC procC's finally 8. using a try.println("inside procC"). } procB().out..// Execute a try block normally. } finally { System.println("Exception caught"). procC().e. Java requires that a method either catch or specify all checked exceptions that can be thrown within the scope of the method.catch block for that type of exception.

i++) out. } } } The resulting Output is Inside throwOne. or exceptions that are children of exceptions in the 190 . } catch (IllegalAccessException e) { System. i < size. The throws clause goes after the method name and argument list and before the curly bracket that defines the scope of the method."). the method must specify that it can throw that exception.println("Inside throwOne.elementAt(i)). } public static void main(String args[]) { try { throwOne(). The throws clause specifies that if an exception occurs it is not explicitly handled. for (int i = 0. } The throws clause is composed of the throws keyword followed by a comma-separated list of all the exceptions thrown by that method.println("Caught “). although you can.println("Value at: " + i + " = " + victor. so you don't have to specify it in the throws clause. Thus if a method has exactly the same name and arguments it can only throw exceptions declared in the parent class. true). ArrayIndexOutOfBoundsException { Remember that ArrayIndexOutofBoundsException is a runtime exception. class ThrowsDemo { static void throwOne() throws IllegalAccessException { System. throw new IllegalAccessException("demo").out. Here's an example: public void writeList() throws IOException.6 Overriding methods that throw exceptions An overriding method in a subclass may only throw exceptions declared in the parent class or children of the exceptions declared in the parent class. Specifying the Exceptions Thrown by a Method public void writeList() { PrintWriter out = new PrintWriter(new FileWriter("OutFile. Caught 8.If a method chooses not to catch an exception. This is only true for overriding methods not overloading methods.txt").out.

or throws these exceptions. exception not in base version of method public static void amethod()throws IOException{} } If it were the method in the parent class that was throwing IOException and the method in the child class that was throwing FileNotFoundException this code would compile. They need not be included in any method’s throws list. Thus the following example will not compile import java. It can however throw fewer or no exceptions. there are no similar rules to overloaded methods. most exceptions derived from RuntimeException are automatically available. The most general of these are subclasses of RuntimeException. They are called unchecked exceptions because the compiler does not check to see if a method handles. Also an overridden method in a sub class may throw Exceptions.lang that must be included in a method’s throws list if that method can generate one of these exceptions and does not handle it itself. Java defines several exception classes.lang is implicitly imported to all Java programs. Checked exceptions are those defined by java.parent declaration.io. remember that this only applies to overridden methods. 8. java.lang.7 Java’s built in exceptions Inside the standard package java.*. RuntimeException subclasses (unchecked):              ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException SecurityException 191 . Since. class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ //Will not compile. Again.

IncompatibleClassChangeException 192 . j = j / j. the following code causes an ArithmeticException to be thrown: class Arith { public static void main(String args[]) { int j = 0. class Null { public static void main(String args[]) { String o = null. int a[] = null.  StringIndexOutOfBoundsException UnsupportedOperationException Checked Exceptions defined in java. } } NullPointerException An attempt to access a variable or method in a null object or a element in a null array throws a NullPointerException. For example. } } It is interesting to note that if you throw a null object you actually throw a NullPointerException.length and a[0] in the following class declaration throws a NullPointerException at runtime. o. For example. the accesses o.lang        ClassNotFoundException CloneNotSupportedException IllegalAccessException InstantiationException InterruptedException NoSuchfieldException NoSuchMethodException ArithmeticException Attempting to divide an integer by zero or take a modulus by zero throw the ArithmeticException--no other arithmetic operation in Java throws an exception.length(). a[0] = 0.

e. The following class declaration results in a ClassCastException at runtime: class ClassCast { public static void main(String args[]) { Object o = new Object(). 193 . A method that is declared in one class is deleted but other classes that access the method aren't recompiled. A field that is declared in one class is deleted but other classes that access the field aren't recompiled. // the cast attempt s. String s = (String)o. For example. ClassCastException A ClassCastException is thrown if an attempt is made to cast an object O into a class C and O is neither C nor a subclass of C. A variable's declaration is changed from non-static to static in one class but other classes that access the changed variable aren't recompiled. } } OutOfMemoryException An OutOfMemoryException is thrown when the system can no longer suppy the application with memory. the following class definition throws a NegativeArraySizeException at runtime: class NegArray { public static void main(String args[]) { int a[] = new int[-1]. the following code results in an OutOfMemoryException at runtime: class Link { int a[] = new int[1000000]. For example.. } } NegativeArraySizeException A NegativeArraySizeException is thrown if an array is created with a negative size. The OutOfMemoryException can only occur during the creation of an object. Four specific changes that throw a IncompatibleClassChangeException at runtime are: • • • • A variable's declaration is changed from static to non-static in one class but other classes that access the changed variable aren't recompiled.In general the IncompatibleClassChangeException is thrown whenever one class's definition changes but other classes that reference the first class aren't recompiled.length(). i. a[0] = 0. when new is called.

} } } NoClassDefFoundException A NoClassDefFoundException is thrown if a class is referenced but the runtime system cannot find the referenced class. For example.class it throws the NoClassDefFoundException. if the runtime system can't find C. } } When NoClass is run. IncompatibleTypeException An IncompatibleTypeException is thrown if an attempt is made to instantiate an interface.Link l. cur = cur. the following code causes an IncompatibleTypeException to be thrown. For example. class NoClass is declared: class NoClass { public static void main(String args[]) { C c = new C(). } class OutOfMem { public static void main(String args[]) { Link root = new Link(). Link cur = root. C class must have existed at the time NoClass is compiled. interface I { } class IncompType { public static void main(String args[]) { I r = (I)new("I"). } } ArrayIndexOutOfBoundsException 194 .l. while(true) { cur.l = new Link().

Two methods and two constructors were added to Throwable. } } 8.An attempt to access an invalid element ArrayIndexOutOfBoundsException. } catch (IOException e) { throw new SampleException("Other IOException". public static void main(String args[]) { foo(). The chained exception API was introduced in 1. For example: in an array throws an class ArrayOut { public static void main(String args[]) { int a[] = new int[0]. the class from which all exceptions inherit.. The methods and constructors in Throwable that support chained exceptions are: Throwable getCause() Throwable initCause(Throwable) Throwable(String. and initCause returns the current exception. providing additional information without losing the original cause of the exception. each exception can have a cause. e). Since every Throwable can have a cause. Throwable) Throwable(Throwable) The Throwable argument to initCause and the Throwable constructors is the exception that caused the current exception. } } UnsatisfiedLinkException An UnsatisfiedLinkException is thrown if a method is declared native and the method cannot be linked to a routine in the runtime. getCause returns the exception that caused the current exception. a[0] = 0. 195 . class NoLink { static native void foo(). The following example shows how to use a chained exception: try { .. which itself can have a cause. and so on.8 Chained Exceptions Chained exceptions allow you to rethrow an exception.4 by adding a cause property of type Throwable to exceptions.

passing a reference to another Throwable object as a parameter. All that you are required to do is pass a Throwable object's reference to the constructor for a new Throwable object. System.println("Msg is:\n" + e. }//end catch }//end main }//end Excep20 //This is a new exception class class NewEx01 extends Exception{ public NewEx01() { 196 .out. of course.meth01().getMessage()).println("Print StackTrace"). passing a reference to another Throwable object as a parameter.out.println().println("Cause is:\n" + e.println("In main catch block"). Two ways to encapsulate a cause As suggested above. The intent is that this object will be interpreted as the thing that caused this throwable to get thrown in the first place. System. What is a cause? A cause is a reference to another Throwable object. that the class from which you are instantiating the new object has such a constructor. } catch(NewEx01 e){ System. class Excep20{ public static void main(String[] args){ try{ new Class01().printStackTrace(). This works even when you are instantiating a new object from a class that doesn't have a constructor that accepts a parameter of type Throwable. This assumes. One way is to invoke one of the constructors that accepts a Throwable as a parameter. you can associate a cause with a Throwable in two different ways. or invoke the initCause method on an existing Throwable object.} In this example. when an IOException is caught. whether or not it had anything to do with the true cause.//blank line System.out. you could encapsulate any Throwable object in a new Throwable object.getCause()). It then becomes a cause.out.io. a new SampleException exception is created with the original cause attached and the chain of exceptions is thrown up to the next higher level exception handler. System.*. However. import java. The other way to associate a cause with a Throwable is to invoke the initCause method on an existing Throwable object's reference.out. e.

} public NewEx01(String message. System. System.println("Msg is:\n" + e. } public NewEx01(Throwable throwable){ super(throwable).out.getMessage()). System. } }//end NewEx01 //This is a new exception class class NewEx02 extends Exception{ public NewEx02() { } public NewEx02(String message){ super(message). throwable).out. } }//end NewEx02 class Class01{ void meth01() throws NewEx01{ try{ meth02().println("Cause is:\n" + e.//blank line throw new NewEx01("Msg from meth01".println("In meth01 catch block"). } public NewEx02(String message.out. 197 .out.println(). }//end catch }//end meth01 void meth02() throws NewEx02{ try{ meth03(). throwable).getCause()). } catch(NewEx02 e){ System.} public NewEx01(String message){ super(message).Throwable throwable){ super(message.Throwable throwable){ super(message. } public NewEx02(Throwable throwable){ super(throwable).e).

getMessage()). You should go to the trouble of writing your own exception classes if you answer "yes" to any of the following questions.println("Msg is:\n" + e.9 Creating Your Own Exception Classes Choosing the Exception Type to Throw When faced with choosing the type of exception to throw. }//end catch }//end meth02 void meth03(){ try{ int x = 3/0.initCause(e). }//end catch }//end meth03 }//end Class01 8.out.out.println("In meth02 catch block").println("Cause is:\n" + e.getCause()). you can probably get away with using someone else's: • • • Do you need an exception type that isn't represented by those in the Java development environment? Would it help your users if they could differentiate your exceptions from those thrown by classes written by other vendors? Does your code throw more than one related exception? If you use someone else's exceptions. Otherwise. System. System. System. you have two choices: 1. throw ex. throw new NewEx02("Msg from meth02". 2.println(). ex. Use one written by someone else. } catch(ArithmeticException e){ IndexOutOfBoundsException ex = new IndexOutOfBoundsException("Msg from metho03").out. The Java development environment provides a lot of exception classes that you could use. Write one of your own.out.} catch(RuntimeException e){ System.e). will your users have access to those exceptions? A similar question is: Should your package be independent and self-contained? Example public class DivideByZeroException extends Exception { 198 .

parseInt(args[1]). the java. 199 .lang package provides two Throwable subclasses that further divide the type of problems that can occur within a Java program: Errors and Exceptions. The bottom line is that you shouldn't subclass RuntimeException unless your class really is a runtime exception! Naming Conventions It's good practice to append the word "Exception" to the end of all classes that inherit (directly or indirectly) from the Exception class.out. } } } Choosing a Superclass However.println(e).public DivideByZeroException() { super("Dividing by Zero!").) Runtime exceptions don't have to be specified in the throws clause of a method. } } catch(ArrayIndexOutOfBoundsException e) { System. } } public class DivisionExample { public static void main(String args[]) { try { int x = Integer. if(y == 0) { throw new DivideByZeroException().println(x/y). int y = Integer.parseInt(args[0]). Most of the applets and applications that you write will throw objects that are Exceptions.println(e). (Errors are reserved for serious hard errors that occur deep in the system. } else { System.out. } catch(DivideByZeroException e) { System.out. Similarly. classes that inherit from the Error class should end with the string "Error". } public DivideByZeroException(String message) { super(message).

However because programmers in the past have used the word assert in creating their own versions of assertions the compilation process requires a command line parameter to tell it that it will be using the genuine JDK 1. When a program is running normally assertions are disabled and cause no performance overhead. assert statements are disabled during normal program run. Why Assertions exist? Assertions are a fairly simple concept where you write a statement that should always be true. When a programmer is investigating an issue assertions can be enabled and if any of the assert statements are not true an assert exception will be thrown. It would be perfectly possible to write code using the constructs available in Java prior to JDK1. Assertions can be considered an extension of comments in that comments are often used to tell a person reading the code that a particular statement or piece of code should always be true. Assertions are a key part of JDK 1. By default. but in a form that can be removed from the finally compiled version of the code so they cause no runtime overhead.4 and require no additional import statements in the source code.java If you then run the program normally in the form java Myprog 200 . This takes the form javac -source1. If you then run the code with assertions enables you do not have to rely on a close reading of the code as you would with comments but the running of the code itself will check your assertions are true. As the name implies assertions are used to assert something that should always be true.10 Assertions Assertions were added to Java with the release of JDK1.4.4 that simulates the functionality of assertions but it would be hard to do so in such a way that they would be turned off at runtime. How assertions are used? Where and how you use assertions is a matter of judgment in a similar way to where and how you use comments. instead of indicating by a comment that a statement should always be true you can assert that it should always be true.4 Myprog.4 version of assertions. With assertions. Assertions are a feature of other Object Orientated languages and there has been pressure for a while for them to be added to Java.8. and if they are not an assert error will be thrown.

For example if you are falling through a case statement or a set of if/else statements you might believe that the code should always exit before it reaches the final test. For another example if you were recording the date of a persons death you program (or your morality) might have a problem if you had the date of death in the future. If a person has an age less than zero your program or its input has a significant problem. really are true you can run the program with assertions enabled as follows. therefore you could assert that the date of death is in the future. Thus traditionally a programmer will inspect the command line passed to a Java program by looking at the value in the String args array passed from the command line. mpg. It is not appropriate to use assert to check the command line parameters of a program because assertions will not always be enabled. You set up a case statement that branch according to the type of file. Your application might be expecting to deal with jpg.assertions are disabled and no assert exceptions will be thrown. It is not appropriate to use assertions to check the parameters passed to public methods. Because your public methods may be used in programs written by other people you cannot be certain that they will have assertions enabled and thus the normal running of the program may be faulty. Assert syntax 201 . The same assumption may be made for code in protected or in package protected methods. If you subsequently have an issue you want to investigate and confirm that all of the assertions of items that should always be true. The introduction of the assert mechanism does not change this. Where should you use assertions? Assertions should not be used to enforce the public interface of a program. Because you believe that the type will always be one of those file types there is definitely a problem if you get to the end of the case statement without branching and you can place an assert statement at the location of the default option. For example it should always be true that a person has an age greater than zero. However it is appropriate to use assertions for checking the parameters to private methods as these will generally only be called by code written by people who have access to the source of those methods. One of the most public interfaces of a program is its command line parameters. avi or gif files. Imagine if you had an application dealing with media types. Typically if this array does not contain the expected type of values the program will exit and print a message indicating what the correct format of the command line should be. java -enableassertions Myprog or java –ea Myprog What should you assert to be true? Assertions should be used for anything you believe should always be true.

This example is simple in that the right hand side of the expression is a simple string.m1( 1 ): " ). For example if you were testing that a persons age was greater than zero you might create an assert in the form assert (iAge > 0). System. The more complex version might be of the form assert (iAge > 0) :"age must be greater than zero". i.m1( 1 ). } public static void main( String[] args ) { Foo foo = new Foo().print( "foo.m1( -1) : OK If the assertions are enabled the output is 202 .print( "foo.m1( -1 ): " ).out. System. public class Foo { public void m1( int value ) { assert 0 <= value.The assert statement has two formats The simple assert somebooleatest and assert somebooleantest : someinformatinvemethod In the first simpler version the assert tests that something is true and if it is not an AssertionError is thrown. foo.e.m1(1) : OK foo.out. System.println( "OK" ).m1( -1 ). a method with any return type except void.out. } } If the assertions are disabled the output is foo. but this could be any method call that returns a value. foo.

Prints: false.x. Run-time error g.foo. b.false d.c. None of the above public static void main (String[] args) { Error error = new Error(). Prints: true. You can also define your own exception class. d. class Level1Exception extends Exception {} class Level2Exception extends Level1Exception {} class Level3Exception extends Level2Exception {} class Purple { public static void main(String args[]) { int a. System.g. class A {A() throws Exception {}} // 1 class B extends A {B() throws Exception {}} // 2 class C extends A {} // 3 Which of the following statements is true? a. None of the above 3. class A { c.b. x = 1. Prints: true. There are two types of exception types: checked and runtime exceptions. All exception classes are subclasses of Throwable class. Questions 1. Compile-time error f.f.m1( -1) (Runtime Exception – AssertionError) Summary An exception is an abnormal condition arised during the program execution that disrupts the normal flow of program and terminates the application.print(error instanceof Throwable). a = b = c = d = f = g = 0.lang. Prints: false.d.print((exception instanceof Throwable) + ".out. 2. Exception exception = new Exception(). System. } } What is the result of attempting to compile and run the program? a. There are built-in api exception classes in java."). Compile-time error at 3.out.m1(1) : OK foo. try { 203 .true e.false b. Compile-time error at 2.true c. Compile-time error at 1.

204 . case 1: System.} switch (x) { case 1: throw new Level1Exception()."+g).1.0.0. System. switch (j) { case 0: System.} finally {g++."+b+".1. d. break.0. e.} } Which statements are true? a. break.1.0.try { } catch (Level2Exception e) {b++. What is the result of attempting to compile and run the program? a.0.1. Prints: 1.1.} finally {c++. class A { d."+c+". Prints: 0.} System.1 c.1. With assertions enabled it prints nothing.0. b.print("0").1. c. } } public static void main (String[] args) { A a = new A().print(a+". Run-time error h.1. case 2: throw new Level2Exception(). Prints: 1.out.0 b.out. } a++.1.print("1"). Prints: 0.0. With assertions disabled it prints 210210-1 With assertions disabled it prints only 210210 Assertions should not be used within the default case of a switch statement. for (int i=5."+f+".0.} catch (Exception e) {f++. i--) {a. With assertions enabled it prints 210210-1 followed by an AssertionError message."+d+".out. } } } catch (Level1Exception e) { d++. case 3: throw new Level3Exception().out.m1(i). f. default: assert j == 2.0. Prints: 0. i >= -1.1. None of the above } void m1(int i) { int j = i % 3. Compile-time error g.1.1 4. With assertions enabled it prints 210210 followed by an AssertionError message.1 f. With assertions enabled it prints only 210210.print(j). g.1 e.

205 .

This also has an impact on context switching. Thread-based multitasking is having a program perform two tasks at the same time.1 Multitasking Multitasking is performing two or more tasks at the same time.Chapter 9 : Multithreaded programming 9. Likewise.2 What Is a Thread? 206 . Process-based multitasking is running two programs concurrently. because switching from one part of the program to another happens within the same address space in memory. Additional resources are needed for each process to communicate with each other. The objective of multitasking is to utilize the idle time of the CPU. each process requires its own address space in memory. Programmers call this context switching. A good way to remember the difference between process-based multitasking and thread-based multitasking is to think of process-based as working with multiple programs and thread-based as working with parts of one program. An idling engine wastes gas. Process-based multitasking has a larger overhead than thread-based multitasking. The operating system requires a significant amount of CPU time to switch from one process to another process. This is thread-based multitasking. you could say that process-based multitasking is program-based multitasking. You want your CPU cycles to be processing instructions and data rather than waiting for something to process. In comparison. communication among parts of the program happens within the same memory location. Therefore. In processbased multitasking. For example. where each process (program) is a context. A CPU cycle is somewhat similar to your engine running. the threads in thread-based multitasking share the same address space in memory because they share the same program. Your objective is to keep your car moving as much as possible so you can get the most miles from a gallon of gas. Nearly all operating systems are capable of multitasking by using one of two multitasking techniques: process-based multitasking and thread-based multitasking. The same concept applies to the CPU in your computer. Programmers refer to a program as a process. Your engine keeps running regardless of whether the car is moving. 9. a word processing program can check the spelling of words in a document while you write the document. Think of the CPU as the engine of your car.

207 . Thread-based multitasking has multiple threads running at the same time (that is. A thread is part of a program that is running. The following figure shows this relationship. A thread is similar to a real process in that a thread and a running program are both a single sequential flow of control. there is a single point of execution.. Each thread is a different path of execution. However. Threads are processed asynchronously. At any given time during the runtime of the program.All programmers are familiar with writing sequential programs. Rather. However. You are used to life operating in a concurrent fashion. a thread itself is not a program. a thread is considered lightweight because it runs within the context of a full-blown program and takes advantage of the resources allocated for that program and the program's environment. This means that one thread can pause while other threads continue to process. a sequence. or watch three sorting algorithms race to the finish. A single thread also has a beginning. This is a sequential program. This is illustrated by the following figure: The Java run-time environment manages threads. and an end and at any given time during the runtime of the thread.so why not your browser? Some texts use the name lightweight process instead of thread. multiple parts of a program running concurrently). unlike in process-based multitasking where the operating system manages switching between programs. an execution sequence. The HotJava Web browser is an example of a multithreaded application.. and an end. print a page in the background while you download a new page. there is a single point of execution. Definition: A thread is a single sequential flow of control within a program. it cannot run on its own. You've probably written a program that displays "Hello World!". each has a beginning. That is. play animation and sound concurrently. it runs within a program. Within the HotJava browser you can scroll a page while it's downloading an applet or image.

The thread that processes mouse events for a Java program is also a daemon thread. There are two ways to provide the run method. By passing an argument to the constructor that creates the Thread object. sleeping. running. the underlying implementation doesn’t matter. For most programming needs. without having any connection with the overall state of the program. a Runnable object provides the run method to the thread. Java provides the ThreadGroup class for this purpose. the ThreadGroup of a thread can be set when the Thread object is created. Basic support for threads in the Java platform is in the class java. If the daemon attribute is not explicitly specified. In general. To implement a thread using the Thread class. (The actual implementation of concurrent operations is system-specific. The daemon attribute is queried using the isDaemon() method. Every Thread object belongs to a ThreadGroup object. Daemon threads A daemon thread is a thread that runs continuously to perform a service. • • Subclass the Thread class and override the run method. and having a priority. and threads that run system code are daemon threads. (It must have its own execution stack and program counter for example. Thus. Controlling groups of threads Sometimes it is necessary to control multiple threads at the same time. the Thread belongs to the same ThreadGroup as its parent Thread object. yielding. The daemon attribute of a thread is set when the Thread object is created. If an explicit ThreadGroup is not specified. by passing an argument to the constructor that creates the Thread object.lang. 208 .As a sequential flow of control. the thread that runs the garbage collector in Java is a daemon thread. the Java virtual machine stops. it is set using the setDaemon() method. If a thread dies and there are no other threads except daemon threads alive. you need to provide it with a run method that performs the thread's task. Provide a class that implements the Runnable interface and therefore implements the run method. A Thread object has a boolean attribute that specifies whether or not a thread is a daemon thread.Thread. threads that run application code are not daemon threads. a thread must carve out some of its own resources within a running program.) These behaviors include starting. some other texts use execution context as a synonym for thread. For example. It provides a thread API and provides all the generic behavior for threads. In this case.) The code running within the thread works only within that context. the Thread inherits the daemon attribute of its parent Thread object.

the thread does not stop unless it is running.getName(). This method can be called only once. To create a thread.9.int n) The thread sleeps for m milliseconds. Thread. plus n nanoseconds. The thread does not start running until Thread. When Thread. However. the thread begins executing in the run() method of the target class. The thread will start executing in the run() method of the Runnable parameter when Thread. 209 . The constructors are the following: Thread() Thread(Runnable) Thread(ThreadGroup) Thread(String) Thread(ThreadGroup.String) Thread(ThreadGroup. it does not die until it starts running again.start() is called. Runnable The Runnable parameter is an object that has implemented the Runnable interface.Thread is used to create and control threads. A new Thread class always starts running the public void run() method of a class. a new instance of this class must be created.start() is called.lang.Runnable. the new thread starts running in the run() method of an object. If it is suspended. All of them create a new thread. A ThreadGroup can be used to organize a thread. String There are many methods in the Thread class.start() must be called to actually make the thread run. It has no effect on • a thread that is not suspended.String) Thread(Runnable. Currently. sleep(int m)/sleep(int m. stop() This method stops and kills a running thread.start() is called. • • • suspend() This method suspends the execution of the thread. resume() This method resumes the execution of a suspended thread. When Thread. the thread does not start running right away.start() has been called. It remains suspended until resume() is called. Some of the methods that control the thread execution are the following: • start() This method starts the thread. It starts executing in the run() method of its Runnable target that was set when the constructor was called.3 The Thread class The class java.String) The constructors can use three possible parameters: • • • The name of the new thread is the parameter String. A thread can get its name by calling Thread. ThreadGroup The new thread will belong to the group specified by the parameter ThreadGroup. This is a deprecated method. The Thread class has seven constructors.

9. } } catch(InterruptedException e) { System. you can control it just like any other thread.setName(“My thread”). //controlling the main thread class CurrentThreadDemo { public static void main(String args[]) { Thread t = Thread.4 Using the main thread When a Java program starts up. 5. which is a public static member of Thread. it can be controlled through a Thread object. Its general form is shown below: static Thread currentThread() This method returns a reference to the thread in which it is called. To do so you must obtain the reference to it by calling the method currentThread(). Thread. because it is the one that is executed when your program begins. n > 0.5.currentThread().println(“Main thread interrupted”). one thread begins running immediately.sleep(1000). } } } The output of the program is as follows : Current thread : Thread[main.println(n).main] After name change : Thread[My Thread. System.out. The main thread is important because :   It is the thread from which other “child” threads will be spawned. // change the name of the thread t.println(“Current thread :“+ t). n -.out. Once. System.) { System.out. Example.main] 5 4 3 210 . Often it must be the last thread to finish execution because it performs various shutdown actions. Although the main thread is created automatically when your program is started.out.println(“After name change :” +t). you have a reference to the main thread. This is usually called the main thread of your program. try { for(int n = 5.

The sleep method causes the thread from which it is called to suspend execution for the specific period of milliseconds. the first of two classes in this example. You can obtain the name of the thread by calling getName(). By default. A thread group is a data structure that controls the state of a collection of threads as a whole.2 1 When you try to print t. it displays the name of the thread. Its general form is static void sleep(long milliseconds) throws InterruptedException static void sleep(long milliseconds.println(i + " " + getName()).5 Creating a thread Subclassing Thread and Overriding run The first way to customize a thread is to subclass Thread (itself a Runnable object) and override its empty run method so that it does something. This process is managed by particular runtime environment. try { sleep((long)(Math. its priority and the name of its group. Let's look at the SimpleThread class. Its priority is 5.random() * 1000)). and main is also the name of the group of threads to which this thread belongs.out. } public void run() { for (int i = 0. int nanoseconds) throws InterruptedException You can set the name of the thread by using setName(). the name of the main thread is main. This constructor is implemented by calling a superclass constructor and is interesting to us only because it sets the Thread's name. } catch (InterruptedException e) {} } System. The syntax is given below: final void setName(String threadName) final String getName() 9. i < 10. i++) { System.println("DONE! " + getName()). 211 . } } The first method in the SimpleThread class is a constructor that takes a String as its only argument. which is the default value. which does just that: public class SimpleThread extends Thread { public SimpleThread(String str) { super(str).out. which is used later in the program.

and both threads are displaying their output at the same time. The TwoThreadsTest class provides a main method that creates two SimpleThread threads: Jamaica and Fiji. That's it for the SimpleThread class.start(). which in turn calls the run method.The next method in the SimpleThread class is the run method. } } The main method starts each thread immediately following its construction by calling the start method.start(). the run method prints DONE! along with the name of the thread. Let’s put it to use in TwoThreadsTest. then sleeps for a random interval of up to 1 second. Implementing Runnable interface 212 . new SimpleThread("Fiji"). You should see output similar to this: Note how the output from each thread is intermingled with the output from the other. public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica"). When the loop completes. The run method is the heart of any Thread and where the action of the Thread takes place. The reason is that both SimpleThread threads are running concurrently. Compile and run the program. In each iteration the method displays the iteration number and the name of the Thread. So both run methods are running. the thread stops running and dies. The run method of the SimpleThread class contains a for loop that iterates ten times. After the loop has finished.

println( ++data ). t1. public ThreadedClass(){ data = 0. nothing else can happen in the system.lang package and has only one method in it – that is public void run() When you are implementing the Runnable interface you have to override the run method //Implementing Runnable public class ThreadedClass implements Runnable { int data. a signal that a network file is ready to be read. 9. t2. with polling. In this model. say. only one instance of ThreadedClass is created. } public Thread getNewThread(){ Thread t = new Thread( this ).start(). Thread t1 = threadedClass. then the event loop dispatches the control to the appropriate event handler.start(). Once this polling mechanism returns with. This wastes CPU time.getNewThread().The Runnable interface is a built-in interface in java. It can also result 213 . } public void run(){ //this method runs when start() is invoked on the thread System. return t. Until this event handler returns. This helps reduce inefficiency by preventing the waste of CPU cycles.getNewThread(). This one instance is used to spawn a multitude of threads (each executing the run() method of the same object). } public static void main( String[] args ){ ThreadedClass threadedClass = new ThreadedClass(). polling a single event queue to decide what to do next. } } In the main() method of the code above. Thread t2 = threadedClass.6 The Java Thread Model Java uses threads to enable the entire environment to be asynchronous. a single thread of control runs in an infinite loop.out. Single-threaded systems use an approach called an event loop.

by unsuccessfully attempting to acquire an object’s lock. One thread can pause without stopping other parts of your program.in one program dominating the system and preventing any other events from being processed. • Terminated or Dead State A thread reaches "dead" state when the run method has finished execution. The Life cycle of a thread The following figure shows the states that a thread can be in during its life and illustrates which method calls cause a transition to another state. Once a thread in the ready state gets access to the CPU. the entire program stops running. by blocking on I/O. A suspended thread is started. The thread on which yield() is invoked would move from running state to ready state. A CPU intensive operation being executed may not allow other threads to be executed for a "large" period of time. • Resumed. To prevent this it can allow other threads to execute by invoking the yield() method. It can also enter the waiting state by invoking its (deprecated) suspend() method. This thread cannot be executed now. In single-threaded environment. it gets converted to running state. or by invoking an object’s wait() method. This thread has access to CPU. A simple diagram is shown below: A more detailed diagram follows: 214 . The states of a Thread A thread can be in one of these states: • Running A thread is said to be in running state when it is being executed. but is not being currently executed. • Blocked A resource cannot be accessed because it is being used by another thread. when a thread blocks because it is waiting for some resource. The benefit of Java’s multithreading is that the main loop/polling mechanism is eliminated. • Suspended Execution is paused and can be resumed where it left off. A thread can enter the waiting state by invoking its sleep() method. • Ready State A thread in this state is ready for execution.

which is the Thread.0. you know that the thread either is a New Thread or is Dead.MIN_PRIORITY and Thread. Nor could you differentiate between a Runnable thread and a Not Runnable thread. Thread aThread = Thread.currentThread(). If the isAlive method returns true. currentPriority = aThread.MAX_PRIORITY can also be used.0 introduced the Thread. you know that the thread is either Runnable or Not Runnable. Constants Thread. 215 . int currentPriority.Testing Thread State Release 5.getPriority().getState method. the setPriority() method sets the thread priority to 5.NORM_PRIORITY. 9. you couldn't differentiate between a New Thread or a Dead thread.State values is returned: • • • • • • NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED The API for the Thread class also includes a method called isAlive. The isAlive method returns true if the thread has been started and not stopped. When called on a thread. Prior to release 5. If the isAlive method returns false.7 Thread priority A thread's priority is specified with an integer from 1 (the lowest) to 10 (the highest). By default. one of the following Thread.

} } public void stop() { running = false. class Clicker implements Runnable { int click = 0.NORM_PRIORITY + 2). } 216 .println("Main Thread Interrupted"). Clicker hi = new Clicker (Thread. if you cannot resist messing with priorities.setPriority(Thread.out.start(). Thread t.start().MAX_PRIORITY).aThread. } } class HiLoPri { public static void main (String args [ ]) { Thread. lo.t. private volatile boolean running = true. try { Thread.t. Clicker lo = new Clicker (Thread.stop().stop().currentThread(). However. use higher priorities for threads that frequently block (sleeping or waiting for I/O). } public void run () { while (running) { click++. t.setPriority( currentPriority + 1 ). Setting priorities may not always have the desired effect because prioritization schemes may be implemented differently on different platforms.join().setPriority(p). try { hi.NORM_PRIORITY .2). hi. } catch (InterruptedException e) { System. } lo. } public void start () { t. public Clicker(int p) { t = new Thread(this). Use medium to low-priority for CPU-intensive threads to avoid hogging the processor down. lo. hi.sleep(10000).join().start().

currentThread(). } } The output of this program. shown as follows when run under Windows 2000.println("High-Priority Thread:" + hi.out.println(Thread. } } 217 . For this reason the Java Thread class has a static method called yield. indicates that the threads did context switch even though neither voluntarily yielded the CPU nor blocked for I/O. The higher priority thread got approx. Low-Priority Thread:4408112 High-Priority Thread:589626904 The output depends on the speed of your CPU and the number of other tasks running in the system. System.out. Thread. On some operating systems the threading algorithm may automatically give different threads a share of the CPU time. which causes the currently running thread to yield its hold on CPU cycles. Volatile ensures that the value of running is examined each time the following loop iterates: while(running) { click++.8 Using the Thread yield method.yield().println("InterruptedException Caught").click).getName() + " Leaving run"). System.out.click). Example of using yield() method public class TestRunner implements Runnable { public void run() { System. This thread returns to the "ready to run" state and the thread scheduling system has a chance to give other threads the attention of the CPU.out.out. 90% of the CPU time. on others one thread might simply hog processor resources. } 9.println(Thread. If no other threads are in a "ready to run state" the thread that was executing may restart running again.getName() + " In run").catch (InterruptedException e) { System.currentThread(). Because of the platform dependent nature of Java threading you cannot be certain if a thread will ever give up its use of CPU resources to other threads.println("Low-Priority Thread:" + lo. } System.

// This method is called when the thread runs public void run() { try { for(int i=1. i<= 10. Thread t2 = new Thread(r1). if(!allDone) System. If you don’t want to use the deprecated method you can set a variable that the thread checks occasionally. class MyThread extends Thread { boolean allDone = false. However.println("i = " + i). while (i < 100) { i++.setName("BlahBlah"). Thread t1 = new Thread(r1).start().public class TestYield { public static void main (String[] args) { TestRunner r1 = new TestRunner(). it should return from the run() method. 218 .out. t1. t1.setName("TestThreadHaah"). When the thread detects that the variable is set. System. t2. else return. For example. a thread should arrange for its own death by having a run method that terminates naturally.start(). the while loop in this run method is a finite loop: It will iterate 100 times and then exit: public void run() { int i = 0. Using them often results in deadlocks and incorrect resource cleanup. suspend() Instead of using stop. t2.println(i).9 Stopping a Thread and stop() methods of Thread provide asynchronous methods of stopping a thread. these methods have been deprecated because they are very unsafe.i++) { sleep(500).out. } } 9. } } A thread with this run method dies naturally when the loop completes and the run method exits.

arbitrary behavior can result. thus. This behavior may be subtle and difficult to detect. } } Why is stop deprecated? Because it is inherently unsafe. even hours or days in the future. However. the user has no warning that his program may be corrupted. Such objects are said to be damaged.start(). Stopping a thread causes it to unlock all the monitors that it has locked. otherwise. there isn’t any guarantee that the main thread won’t finish before a child thread finishes. or it may be pronounced.out.sleep(2000). Both of these methods are defined in the Thread class.println(e). ThreadDeath kills threads silently. Programmers use two other techniques to ensure that the main thread is the last thread to terminate. } catch(InterruptedException e) { System. The isAlive() method determines whether a thread is still running. The join() method works differently than the isAlive() method.10 Determining When a Thread Has Finished Typically. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.println(e). 9.} } } } catch(InterruptedException e) { System. other threads may now view these objects in an inconsistent state. a boolean false is returned. Unlike other unchecked exceptions. These techniques involve calling the isAlive() method and the join() method. If it is. thread. When threads operate on damaged objects. You can use the isAlive() method to examine whether a child thread continues to run. try { Thread.) If any of the objects previously protected by these monitors were in an inconsistent state. the isAlive() method returns a boolean true value. the main thread is the last thread to finish in a program.allDone = true. } // Stop the thread thread. The corruption can manifest itself at any time after the actual damage occurs.out. } class ThreadStopDemo { public static void main(String args[]) { // Create and start the thread MyThread thread = new MyThread(). The join() method waits until the child thread terminates and “joins” 219 .

println(“Finished”). This algorithm schedules threads on the basis of their priority relative to other Runnable threads.out. the runtime system chooses for execution the Runnable thread that has the highest priority.out. In addition. } // Wait for the thread to finish try { thread. // Check if the thread has finished in a non-blocking way if (thread. At any given time. The Java runtime environment supports a very simple.out. threads run one at a time in such a way as to provide an illusion of concurrency.start().the main thread. you can use the join() method to specify the amount of time you want to wait for a child thread to terminate. } if (thread. yields. deterministic scheduling algorithm called fixed-priority scheduling. } catch (InterruptedException e) { System.isAlive()) { System.11 Thread Scheduling Many computer configurations have a single CPU.println(“Finished”).out.isAlive()) { System.out. when multiple threads are ready to be executed. } } } 9. Execution of multiple threads on a single CPU in some order is called scheduling. Only when that thread stops.println(“Thread has not finished”). it inherits its priority from the thread that created it. thread. Hence.join(). or becomes Not Runnable will a lower-priority thread start executing. } else { System. class ThreadDemo { public static void main(String args[]) { // Create and start a thread MyThread thread = new MyThread().println(“Thread has not finished”). If two threads of the same priority are 220 . Thread scheduling is implementation dependent and cannot be relied on to act the same way on every JVM When a thread is created.println(“Thread was interrupted”). } else { System.

Then the second thread is given a chance to run. As a result you are generally advised to use notifyAll instead of notify. Time slicing/preemptive Each thread gets a set amount of CPU time for executing. It yields.waiting for the CPU. The downside is that you cannot be certain how long a Thread might execute or even when it will be running. If you have multiple waiting threads then it will be probably the thread that has been waiting the longest that will wake up. However. The Java runtime system's thread scheduling algorithm is also preemptive. Although Java defines priorities for threads from the lowest at 1 to the highest at 10. this is not guaranteed. The chosen thread runs until one of the following conditions is true: • • • A higher priority thread becomes runnable. 221 . and the priorities of the threads will influence the result. If you have only one waiting thread then you do not have a problem. and so on. Rule of thumb: At any given time. A program under this system needs to be created in such a way that it "voluntarily" yield access to the CPU. the highest priority thread is running. When each thread has had its chance with the CPU the cycle starts again. You cannot be certain which thread gets woken. the runtime system chooses the new higher-priority thread for execution. some platforms will accurately recognise these priorities whereas others will not. For this reason. The thread scheduler may choose to run a lower priority thread to avoid starvation. Non time slicing/Cooperative A priority system is used to decide which thread will run. or its run method exits. until the interpreter exits. However you cannot be certain. Do not rely on it for algorithm correctness. If at any time a thread with a higher priority than all other Runnable threads becomes Runnable. On systems that support time-slicing. use thread priority only to affect scheduling policy for efficiency purposes. Of course this is not always possible and you may have to try to test your code on as many platforms as possible. its time allotment has expired. The notify method will wake up one thread waiting to reacquire the monitor for the object. The new thread is said to preempt the other threads. In a pre-emptive system one program can "pre-empt" another to get its share of CPU time. and not to make assumptions about scheduling or priorities. This ensures against a single thread getting all of the CPU time. In a time sliced system each thread gets a "slice" of the CPU time and then gets moved to the ready state. Once it has used up its time with the CPU. it is removed from accessing the CPU and any other waiting Threads get a chance at CPU time. the scheduler arbitrarily chooses one of them to run. A thread with the highest priority gets time with the CPU. The beauty of this approach is that you can be confident that each thread will get at least some time executing.

as you type characters on the keyboard.Relinquishing the CPU As you can imagine. every object in the Java language has a single monitor associated with it. imagine an application in which one thread (the producer) writes data to a file while a second thread (the consumer) reads data from the same file. the threads in those examples ran at their own pace without concern for the state or activities of any other concurrently running threads. To achieve this safety. called producer-consumer scenarios. only one of them will get it when it is released by the current owner. Both of these examples use concurrent threads that 222 . Any thread wishing to execute this code must acquire the associated mutex at the top of the code block and release it at the bottom. asynchronous threads. in that only one thread can own the mutex at any given time. concurrently running threads share data and must consider the state and activities of other threads. In general. As the name indicates. writing CPU-intensive code can have negative repercussions on other threads running in the same process. C. A monitor is a body of code whose access is guarded by a mutex. If multiple threads are waiting in line for the same mutex. In the early 1970s. such that only one of them is allowed to proceed when accessing the same object or lines of code. there must be a mechanism by which multiple threads running the same method can synchronize their operations. the producer thread places mouse events in an event queue and the consumer thread reads the events from the same queue. this effectively ensures that only the owing thread can execute a monitor block of code.A. the others will continue to block. For example. In one such set of programming situations. 9.) In many interesting situations. (The guarded code need not be contiguous -for example. This synchronization requires the threads to communicate with each other using objects called semaphores. A method in a Java object is said to be thread safe if it can be safely run in a multithreaded environment. try to write well-behaved threads that voluntarily relinquish the CPU periodically and give other threads an opportunity to run.12 Thread Synchronization So far the examples in this chapter have contained independent. the producer generates a stream of data that a consumer uses. Any other thread that tries to acquire ownership will be blocked and must wait until the owning thread releases the mutex. One specific type of semaphore is called a mutual exclusion semaphore or a mutex.R. Each thread contained all the data and methods required for its execution and didn’t require any outside resources or methods. Hoare and others developed a concept known as a monitor. ownership of this semaphore object is mutually exclusive. separate. The yield method gives other threads of the same priority a chance to run. Because only one thread can own a mutex at a given time. Also. the yield is ignored. If no equal-priority threads are Runnable. A thread can voluntarily yield the CPU by calling the yield method. Or.

print(“[“ + msg). The synchronized keyword The synchronized keyword can be used to mark a statement or block of code so that only one thread may execute an instance of the code at a time. 223 .out. } } class Caller implements Runnable { String msg. } System. When a synchronized block is executed. Example //This program is not synchronized class Callme { void call(String msg) { System.share a common resource: The first shares a file. It is generally more common to synchronize the whole method rather than a block of code. For a method the synchronized keyword is placed before the method thus synchronized void amethod() { /* method body */} For a block of code the synchronized keyword comes before opening and closing brackets thus. } catch(InterruptedException e) { System. Entry to the code is protected by a monitor lock around it.out. This process is implemented by a system of locks. try { Thread.sleep(1000). synchronized (Object Reference) { /* Block body */ } The value in parentheses indicates the object or class whose monitor the code needs to obtain. Because the threads share a common resource. Thread t. they must be synchronized. You may also see the words monitor.out. or mutex (mutually exclusive lock) used.println(“]”).println(“Interrupted”). Any other thread will not be able to execute the code until the first thread has finished and released the lock. and the second shares an event queue. Callme target. its object is locked and it cannot be called by any other code until the lock is freed. Note that the lock is based on the object and not on the method. Thus when a thread starts to execute a synchronized block it grabs the lock on it. A lock is assigned to the object and ensures only one thread at a time can access the code.

Caller obj1 = new Caller(target. Caller obj2 = new Caller(target.println(“Interrupted”).out. obj2.t. msg = s.public Caller(Callme targ. try { obj1. In that case you can use the synchronized block in the run method as follows: public void run() { 224 .t.start(). } } class Synch { public static void main(String args[]) { Callme target = new Callme(). t.join(). “Synchronized”). t =new Thread(this). } catch(InterruptedException e) { System.call(msg). The output of the program is [Hello] [Synchronized] If the Callme class is a third party class then you cannot change its code. String s) { target = targ. } } } Output is : [Hello[Synchronized ] ] Same example using synchronization: In the code above just add the keyword synchronized in front of the call method in the Callme class. synchronized void call(String msg) This prevents other thread from entering call() while another thread is using it.join(). “Hello”). } public void run() { target.

The Producer/Consumer Example In this example. } } public class Producer extends Thread { private CubbyHole cubbyhole. public int get() { return contents. } Only the run method is changed. public Producer(CubbyHole c. stores it in a CubbyHole object. the Producer generates an integer between 0 and 9 (inclusive). } public void run() { for (int i = 0.put(number. this. i). try { sleep((int)(Math.call(msg). The rest of the code is same. the Producer sleeps for a random amount of time between 0 and 100 milliseconds before repeating the numbergenerating cycle: public class CubbyHole { private int contents. To make the synchronization problem more interesting.number = number. i++) { cubbyhole.random() * 100)). i < 10. } public void put(int value) { contents = value. int number) { cubbyhole = c. private int number. public class Consumer extends Thread { 225 .} synchronized(target) { target. } catch (InterruptedException e) { } } } } The Consumer consumes all integers from the CubbyHole (the exact same object into which the Producer put the integers in the first place) as quickly as they become available.

neither Producer nor Consumer makes any effort whatsoever to ensure that happens. the Consumer misses a number. the result is wrong because the Consumer should get each integer produced by the Producer exactly once.get(number). In this situation. for (int i = 0. A race condition is a situation in which two or more threads or processes are reading or writing some shared data.number = number. within the get and put methods of the CubbyHole object. } } } Producer and Consumer example share data through a common CubbyHole object. this. One problem arises when the Producer is quicker than the Consumer and generates two numbers before the Consumer has a chance to consume the first one. and let’s discuss the potential problems that might arise from this. Part of the output might look like this: Another problem might arise when the Consumer is quicker than the Producer and consumes the same value twice. the Consumer might produce output that looks like this: Either way. private int number. public Consumer(CubbyHole c. and the final result depends on the timing of how the threads are scheduled.private CubbyHole cubbyhole. assume for a moment that these two threads make no arrangements for synchronization. In this situation. int number) { cubbyhole = c. However. i++) { value = cubbyhole. Race conditions in the producer-consumer example are prevented by having the storage of a new integer into the CubbyHole by the 226 . i < 10. The synchronization between these two threads occurs at a lower level. Although Consumer ideally will get each value produced once and only once. A problem such as this is called a race condition. Race conditions can lead to unpredictable results and subtle program bugs. } public void run() { int value = 0.

. The Producer locks the CubbyHole. Second. Other threads cannot call a synchronized method on the same object until the object is unlocked. Thus. the code segments that access the same object from separate.. int value) { . private boolean available = false. public synchronized int get(int who) { . So put and get in the CubbyHole class should be marked with the synchronized keyword. The Java platform associates a lock with every object and the lock is acquired upon entering a critical section.Producer be synchronized with the retrieval of an integer from the CubbyHole by the Consumer. When an object is locked by one thread and another thread tries to call a synchronized method on the same object. and the Consumer must have a way to indicate that the value has been retrieved. the two threads must not simultaneously access the CubbyHole.. A critical section can be a block or a method and is identified with the synchronized keyword. The Object class provides a collection of methods — wait. and notifyAll — to help threads wait for a condition and notify other threads when that condition changes. } public synchronized void put(int who. In the producer-consumer example. } } The method declarations for both put and get contain the synchronized keyword. The activities of the Producer and the Consumer must be synchronized in two ways. when it calls CubbyHole's put method. and the Producer should not modify it when the Consumer is getting the value.java are the critical sections. A thread can prevent this from happening by locking an object. That is. First. Whenever control enters a synchronized method. the thread that called the method locks the object whose method has been called.. the put and get methods of CubbyHole. Here’s a code skeleton for the CubbyHole class: public class CubbyHole { private int contents. thereby preventing the Consumer from calling the CubbyHole's get method: 227 . the Producer must have a way to indicate to the Consumer that the value is ready. the two threads must do some simple coordination. notify. concurrent threads are called critical sections. the second thread will block until the object is unlocked. The Consumer should not access the CubbyHole when the Producer is changing it. Locking an Object Within a program.

The Java runtime environment allows a thread to reacquire a lock because the locks are reentrant.public synchronized void put(int value) { //CubbyHole locked by the Producer . calls the other. // CubbyHole unlocked by the Consumer } The acquisition and release of a lock is done automatically and atomically by the Java run-time system. Now.println("here I am. because b is also synchronized. this sequence of method calls causes deadlock.. thereby preventing the Producer from calling put: public synchronized int get() { // CubbyHole locked by the Consumer . Reentrant locks are important because they eliminate the possibility of a single thread’s waiting for a lock that it already holds. } } contains two synchronized methods: a and b. When control enters method a. thereby reacquiring the lock. a. System. this works.. In platforms that don’t support reentrant locks. The current thread can acquire Reentrant 228 . b. it locks the CubbyHole. thus ensuring data integrity. Synchronization isn't the whole story. the Producer unlocks the CubbyHole. Similarly. when the Consumer calls CubbyHole's get method. The two threads must also be able to notify one another when they've done their job.println("here I am. in a()"). The first.. in b()"). the current thread acquires the lock for the Reentrant object.out. This ensures that race conditions cannot occur in the underlying implementation of the threads. Reaquiring a Lock The same thread can call a synchronized method on an object for which it already holds the lock. } public synchronized void b() { System. a calls b.. the thread attempts to acquire the same lock again. Consider this class: public class Reentrant { public synchronized void a() { b().out. Because the Java platform supports reentrant locks. //CubbyHole unlocked by the Producer } When the put method returns.

} } As implemented. } } //won't work! public synchronized void put(int value) { //won't work! if (available == false) { available = true. the causing thread notifies the waiting thread to wake up and proceed from where it left off. these two methods won't work. CubbyHole has another private member variable. Here's one possible implementation for the put and get methods: public synchronized int get() { if (available == true) { available = false. that is a boolean. as is evidenced by the output: here I am. What happens if the Producer hasn't put anything in the CubbyHole and available isn't true? The get method does nothing. in b() here I am. The available variable is true when the value has been put but not yet gotten and is false when the value has been gotten but not yet put. It therefore waits for the condition to be met. available. Similarly. Once the condition is true. 229 . and both a and b execute to conclusion. put doesn't do anything.13 Interthread Communication The construct of wait/notify plays an important role in the Java language's interthread communication mechanism. contents = value. The essential idea is that one thread needs a certain condition that can be brought about by another thread to become true. in a() 9. if the Producer calls put before the Consumer got the value. Look at the get method.the Reentrant object's lock again. return contents. The CubbyHole stores its value in a private member variable called contents. wait and notify should be placed within synchronized code to ensure that the current code owns the monitor Using the notifyAll and wait Methods in the Producer/ Consumer Example Let's investigate how the code in CubbyHole's put and get methods helps the Producer and the Consumer coordinate their activities.

//notify Consumer that value has been set notifyAll(). When Producer puts something in the CubbyHole. the Producer should wait until the Consumer takes a value (and notifies the Producer of its activities) before replacing it with a new value. } public synchronized void put(int value) { while (available == true) { try { //wait for Consumer to get value wait(). it notifies Consumer by calling notifyAll. return contents. The two threads must coordinate more fully and can use Object's wait and notifyAll methods to do so. int contents. available = true.You really want the Consumer to wait until the Producer puts something in the CubbyHole and the Producer to notify the Consumer when it's done so. //notify Producer that value has been retrieved notifyAll(). The wait method relinquishes the lock held by the Consumer on the CubbyHole (thereby allowing the Producer to get the lock and update the CubbyHole) and then waits for notification from the Producer. Each time through the loop. get calls the wait method. The Consumer then comes out of the wait state and the get method returns the value in the CubbyHole. Here are the new get and put implementations that wait on and notify each other of their activities: class CubbyHole { boolean available. public synchronized int get() { while (available == false) { try { //wait for Producer to put value wait(). } } The code in the get method loops until the Producer has produced a new value. } catch (InterruptedException e) { } } available = false. } catch (InterruptedException e) { } } contents = value. 230 . Similarly.

wait(long timeout. 1). that creates a CubbyHole object. Both wait and sleep delay for the requested amount of time. p1. The Object class also defines the notify method. One thread gets it.start(). Running the Producer-Consumer Example Here’s a small standalone application. This doesn't matter too much for threads that don't sleep for long. It waits for the Consumer thread to consume the current value before allowing the Producer to produce a new one. but it could be important for threads that sleep for minutes at a time. and the others go back to waiting. and a Consumer and then starts both the Producer and the Consumer: public class ProducerConsumerTest { public static void main(String[] args) { CubbyHole c = new CubbyHole().start(). the CubbyHole). a Producer. Consumer c1 = new Consumer(c. int nanos) Waits for notification or until timeout milliseconds plus nanos nanoseconds have elapsed. you also can use them in place of sleep. which arbitrarily wakes up one of the threads waiting on this object. You can easily wake up wait with a notify but a sleeping thread cannot be awakened prematurely. The awakened threads compete for the lock. The notifyAll method wakes up all threads waiting on the object in question (in this case. Producer p1 = new Producer(c.The put method works in a similar fashion. 1). Note: Besides using these timed wait methods to synchronize threads. There are the three versions of the wait method contained in the Object class: wait() Waits indefinitely for notification wait(long timeout) Waits for notification or until the timeout period has elapsed. c1. timeout is measured in milliseconds. } } Here’s the output of ProducerConsumerTest: Producer Consumer Producer Consumer #1 #1 #1 #1 put: got: put: got: 0 0 1 1 231 . called ProducerConsumerTest.

Deadlock most often occurs when two (or more) threads are each waiting for the other(s) to do something. A simple example is where each thread already holds one object and needs another that is held by the other thread.15 Suspending. Starvation occurs when one or more threads in your program are blocked from gaining access to a resource and. these two threads can run forever in lock-step. occurs when two or more threads are waiting on a condition that cannot be satisfied.) 9. restarting the thread is also a simpler matter. thereby ensuring that neither can pass. suspending a thread is a simple matter. unlike a deadlock. This continues for some time. Each person tries to be polite by moving to one side to let the other one pass. Resuming & Stopping Threads Sometimes suspending execution of a thread is useful. A system is fair when each thread gets enough access to limited resources to make reasonable progress. but no work gets done. If the user doesn’t want a clock. A fair system prevents starvation and deadlock. Deadlock. as a result. Once suspended. then its thread can be suspended. so what is done by the first thread is undone by another. the ultimate form of starvation. Livelocks A livelock.Producer Consumer Producer Consumer Producer Consumer Producer Consumer Producer Consumer Producer Consumer Producer Consumer Producer Consumer #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 put: got: put: got: put: got: put: got: put: got: put: got: put: got: put: got: 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 9. For example. This usually happens when the two threads are working at cross-purposes. a separate thread can be used to display the time of the day.14 Starvation and Deadlock If you write a program in which several concurrent threads are competing for resources. with both of them swaying from side to side and no progress being made. happens when threads are actually running. cannot make progress. Whatever the case. Now imagine a situation wherein each thread puts down the object it possesses and picks up the object put down by the other thread. (A common real world example is when two people approach each other in a narrow corridor. Clearly. 232 . effectively managing to achieve nothing at all. you must take precautions to ensure fairness. but both keep moving to the same side at the same time.

} System.out.out. t.join().println(name + “:” + i).start(). //name of thread Thread t. System.i--) { System. } } class SuspendResume { public static void main(String args[]){ NewThread t1 = new NewThread(“One”). t2. } catch(InterruptedException e) { System. } } catch(InterruptedException e) { System.println(“Main thread exiting”).println(“Resuming thread one”).println(“New Thread :” + t). Thread.An example using the deprecated methods: //using suspend() and resume() class NewThread implements Runnable { String name.out. NewThread(String threadName) { name = threadName.t.println(e).out. t = new Thread(this.out. try { Thread.sleep(1000). t1.out.println(name + “exiting”).println(“Suspending thread one”). } } 233 .suspend(). // start the thread } // this is the entry point for Thread public void run() { try { for(int i=15.println(“Main thread interrupted”).t. name). System.sleep(1000). t1.t.t. i > 0.join(). } System. System. NewThread t2 = new NewThread(“Two”). Thread.out.out.resume(). t1.sleep(200).

i--) { System. class NewThread implements Runnable { String name. While one thread is suspended the other runs. //name of thread Thread t.out.out.println(name + “:” + i). t. The same example code is written below without using deprecated methods. synchronized(this) { while(suspendFlag) { wait().println(e).println(“New Thread :” + t). Thread. boolean suspendFlag.sleep(200). } synchronized void myresume() { suspendFlag = false. t = new Thread(this. System.println(name + “exiting”).start(). } } } } catch(InterruptedException e) { System. } void mysuspend() { suspendFlag = true. NewThread(String threadName) { name = threadName. name).out.out. suspendFlag = false. i > 0. notify(). } } In the main method of the previous code instead of calling suspend() call mysuspend() method and instead of resume() call myresume() 234 . // start the thread } // this is the entry point for Thread public void run() { try { for(int i=15.This program creates two threads and suspends one of them. } System.

ThreadGroup tg) { super(tg. Thread. ThreadGroup gB = new ThreadGroup(“Group B”). } catch(Exception e) { System.out.out.gA).gA).9. NewThread t1 = new NewThread(“One”.out.16 ThreadGroup ThreadGroup creates a group of threads.println(e).gB).threadName).sleep(5000).println(getName() + “:”+ i). NewThread t2 = new NewThread(“Two”. try { Thread. 235 .println(getName() + “: exiting”). String groupName) ThreadGroup offers a convenient way to manage groups of threads as a unit. } } catch(Exception e) { System. It defines two constructors: ThreadGroup(String groupName).sleep(1000). System. } gA. i--) { System. start(). ThreadGroup(ThreadGroup parent. //start the thread } //This is the entry point for the thread public void run() { try { for(int i=15. Example of ThreadGroup: class NewThread extends Thread { NewThread(String threadName. i > 0. This is valuable in situations in which you want to suspend and resume a number of related threads. } System.gB).suspend().println(“New Thread :”+ this).out. } } class ThreadGroupDemo { public static void main(String args[]) { ThreadGroup gA = new ThreadGroup(“Group A”). NewThread t4 = new NewThread(“Four”. NewThread t3 = new NewThread(“Three”.out.println(e).

} catch(Exception e) { System.println(e). t4. try { t1.join(). } gA.out.join(). } } } Summary A thread is a logical execution unit that has a single sequential flow.sleep(5000).out. Multitasking can be achieved by process based multitasking and thread based multitasking. t2. 236 .join(). } catch(Exception e){ System. In multithreaded application you can execute multiple threads within a single program. t3.try { Thread.resume(). Thread-based multitasking also called as multithreading is cheaper compared to process based multitasking.join().println(e).

so you could use a literal string in place of a String there. you use Strings when you don't want the value of the string to change. For example.out. because the compiler ends up creating two Strings instead of one: first when the compiler encounters "Hola Mundo!". For example."). Because the compiler automatically creates a new String object for every literal string it encounters. String s = "Hola Mundo". this one String s = new String("Hola Mundo"). Creating a string 237 .) If the String is changed in any way a new String object is created in memory for the new value.1 The String class Strings in Java are constants.lang package and they implement the CharSequence interface. System. for mutable strings. and you don't want the method to modify the string in any way (which is typical). and StringBuffer. meaning they can not be changed. 10.out. System. Once they are initialized and populated the value and memory allocation is set (they are immutable. In the Java language. you can use a literal string to initialize a String. Both String and StringBuffer are the classes in java. Because they are constants. and second when it encounters new String(). Strings are typically cheaper than StringBuffers and they can be shared. you use StringBuffers when you know that the value of the character data will change.Chapter 10 : String Handling The Java development environment provides two classes that store and manipulate character data: String. for immutable strings. The StringBuffer class provides for non-constant strings. you specify literal strings between double quotes "Hello World!" You can use literal strings anywhere you would use a String object. So it's important to use Strings when they're appropriate.println() accepts a String argument.println("And might I add that you look lovely today. but more efficient than. if you pass a string data into a method. you would use a String. The above construct is equivalent to. The String class provides for constant strings.

// One constructor accepts an array of chars System. } } This program prints ABCDEF CDE There are two more constructors of String class String(StringBuffer) String(StringBuilder) The first one creates a string whose value is set from a string buffer. This method is called on one string object and takes another as an input 238 . 66.println (str).'A'}. int startIndex. 70}. Comparing Strings The equals method Comparing two Strings references to see if they hold identical strings is easily achieved with the equals method.println(s1). String s2 = new String(ascii. System. 2.out.out. The second creates a string whose value is set from a string builder.'V'.'A'. // will print JAVA One more constructor of String is String (String obj) String s = new String(“Java”).out. 68. int numChars) Class StringExample { public static void main(String args[]) { byte ascii [] = {65. 69. 67.Strings are created like any other object in Java using the new operator.println(s2). String str = new String (letters). While creating a String object you can also specify the byte values. String s1 = new String(ascii). System. String (byte asciiChars[]) String (byte asciiChars[]. For example one of the String constructors allows an array of characters to be taken as input: char letters[] = {'J'. 3).

you are actually checking to see whether the two references str and str2 refer to the same object.out. // false If you try to compare two strings like this: if (str == str2) System. Two references which point to the same object will always return true with the equals method.println ("str and str3" + str.println ("false").equals(str2)). if they are equal it returns the boolean value true. if it is equal to 0 they are equal and if the result is greater than 0 then the first is greater than the second. System.parameter.out. So if you want to compare the contents of the string use equal. String str2 = "Java".out. with be false with the == operator. // true System. boolean equalsIgnoreCase (String str) The compareTo method int compareTo(String str) This method is called in the same way as the equals method but returns an integer result. For example: String str = "hello".out. The equalsIgnoreCase method This method is similar to the equals method instead it performs the case insensitive comparison of Strings. if you want to check if the two references refer to the same object use ==. String str2 = "hello".equals(str2)).println ("str and str2" + str. If the result is less than 0 then the first string is less than the second. else System. This short example shows how comparisons are made amongst string: class strCmp { public static void main (String args[]) { String str = "Hello".println ("true").equals(str2)).out. It is possible that two strings are equal without them being the same object. // false 239 . otherwise it returns false. but two references which refer to different objects.println (str. both containing the same string. String str3 = "goodbye". System.

RegionMatchesDemo. the case is ignored when comparing characters.regionMatches(i.length(). if true. int) This method tests whether the specified region of this string matches the specified region of the String argument.System. i+len)). findMe. The boolean argument indicates whether case should be ignored.out. i. foundIt = true. int i = 0. } } } The output from this program is Eggs. the program calls the regionMatches method to determine whether the substring beginning with the current character matches the string for which the program is looking. The charAt method 240 . str is less than str2 } } The compareToIgnoreCase method This method is similar to the compare method the only difference is it performs the case insensitive comparison. boolean foundIt = false. // a negative number.println(searchMe. String.substring(i.e. uses the regionMatches method to search for a string within another string: public class RegionMatchesDemo { public static void main(String[] args) { String searchMe = "Green Eggs and Ham". } if (foundIt) { System. len)) { i++. The program steps through the string referred to by searchMe one character at a time. int. String. 0.println (str. The following program. For each character. int. int compareToIgnoreCase(String str) The regionMatches method boolean regionMatches(int. int) boolean regionMatches(boolean. int len = findMe.out. String findMe = "Eggs". while (!searchMe. int.compareTo(str2)).

println (str. char is position 0 System. String str2 = "Java". This method is called on a string object with no parameters and returns an integer number which is the number of characters in the string class strExample { public static void main (String args[]) { String str = "Hello".e.out.length() + str2. char ch = “abc”. However. System.char charAt (int where) This method is called on a string object with an integer value as a parameter. What they actually do is return a new String.charAt(0)). they are called immutable objects.println (str. i. //demonstrate toUpperCase and toLowerCase class ChangeCase { public static void main(String args[]) { String s = “ This is a test”.charAt(1).out. once they have been declared the objects can not be altered. there are several methods which appear to need to alter the contents of the string. it returns a char which is at the location of the parameter passed in the string.length()). The toUpperCase and ToLowerCase method String toLowerCase() String toUpperCase() These two methods are called on a string object and simply convert all letters in the string to the appropriate case. 241 . // 5 + 4 = 9 } } Altering Strings Strings in Java are actually rather like constants. Hence. // H. assigns ‘b’ to ch The length method public int length().

out. LowerCase : this is a test. The substring method String substring (int startIndex) String substring (int startIndex. Puts “Hello World” into s. the first accepts an int and the second two. String lower = s.println(“Uppercase:”+ upper).println(“Original :” + s). int endIndex) This versatile method is overloaded to have two versions. System. String s2 = s1. The first type leaves the new string with all letters from the old ranging from the first to the number specified.toUpperCase(). UpperCase : THIS IS A TEST. The trim method String trim() A very simple method called on a string object this simply removes all whitespace from the string String s = “ Hello World ”. The two are concatenated together with the object on which the method was called holding the new string. The second version allows the start of the substring being created to be specified as well as the end. System. puts “OneTwo” into s2.System. String s1 = “One”.println(“Lowercase:”+ lower). The concat method String concat(String str) This method is called on one string object with another as its parameter.out. } } The output produced by the program is shown here: Original : This is a test. String upper = s.concat(“Two”). trim().out.toLowerCase(). 242 .

char replacement) This method is called on a string object with two char parameters.// java str = str.println (str).println (str).PI)).println (str2). An example of methods which alter Strings class altStr { public static void main (String args[]) { String str = "Hello".valueOf(Math.toUpperCase(). // HELLO System.out. String s = “Hello”. when it is found it is replaced with the second. str2 = str2. int startIndex.trim(). str = str.out. System. Instead it is a static method which is overloaded to accept all simple Java types and returns a string.out.’w’). For example. int numChars) This method is slightly different to the one mentioned above because it is not called on a string object. // str now equals "HELLOjava" 243 . The string is searched for the first char parameter. to print the value of pi System. String str2 = "Java".out. puts the string”Hewwo” into s The valueOf method static static static static static String String String String String valueOf valueOf valueOf valueOf valueOf (double num) (long num) (Object obj) (char char[]) (char char[]. // str now equals "HELLO java" System.replace(‘l’. As a convenience. str = str.toLowerCase().println(String.concat(str2). the String class provides the static method valueOf() which you can use to convert variables of different types to Strings.The replace method String replace (char original.

out. str = String. class indexTest { public static void main (String args[]) { String str = "This string will be searched".substring (5. no offset (str.str. The example below shows possible versions of the two methods. // find s. find in str.println // find the string (str.out. 'i'). no offset 244 .out. int startIndex) lastIndexOf(String s. no offset System.replace ('a'.out.println (str. offset by 9 System.valueOf (3. The input parameters for these methods is a char or string which is to be found and an optional offset from the beginning (or end) of the string.println // find the string System. given as an int.println (str).lastIndexOf ('s'. str = str.141). 4)).out.length()). // str = "3.out.141" } } Searching String The indexOf and lastIndexOf methods int int int int int int int int indexOf (int ch) indexOf (String s) indexOf(int ch. find.println (str.println (str).System.indexOf (find)). int startIndex) lastIndexOf(int ch) lastIndexOf(String s) lastIndexOf(String s. String find = "will". These methods allow for the string to be searched either from the beginning (IndexOf) or from the end (lastIndexOf). System. str = str. int startIndex) indexOf(String s.out.out. System. int startIndex) These two overloaded methods allow a character or substring to be searched for. // str = "java" System.lastIndexOf(find)).indexOf ('s')).println (str). // find char. // str = "jivi" System.println (str).

} } The extension() method uses lastIndexOf() to locate the last occurrence of the period ('.substring(sep + 1. return fullpath. and the substring() method throws a "string index out of range exception". then dot + 1 is equal to the length of the string which is one larger than the largest index into the string (because indices start at 0).') in the filename.lastIndexOf(pathseparator). } String filename() { int dot = fullpath. the String class supports four different versions of both the indexOf() and lastIndexOf() methods which  returns the index of the first (last) occurrence of the specified character 245 . if the filename does not have a period ('.') to the end of the string. Also.') in it.') character is the last character of the string. dot). notice that extension() uses dot + 1 as the argument to substring(). return fullpath.substring(0.substring(dot + 1). the substring from the period ('. int sep = fullpath. The following class illustrates the use of lastIndexOf() and substring() to isolate different parts of a filename.').lastIndexOf('. Filename(String str. This code assumes that the filename actually has a period ('. Then substring() uses the return value of lastIndexOf() to extract the filename extension--that is. substring() accepts an index equal to (but not greater than) the length of the string and interpret it to mean "the end of the string". } String extension() { int dot = fullpath.lastIndexOf('. char pathseparator.} } The indexOf() and lastIndexOf() methods are frequently used in conjunction with substring() which returns a substring of the string. return fullpath. pathseparator = sep. However. char sep) { fullpath = str.').lastIndexOf(pathseparator).'). sep). While the methods in the example above uses only one version of the lastIndexOf() method. then lastIndexOf() returns -1. class Filename { String fullpath. } String path() { int sep = fullpath. If the period ('.

boolean startsWith(String str) boolean startsWith(String str. returns the index of the first (last) occurrence of the specified String.startsWith(“bar”.startsWith(“Foo”). This method uses the concept of a regular expression to specify the delimiters. The toCharArray() method If you want to convert the characters in a string to char type and store it in the character array use this method char [] toCharArray() The startsWith and endsWith methods The startsWith method determines whether a given String begins with a specified string. “Foobar”.endsWith(“bar”).3) returns true The split method J2SE 1. both return true “Foobar”. or tokens. int startIndex) boolean endsWith(String str) For example. searching forward (backward) from the specified index The getBytes method byte [] getBytes() This method converts the String to the byte array where each character in the string is converted to its ascii equivalent and stored in the array. The endsWith determines whether the String ends up with a specified String. 246 . searching forward (backward) from the specified index returns the index of the first (last) occurrence of the specified String. “Foobar”.   returns the index of the first (last) occurrence of the specified character.4 added the split() method to the String class to simplify the task of breaking a string into substrings. A regular expression is a remnant from the Unix grep tool ("grep" meaning "general regular expression parser").

println(s).out. This code displays 247 .out.split() method is much easier and more natural to use than the StringTokenizer class.out. String t = s + "there" + ". The + operator There is another special piece of string syntax using the + operator. an overloaded StringTokenizer constructor allows you to specify that the tokens to be returned include the delimiter characters themselves. how are you" + "today".length. Using split(). the first example above becomes String str = "This is a string object".println(s). Example of String concatenation with other data types int age = 9. Here int is converted to String String s = “four :” + 2 + 2. i < words.split ("*"). // t = "Hello there.In its simplest form. The split() method takes a parameter giving the regular expression to use as a delimiter and returns a String array containing the tokens so delimited.println (words[i]). simply specify "*" as the regular //expression: String str = "A*bunch*of*stars". System. System. String CustOrder = "Java Programming Course". how are you today" The following code will append several values together and output a line of text to the system console. for (int i=0. String s = "Hello". searching for a regular expression consisting of a single character finds a match of that character. the character 'x' is a match for the regular expression "x".println(CustName + " ordered a " + CustOrder + ". However. This allows strings to be added together.out. i++) System. StringTokenizer is still useful for some tasks. String[] words = str. For example. String[] starwords = str. the String. For most string splitting tasks. String s = “He is ” + age + “ years old”. String CustName = "John Smith".split (" "). For example. System. //To use "*" as a delimiter."). at the moment it is convenient to know how to use this.

which is not possible with a normal String. the system creates four String objects to handle the alterations.”. Constructors of StringBuffer class Constructor StringBuffer() Description Constructs a string buffer with no characters in it and an 248 . The effects may be minimal in this instance (given the small amount of code).four : 22 rather than four : 4 This is because the String concatenation operator has the higher precedence than the arithmetic + operator.com. The reason Java has too separate classes to deal with strings is simply for performance reasons. Hence to get the desired result use String s = “four :” + (2 + 2). but a larger application with more operations will likely degrade performance. sample1 += “the place “. This is the niche filled by the StringBuffer class. such as adding characters into to the end of a string. 10. In the end. sample1 += “to be. For example : The following code creates String objects and uses the concatenation (+) character to add more characters to them: String sample1 = new String(“Builder. The first is created with the text Builder. This is useful for a number of operation. While the original String class dealt with strings which were of a fixed length (the length of the number of characters the string contained) and whose contents could not be altered the StringBuffer class deals with strings which are not full of characters and whose contents can be changed. sample1 += “ is “. A new object is created every time more text is appended. The problem with this approach is that too many resources are being used for such a simple procedure.2 The StringBuffer Class The StringBuffer class is the second of Java's classes which deal with string handling. The plus operator which looks like it allows normal Strings to be extended actually uses the StringBuffer class and converts back to a string.com”).

// capacity = 16 StringBuffer strbuf2 = new StringBuffer (25). // capacity = 25 StringBuffer strbuf3 = new StringBuffer ("Java"). Constructs a string buffer with no characters in it and an initial capacity specified by the length argument. The StringBuffer class is designed to create and manipulate dynamic string information. in other words. The second instance of the class has no value and a capacity of 30 characters. The StringBuffer class is included in the base java. The memory allocated to the object is automatically expanded to accommodate additional text. StringBuffer strbuf = new StringBuffer (). in this case the capacity of the StringBuffer will be the number of characters in the initial string plus a further 16. The following example shows the possible ways of building StringBuffer objects. StringBuffer sb = new StringBuffer(30). Creating StringBuffer objects To create a StringBuffer object use the following: StringBuffer rb = new StringBuffer(). so no special imports statement is needed to take advantage of it. Constructs a string buffer so that it represents the same sequence of characters as the string argument. // capacity = 4 + 16 = 20 The length method int length() Returns the length (character count) of this string buffer. If the default constructor is called with no parameters this capacity is set to 16. Another constructor allows an initial set of characters to be passed as a parameter. Methods concerned with capacity 249 . and the final line creates an object with the initial value. StringBuffer sb = new StringBuffer(“Builder.com”). which is the number of characters that the StringBuffer will contain if full.StringBuffer(int capacity) StringBuffer(String str) initial capacity of 16 characters. the initial contents of the string buffer is a copy of the argument string. otherwise an int may be passed as a parameter to specify the capacity.lang package. The first line creates an object with no text and the default capacity of 16 characters. When a StringBuffer object is created it has a capacity. StringBuffer sb = new StringBuffer().

out. This will "clear" out the value in the StringBuffer.capacity()).println (strbuf. The ensureCapacity method void ensureCapacity(int capacity) Once a StringBuffer object has been created the size of the buffer can be resized using the ensureCapacity method. rb. System.println (strbuf). The following example shows this: StringBuffer strbuf = new StringBuffer ("Hello"). To reset a StringBuffer (to use it somewhere else) set the length to zero using the setLength() method. // Hello_World 250 . if the value passed (int) is greater than the existing length then the remainder will be filled with zeros.length()).out. called on the StringBuffer object with the new size (int) as the only parameter.out. // prints 21 The capacity() method differs from length() in that it returns the amount of space currently allocated for the StringBuffer. rather than the amount of space used. Note that this method ensures a minimum capacity. An example of StringBuffer capacity class altBuf { public static void main (String args[]) { StringBuffer strbuf = new StringBuffer ("Hello"). the actual capacity may be more than you have specified. System. System.out. // prints 5 System. // Hello strbuf.The capacity method int capacity() This method is called on a StringBuffer object and returns the capacity as an int.append ("_world"). The setLength method void setLength(int length) This method allows the length of a StringBuffer object to be set. unless the buffer is full.setLength(0).println (strbuf). Note that the capacity will be different to the length.println (strbuf.

boolean booleanValue) Inserts the string representation of the boolean argument into this string buffer.out.insert (6. System.out. StringBuffer insert(int index.println(“Buffer before = ” + sb).println(“charAt(1) after = ” + sb. System.charAt(1)).setLength(2). System. System.’i').println (strbuf).out.out.setCharAt(1. // Hello Java World } } The charAt and setCharAt methods char charAt(int index) void setCharAt(int index. The setCharAt method takes two parameters as input. char[] charArray) Inserts the string representation of the char array argument into this string buffer.out. //demonstrate charAt and setCharAt class CharAtDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer(“Hello”). StringBuffer insert(int index.println (strbuf). char charValue) Inserts the string representation of the char argument into this string buffer.setCharAt (5.strbuf. } } Here is the output generated by this program: Buffer before = Hello charAt(1) before = e buffer after = Hi charAt(1) after = i The insert method StringBuffer insert(int index. // Hello World strbuf. 251 .println(“charAt(1) before = ” + sb.charAt(1)).println(“Buffer after : ” +sb). "Java "). ' '). System. System. char charValue) The charAt method works the same as for a String object. sb. sb. an int to specify the position in the StringBuffer and a char which the character at the given position will be changed to.out.

int intValue) Inserts the string representation of the second int argument into this string buffer. System. the first (int) is the position where the data is to be added. int startIndex. StringBuffer insert(int index.println(sb.StringBuffer insert(int index. and the second is the data to be added (of any simple type. Indices begin at 0. An example of altering the contents of StringBuffer objects class AltBuf { 252 . or a String). Again this method is called on a StringBuffer object but it takes two parameters. "Hot " needed to be inserted before the 'J' in "Java". StringBuffer insert(int index. StringBuffer insert(int index. long longValue) Inserts the string representation of the long argument into this string buffer. so the index for 'J' is 6. StringBuffer sb = new StringBuffer("Drink Java!").out. To add data at the end of a StringBuffer use an index equal to the current length of the StringBuffer or use append(). StringBuffer insert(int index. sb. you specify the index before which you want the data inserted. char[] charArray. String str) Inserts the string into this string buffer. int numChars) Inserts the string representation of a subarray of the str array argument into this string buffer. "Hot "). This code snippet prints Drink Hot Java! With StringBuffer's many insert(). double doubleValue) Inserts the string representation of the double argument into this string buffer. This example illustrates how you would insert a string into a StringBuffer. The insert method is identical to the append method except that the data is added to the string at a specified position.toString()). float floatValue) Inserts the string representation of the float argument into this string buffer.insert(6. To insert data at the beginning of a StringBuffer use an index of 0. StringBuffer insert(int index. StringBuffer insert(int index. Object obj) Inserts the string representation of the Object argument into this string buffer. In the example.

println (strbuf). "Java "). // Hello Java World } } The toString method String toString() Converts to a string representing the data in this string buffer. // Hello_World strbuf. System. System. StringBuffer append(char[] charArray) Appends the string representation of the char array argument to this string buffer.append ("_world"). " ").out. StringBuffer append(char charValue) Appends the string representation of the char argument to this string buffer. System. StringBuffer append(char[] charArray. To output the StringBuffer value use the toString() method The append method StringBuffer append(boolean booleanValue) Appends the string representation of the boolean argument to the string buffer. // Hello World strbuf. int numChars) Appends the string representation of a subarray of the char array argument to this string buffer. // Hello strbuf. int startIndex.public static void main { StringBuffer strbuf = new ("Hello").println (strbuf).out.out. System. StringBuffer append(double doubleValue) Appends the string representation of the double argument to this string buffer.println (strbuf). StringBuffer append(float floatValue) Appends the string representation of the float argument to this string buffer. StringBuffer append(int intValue) Appends the string representation of the int argument to this string buffer.out. 253 .insert (7.println (strbuf).setCharAt (6.

StringBuffer append(long longValue) Appends the string representation of the long argument to this string buffer. This code creates the string Builder.append("r"). This method allows data of any of the simple data types to be added to the end of a StringBuffer. sb. The append method can be used to append values together.println(b. sb. sb.append("Hello”).com and sends it to the standard output.out.println(sb. StringBuffer b = new StringBuffer(). rb. This is achieved by the method being overloaded for all of the simple data types and using the valueOf method. sb.append("World").toString()). but only one object is created. This allows text to be manipulated accordingly and used for output or data storage. The StringBuffer variable.out. StringBuffer rb = new StringBuffer(). System. sb.append("B"). The append method is called on a StringBuffer object with the data to be added as an input parameter.com"). now holds the value of "Hello World!". This method converts the contents to a String object that can be used for output. The same code using String objects would require more than eight objects. Notice that the code takes advantage of the toString method of the StringBuffer class. rb. sb.append("d").append("u").toString()).append("i"). sb. System. StringBuffer append(Object obj) Appends the string representation of the Object argument to this string buffer.append("Hello").append("World!").append("e").append("l"). StringBuffer append(String str) Appends the string to this string buffer. One more example 254 .append(" "). StringBuffer sb = new StringBuffer(). The append method can accept any data type as input and converts the data to a String to be appended to the end of the value in the StringBuffer.append(". sb.

sb.com is awesome! Builder.deleteCharAt(0).out.delete(4.7).setLength(11). sb.append("Builder.out. int end) Removes the characters in a substring of this StringBuffer. 255 .com The delete method StringBuffer delete(int start. String str) Replaces the characters in a substring of this StringBuffer with characters in the specified String.println(sb. System.println(sb.out.println(“After delete :” + sb). sb.com is awesome!"). System. } } The following output is produced : After replace : This was a test The replace method public StringBuffer replace(int start. The length property is reset so that the text is truncated. //demonstrate delete and deleteCharAt class deleteDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer(“This is a test”). int end.out. The deleteCharAt method StringBuffer deleteCharAt(int index) Removes the character at the specified position in this StringBuffer (shortening the StringBuffer by one character).toString()).println(“After deleteCharAt : ” + sb). The output follows: Builder. System.toString()). sb. This code sets the capacity and populates the object with a string. System. The reverse method StringBuffer reverse() The character sequence contained in this string buffer is replaced by the reverse of the sequence.

return dest. char dst[]. Finally.The following code and output show it in action: StringBuffer sb = new StringBuffer(). The substring method String substring(int startIndex) Returns a new String that contains a subsequence of characters currently contained in this StringBuffer.append("Builder. the same size as source. The method creates a StringBuffer. dest. the method converts dest.toString(). a StringBuffer. 256 .println(sb. int srcEnd.toString()).reverse(). The getChars method public void getChars(int srcBegin. } } The reverseIt() method accepts an argument of type String called source which contains the string data to be reversed.reverse().com!"). System. sb.out. sb.println(sb. int dstBegin) Characters are copied from this string buffer into the destination character array dst.toString()). to a String. Output: Builder.com! !moc.redliuB The reverse method is present only in the StringBuffer class.out. Example class ReverseString { public static String reverseIt(String source) { StringBuffer dest = new StringBuffer(source). then loops backwards over all the characters in source and appends them to dest thereby reversing the string.ensureCapacity(100). System. Hence if you want to reverse a String you can use the StringBuffer for doing so. dest.The substring begins at the specified index and extends to the end of the StringBuffer. sb.

String substring(int startIndex.0 javac compiler normally uses StringBuilder instead of StringBuffer whenever you perform string concatenation as in System. // 2 c = "\u000a".charAt(i)).println(dest.toString()). Because StringBuilder is not synchronized. // 1 b = "\r". } } The output from this program is: doT saw I was toD Questions 1. the J2SE 5. so it really is a drop-in replacement. This program uses both a string and a string builder. i >= 0. which reverses the characters of a string.println ("The result is " + result). In general. int endIndex) Returns a new String that contains a subsequence of characters currently contained in this StringBuffer. class MCZ17 { public static String String String String } } void main (String[] args) { a = "\n". // 3 \u000a = new line d = "\u000d". In fact. All the methods available on StringBuffer are also available on StringBuilder.length(). Following is a sample program called StringsDemo. 10. i--) { dest.1).out. } System.append(palindrome. public class StringsDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod". int len = palindrome.3 The StringBuilder class J2SE5. which is a drop-in replacement for StringBuffer in cases where thread safety is not an issue. it offers faster performance than StringBuffer.out. // 4 \u000d = return 257 . you should use StringBuilder in preference over StringBuffer. StringBuilder dest = new StringBuilder(len).0 added the StringBuilder class. for (int i = (len .

1 2.Compile-time errors are generated at which lines? a. String c = '\u0041'. 4 } public static void main (String[] args) { // Insert code here. e. 3 d. String a = 'a'. c. String b = 'abc'. } Which of the following lines can be inserted at the specified location without generating a compile-time error? a. d. None of the above 258 . 2 c. String d = '\uabcd'. class MCZ20 { b. b.

like this: Reading open a stream while more information read information close the stream Writing open a stream while more information write information close the stream The java. a program opens a stream on an information source (a file.io package. a program can send information to an external destination by opening a stream to a destination and writing the information out sequentially. as shown here Similarly. I/O Stream Classes 259 .io package contains a collection of stream classes that support these algorithms for reading and writing. based on the data type (either characters or bytes) on which they operate.Chapter 11 : I/O 11. memory.1 I/O Streams To bring in information. To use these classes. The stream classes are divided into two class hierarchies. a socket) and reads the information sequentially. a program needs to import the java.

This diagram shows most of the members of the java. parallelograms are abstract classes. and ovals are interfaces Byte Streams 260 . Rectangles are classes.io package.

To read and write 8-bit bytes. The InputStream class defines a methods for reading bytes or arrays of bytes. int offset. skipping bytes of input. both Reader and InputStream provide methods for marking a location in the stream. and resetting the current position. finding out the number of bytes that are available for reading. Two of the byte stream classes. The OutputStream class is an abstract base class that provides a minimal programming interface and a partial implementation of output streams in Java. ObjectInputStream and ObjectOutputStream. The InputStream class is an abstract base class that provides a minimal programming interface and a partial implementation of input streams in Java. Reader provides the API and partial implementation for readers--streams that read 16-bit characters--and Writer provides the API and partial implementation for writers--streams that write 16-bit characters. are used for object serialization. OutputStream defines methods for writing bytes or arrays of bytes to the stream and flushing the stream. 261 . or let it be closed implicitly when the object is garbage collected. Subclasses of Reader and Writer implement specialized streams and are divided into two categories: those that read from or write to data sinks Understanding the I/O Superclasses and InputStream define similar APIs but for different data types. int length) InputStream defines the same methods but for reading bytes and arrays of bytes: int read() int read(byte cbuf[]) int read(byte cbuf[]. InputStream and OutputStream provide the API and partial implementation for input streams (streams that read 8-bit bytes) and output streams (streams that write 8-bit bytes). skipping input. For example. int offset.io. You can explicitly close a stream with the close() method. Character Streams Reader and Writer are the abstract superclasses for character streams in java. and resetting the current position within the stream. These streams are typically used to read and write binary data such as images and sounds. int length) Also. marking locations in the stream. programs should use the byte streams. You can explicitly close an output stream with the close() method. An output stream is automatically opened when you create it. or let it be closed implicitly when the object is garbage collected. Reader contains these methods for reading characters and arrays of characters: Reader int read() int read(char cbuf[]) int read(char cbuf[]. An input stream is automatically opened when you create it. descendants of InputStream and OutputStream.

Or the garbage collector can implicitly close it. Writer defines these methods for writing characters and arrays of characters: int write(int c) int write(char cbuf[]) int write(char cbuf[]. Note that many times.io contains character streams and byte streams that perform the same type of I/O but for different data types. which occurs when the object is no longer referenced. and output streams--are automatically opened when created.io's streams and describes what they do. writers. int offset. input streams. int offset. Type of I/O Byte Streams Character Streams ByteArrayInputStream CharArrayReader Memory ByteArrayOutputStream CharArrayWriter StringReader StringWriter PipedReader PipedWriter FileReader FileWriter StringBufferInputStream PipedInputStream PipedOutputStream FileInputStream FileOutputStream SequenceInputStream ObjectInputStream ObjectOutputStream DataInputStream DataOutputStream LineNumberInputStream PushbackInputStream PrintStream BufferedInputStream BufferedOutputStream FilterInputStream FilterOutputStream Pipe File Concatenation Object Serialization Data Conversion Counting Peeking Ahead Printing Buffering Filtering Converting between Bytes and Characters Use of streams N/A N/A N/A LineNumberReader PushbackReader PrintWriter BufferedReader BufferedWriter FilterReader FilterWriter InputStreamReader OutputStreamWriter 262 .Writer and OutputStream are similarly parallel. int length) And OutputStream defines the same methods but for bytes: int write(int c) int write(byte cbuf[]) int write(byte cbuf[]. java. You can close any stream explicitly by calling its close method. Stream classes The following table lists java. int length) All of the streams--readers.

CharArrayWriter. StringWriter. is similar to StringReader. Pipes are used to channel the output from one thread into the input of another. these streams are used to read from or write to a file on the native file system. StringReader. ByteArrayOutputStream Use these streams to read from and write to memory. ByteArrayInputStream. StringWriter collects the characters written to it in a StringBuffer. SequenceInputStream Concatenates multiple input streams into one input stream. DataInputStream. PipedOutputStream Implement the input and output components of a pipe. ObjectInputStream. StringBufferInputStream StringBuffer. except that it reads bytes from a PipedReader.CharArrayReader. ObjectOutputStream Used to serialize objects. You create these streams on an existing array and then use the read and write methods to read from or write to the array. PipedInputStream. which can then be converted to a String. LineNumberInputStream. PipedWriter. LineNumberReader Keeps track of line numbers while reading. DataOutputStream Read or write primitive data types in a machine-independent format. FileOutputStream Collectively called file streams. FileInputStream. FileWriter. Use StringWriter to write to a String. StringBufferInputStream Use StringReader to read characters from a String in memory. PushbackReader. PushbackInputStream 263 . FileReader.

FilterWriter. An OutputStreamWriter converts characters to bytes.getProperty("file. which filter data as it's being read or written.These input streams each have a pushback buffer. thereby reducing the number of accesses required on the original data source. which is the keyboard by default.in refers to the standard input. which also is the console by default. System. You can get the name of the default character encoding by calling System. An InputStreamReader reads bytes from an InputStream and converts them to characters. InputStreamReader. FilterOutputStream These abstract classes define the interface for filter streams. so you will often see other writable streams wrapped in one of these. BufferedReader. using the default character encoding or a character encoding specified by name. using the default character encoding or a character encoding specified by name and then writes those bytes to an OutputStream. FilterReader. 264 . By default this is the console. These fields are declared as public static within System. When reading data from a stream. BufferedInputStream. FilterInputStream. However. Buffered streams are typically more efficient than similar nonbuffered streams and are often used with other streams. BufferedWriter. System.encoding"). out and err. in. PrintStream. which encapsulates several aspects of the run-time environment. it is sometimes useful to peek at the next few bytes or characters in the stream to decide what to do next. these streams may be redirected to any compatible I/O device. These are the easiest streams to write to. System also contains three predefined streams variables. PrintWriter Contain convenient printing methods. BufferedOutputStream Buffer data while reading or writing. The predefined Streams The java. System.lang defines a class called System.err refers to the standard error stream.out refers to standard output stream. OutputStreamWriter A reader and writer pair that forms the bridge between byte streams and character streams.

io.out. that converts bytes to characters. } } } One example that reads from the console and prints the same string and terminates when an empty string is entered.in in a BufferedReader object.out. you wrap System.2 Reading console input In Java.println(e). use the following constructor: InputStreamReader (InputStream inputStream) Because System.in refers to an object of type InputStream. 265 .in is an object of the type InputStream. console input is accomplished by reading from System.print("Enter a line:"). The constructor of BufferedReader used is shown below: BufferedReader (Reader inputReader) Here inputReader is the stream that is linked to the instance of BufferedReader that is being created. InputStreamReader is its concrete sub-class.out and System.*. Its general form is shown here: String readLine() throws IOException An example of reading an entire line of input from console import java. The readLine() method is a member of BufferedReader class. BufferedReader supports buffered input stream. System. System.out.println(stdin.readLine()).in)). Reader is an abstract class. it can be used for inputStream. } catch(IOException e) { System. to create a character stream. To obtain InputStreamReader object.in. To obtain a character-based stream that is attached to the console. System. BufferedReader stdin =new BufferedReader( new InputStreamReader(System. These are byte streams.System. even though they typically are used to read and write characters from and to the console.in)). 11. public class ConsoleInputDemo { public static void main(String[] args) { try { BufferedReader stdin =new BufferedReader( new InputStreamReader(System.err are objects of type PrintStream.

io. The OutputStreamWriter class only has a few basic write() methods.println(s).out. System. } while( c != ‘q’).in)).3 Writing console output This example prints a single character on the console. BufferedReader br = new BufferedReader ( new InputStreamReader(System.length() != 0) { System.io. We can obtain many print() and println() overloaded methods with the PrintWriter class.*.in)). } // An empty line terminates the program } catch(IOException e) { e.readLine()).print(c). System.out.*.*. String s = null. ‘q’ to quit:”). } } } An example of reading characters import java. try { while((s = in.io. } } 11.import java. In this example we simply wrap the 16-bit encoded OutputStreamWriter class around the usual System. 266 . class BRRead { public static void main(String args[]) throws IOException{ char c. //read characters do { c = (char) br. import java.out stream.read().out. public class Echo { public static void main(String[] args) { DataInputStream in = new DataInputStream( new BufferedInputStream(System.printStackTrace().println(“Enter characters .

text.write(c).charAt(i). which provides a wide range of formatting options combined with output operation. i< s. try { for( int i = 0.true). String s = “Hello”. String s = “Hello”. OutputStreamWriter osw = new OutputStreamWriter(System. osw.out. try { pw.println( "IO error:" + ioe ).public class SingleCharConsole16bit { public static void main(String f[]) { char c.printf() The java.*. public class StringOutput { public static void main(String f[]) { PrintWriter pw = new PrintWriter(System. i++) { c = s.flush(). 267 . } } } 11.out).println( "IO error:" + ioe ). // Wrap the System. } osw. } } } Another example that prints a String on the console using PrintWriter class.io.4 System. We take advantage of the autoflushing switch in one of the PrintWriter constructors so that we do not have to flush the buffers explicitly ourselves after every print.length(). import java. } catch (IOException ioe) { System.println(s).out.out.out 8-bit stream with the 16-bit // output stream.out.Format subclasses offer limited formatting capabilities and are rather clumsy compared to the C language printf() function. } catch (IOException ioe) { System.

out.octal integer 'e' .printf() to send formatted numerical output to the console..Formatter object internally. It uses a java. The format argument is a string in which you embed specifier substrings that indicate how the arguments appear in the output..util.142 The format string includes the specifier "%5.PI. of which there are several besides 'f'. It allows a method to accept a variable number of arguments. The arguments can be primitives as well as object references.g.3f" that is applied to the argument. The width value 5 requires at least five characters for the number. Object. Some of the other conversions include 'd' ." indicates the varargs functionality. The general form of the specifier includes several optional terms: %[argument_index$][flags][width][. pi). e.. Furthermore.decimal integer 'o' . which can both format numerical output into a string and send the string to a file or other destination Numerical values are formatted according to format specifiers like those for the printf() function in C. J2SE 5. System. The simplest of the overloaded versions of the method goes as printf (String format. J2SE 5. the precision value 3 requires three places in the fraction. args) The ".3f%n". A specifier needs at least the conversion character. So now you can use System.0 comes with the class java. For example.Formatter.precision]conversion 268 .To satisfy the demands of programmers for such a facility and to facilitate the porting of C programs to Java.util. double pi = Math.printf ("pi = %5.out. The '%' sign signals a specifier.0 added a printf() method to the PrintStream class..floating-point in scientific notation There are also special conversions for dates and times. and the conversion symbol 'f' indicates a decimal representation of a floating-point number. the wrappers for the primitives. results in the console output pi = 3.

0/3. A "\n" can also be used in some cases.printf ("3.PI.0 = %09. // NaN System. // User the argument index to put the argument values into // different locations within th string.printf ("pi = %5.printf ("C = 2 * %1$5.0. // Increase the number of decimal places System. r).5f %n".0. 269 .out.2e %n". q = 0.out. System. but since "%n" always outputs the correct platformspecific line separator. A flag indicates an option for the format. The width indicates the minimum number of characters and the precision is the number of places for the fraction. System.5f * %2$4.0/2. // Multiple arguments System.out. '+' requires that a sign be included and '0' requires padding with zeros.2e %n". // Print the number with 3 decimal places.3f.0/0.0/4567. q). System. // Scientific notation q = 1000.printf ("1.1f.out.printf ("1. q).1f * %2$4. System.0. It is " %n" which outputs a line break.0/2.out.printf ("-1. e = %5.out.out.0 = %5.printf ("1.0/3.2e %n".0 = %7. // More scientific notation q = 3. The following program provides several examples of printf().out.0/ = %7. For example.The argument_index indicates to which argument the specifier applies.0/0. q).4f %n". Math. For example. q). "+ "A = %2$4.3f %n".2e %n".0 = %7.out.0/0. public class PrintfDemo { /** Illustrate several output formats with printf() **/ public static void main (String args[]) { double q = 1. q).0 = %5.0 = %7. // Negative infinity q = -1. Math. double r = 1. System.PI.0/4567.0/0. System.1f * %1$5.printf ("1000/3. Math. q).printf ("0. it is portable across platforms whereas"\n" is not. // Pad with zeros.1. %2$ indicates the second argument in the list. q).0/3.3f %n". q = 1.E). There is also one specifier that doesn't correspond to an argument.5f %n".0.

500 1000/3. which most often is where the Java Virtual Machine is invoked.0/2.142.class").class"). To use this format you'll have to know the "current user directory". A = 1.0 = 0.1.0/0.} } // class PrintfDemo Output of this program: 1.57e-04 -1.0 = -Infinity 0. such as permissions.io can be used to obtain or manipulate the information associated with a disk file. String filename). String filename). e = 2.0 = 6.33333 1. A File object can represent either the name of a particular file or the names of a set of files in a directory. time.14159 11. and to navigate subdirectory hierarchies. date and directory path. We create an instance of the class by giving the name of the file (or directory).0/3.0 = NaN pi = 3. There are several constructors: The File class has the following constructors File(String pathname).0 = 3. Or File f = new File ("c:/server/classes/Hansen/playground/MyFile.7183 C = 2 * 3.1 * 3.0/3.0 = 0.0/4567. File(File directory.14159 * 1.5 File class A File class present in java.0 = 00000. // pathname could be file or a directory name File(String dirPathname.0/0. The simplest is this (using Windows file-syntax): File f = new File ("c:\\server\\classes\\hansen\\playground\\MyFile.33e+02 3. You may also use a relative file name like this: File f = new File("hansen\\playground\\MyFile.class"). If you are in doubt you can get the name of the current user directory like this: 270 .1 * 1.333 1.

String userdir = System.getProperty("user.dir");

Several methods are available for inspecting an instance of the File class. Some of the important ones are: Method
boolean exists() boolean isFile() boolean isDirectory() String[] list() String getName() String getPath()

Purpose does the file exist? is it a file? … or a directory? return the names of all files and directories in a directory get the file or directory's name get the file or directory's path

These methods are actually all we need in order to find all files and directories in a given directory--all the way down to the last leaves in the directory tree The File class is more than just a representation for an existing directory path, file, or group of files. You can also use a File object to create a new directory or an entire directory path. You can also look at the characteristics of files (size, last modification date, read/write), see whether a File object represents a file or a directory, and delete a file. If the file mentioned is not found the program simply exits.
import java.io.*; public class FileExample { public static void main(String[] args) { File f = new File(args[0]); if(f.exists()) { System.out.println(f + " exists"); } else { return; } System.out.println( "Absolute path: " + f.getAbsolutePath() + "\n Can read: " + f.canRead() + "\n Can write: " + f.canWrite() + "\n getName: " + f.getName() + "\n getParent: " + f.getParent() + "\n getPath: " + f.getPath() + "\n file size: " + f.length() + "\n lastModified: " + f.lastModified()); if(f.isFile()) System.out.println("it's a file"); else if(f.isDirectory()) System.out.println("it's a directory"); File rname = new File(args[1]);


f.renameTo(rname); File another = new File(args[2]); System.out.println("deleting..." + another); another.delete(); File makedir = new File(args[3]); makedir.mkdir(); } }

This program takes a filename as the first argument checks whether it exists. If yes then prints the characteristics of the file else exits the program. Next it also checks whether the file object is a file or directory. Then it renames the file as the second argument. The third argument specifies the file to be deleted. The fourth argument is the name of the new directory that gets created. The following program prints the list of all filenames and names of sub directories into the current directory.
// Displays directory listing import java.io.*; public class DirList { public static void main(String[] args) { try { File path = new File("."); // current directory String[] list = path.list(); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } catch(Exception e) { e.printStackTrace(); } } }

The following program prints the list of only .java files in the current directory
import java.io.*; public class DirList { public static void main(String[] args) { try { File path = new File("."); // current directory String[] list = path.list(new DirFilter(“.java”)); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } catch(Exception e) { e.printStackTrace(); } } }


class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { // Strip path information: String f = new File(name).getName(); return f.indexOf(afn) != -1; } }

The interface FilenameFilter has only one method
boolean accept(File dir, String name);

It says that all this type of object does is provide a method called accept( ). The whole reason behind the creation of this class is to provide the accept( ) method to the list( ) method so that list( ) can call back accept( ) to determine which file names should be included in the list. Thus, this technique is often referred to as a callback or sometimes a functor (that is, DirFilter is a functor because its only job is to hold a method). Because list( ) takes a FilenameFilter object as its argument, it means that you can pass an object of any class that implements FilenameFilter to choose (even at runtime) how the list( ) method will behave. The purpose of a callback is to provide flexibility in the behavior of code. DirFilter shows that just because an interface contains only a set of methods, you’re not restricted to writing only those methods. In this case, the DirFilter constructor is also created. The accept( ) method must accept a File object representing the directory that a particular file is found in, and a String containing the name of that file. You might choose to use or ignore either of these arguments, but you will probably at least use the file name. Remember that the list( ) method is calling accept( ) for each of the file names in the directory object to see which one should be included – this is indicated by the boolean result returned by accept( ). To make sure that what you’re working with is only the name and contains no path information, all you have to do is take the String object and create a File object out of it, then call getName( ) which strips away all the path information (in a platform-independent way). Then accept( ) uses the String class indexOf( ) method to see if the search string afn appears anywhere in the name of the file. If afn is found within the string, the return value is the starting index of afn, but if it’s not found the return value is -1. Keep in mind that this is a simple string search and does not have regular expression “wildcard” matching.


11.6 Using File Streams
File streams are perhaps the easiest streams to understand. The file streams-- FileReader, FileWriter, FileInputStream, and FileOutputStream--each read or write from a file on the native file system. You can create a file stream from a file name in the form of a string, a File object, or a FileDescriptor object. An Example of reading from a file using FileReader and printing the file contents on the console. The filename is passed as a command line argument. The FileReader class below accepts the filename as the argument and opens it for reading. If the file is not found an exception of type FileNotFoundException is thrown. FileNotFoundException is a checked exception and is a subclass of IOException. The readLine method of the BufferedReader reads a String till the end of the line. It throws the checked IOException. Hence both the exeptions are handled explicitly by using catch blocks.
import java.io.*; public class FileReadDemo { public static void main(String[] args) { try { BufferedReader in =new BufferedReader(new FileReader(args[0])); String s = new String(); String s2=””; while((s = in.readLine())!= null) s2 += s + "\n"; in.close(); } catch(FileNotFoundException e) { System.out.println(e); } catch(IOException e){ System.out.println(e); } } }

The following program uses FileReader and FileWriter to copy the contents of a file named farrago.txt into a file called outagain.txt:
import java.io.*; public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt"); FileReader in = new FileReader(inputFile);


FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } }

This program is very simple. It opens a FileReader on farrago.txt and opens a FileWriter on outagain.txt. The program reads characters from the reader as long as there's more input in the input file and writes those characters to the writer. When the input runs out, the program closes both the reader and the writer. Here is the code that the Copy program uses to create a file reader:
File inputFile = new File("farrago.txt"); FileReader in = new FileReader(inputFile);

This code creates a File object that represents the named file on the native file system. File is a utility class provided by java.io. The Copy program uses this object only to construct a file reader on a file. However, the program could use inputFile to get information, such as its full path name, about the file. After you've run the program, you should find an exact copy of farrago.txt in a file named outagain.txt in the same directory. Remember that FileReader and FileWriter read and write 16-bit characters. However, most native file systems are based on 8-bit bytes. These streams encode the characters as they operate according to the default character-encoding scheme. You can find out the default characterencoding by using System.getProperty("file.encoding"). To specify an encoding other than the default, you should construct an OutputStreamWriter on a FileOutputStream and specify the encoding. A program that prints the line in a file myfile.txt
import java.io.*; class FileOutputDemo { public static void main(String args[]) { FileOutputStream out; // declare a file output object PrintStream p; // declare a print stream object try {


} catch (Exception e) { System.err.println ("Error writing to file"); } } }

// Create a new file output stream // connected to "myfile.txt" out = new FileOutputStream("myfile.txt"); // Connect print stream to the output stream p = new PrintStream( out , true); p.println ("This is written to a file"); p.close();

Here is another version of the program, CopyBytes, which uses FileInputStream and FileOutputStream instead of FileReader and FileWriter.
import java.io.*; public class CopyBytes { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt"); FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } }

An example to read from a file and print it on screen and also print the line numbers in front of each line
import java.io.*; class ReadFileDemo { public static void main(String args[]) { try { FileReader fin = new FileReader(“file1.txt”); LineNumberReader li =new LineNumberReader(fin); BufferedReader in4 = new BufferedReader(li); PrintWriter out1 = new PrintWriter(System.out, true); String s=null; while((s = in4.readLine()) != null ) {


} }

} catch(EOFException e) { System.out.println("End of stream"); }

out1.println("Line " + li.getLineNumber() + s); } out1.close();

An example of storing some content in a file and recovering it.
import java.io.*; public class FileStore { public static void main(String[] args) { try { DataOutputStream out2 = new DataOutputStream( new BufferedOutputStream( new FileOutputStream("Data.txt"))); out2.writeDouble(3.14159); out2.writeBytes("That was pi"); out2.close(); DataInputStream in5 = new DataInputStream( new BufferedInputStream( new FileInputStream("Data.txt"))); BufferedReader in5br = new BufferedReader( new InputStreamReader(in5)); System.out.println(in5.readDouble()); System.out.println(in5br.readLine()); } catch(EOFException e) { System.out.println("End of stream"); } } }

Another program that reads from a file using FileInputStream one byte at a time but checks whether the information is available before reading.
import java.io.*; public class TestEOF { public static void main(String[] args) { try { DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("TestEof.java"))); while(in.available() != 0) { System.out.print((char)in.readByte());


} }

} } catch (IOException e) { System.err.println("IOException"); }

Concatenating Files The SequenceInputStream creates a single input stream from multiple input sources. This example program, Concatenate, uses SequenceInputStream to implement a concatenation utility that sequentially concatenates files file1.txt and file2.txt together. This is the controlling class of the Concatenate utility:
import java.io.*; public class Concatenate { public static void main(String[] args) throws IOException { FileInputStream fin1 = new FileInputStream(“file1.txt”); FileInputStream fin2 = new FileInputStream(“file2.txt”); SequenceInputStream s = new SequenceInputStream(fin1,fin2); int c; while ((c = s.read()) != -1) System.out.write(c); s.close(); } }

11.7 Scanning text with java.util.Scanner
J2SE 5.0 adds classes and methods that can make every day tasks easier to perform. You will see how the newly added java.util.Scanner class makes it easier to read and parse strings and primitive types using regular expressions. Before the J2SE 5.0 release, you probably would have written code such as the following TextReader class to read text from a file:
import java.io.*; public class TextReader { public static void main(String[] args) { try { File file = new File(“TextSample.txt”); FileReader reader = new FileReader(file); BufferedReader in = new BufferedReader(reader);


Scanner.next()).} } } catch (IOException e) { e.util.readLine()) != null) { System. public class TextScanner { public static void main (String args[]) { try { File file = new File(“TextSample. The class then creates a FileReader associated with the file and then a BufferedReader from the FileReader.out. } in. You can simplify the code in TextReader by using java. you need to create a document for the class to read and parse.println(string).close().Scanner.printStackTrace().util.out. It then uses the BufferedFile reader to read the file one line at a time.*.txt”). a class that parses primitive types and strings: import java. } String string = null. To create the document. import java. while (scanner. You should see the original file echoed back to you in standard output. } scanner. save the following two lines of text in a file named TextSample.hasNext()) { System.util. } } } You should get the following output: 279 . Scanner scanner = new Scanner(file). The basic approach in classes like this is to create a File object that corresponds to the actual file on the hard drive.close().println(scanner. To view the TextReader class in action. } catch (FileNotFoundException e) { e.io.txt in the same directory as TextReader: Here is a small text file that you will use to test java.printStackTrace().scanner. while ((string = in.

getProperty("line. TextScanner prints the String returned by next() on a separate line. TextScanner then calls the hasNext() method in Scanner.Pattern to the method. through the useDelimiter method of Scanner.Here is a small text file that you will use to test java. So until it reaches the end of the file.hasNext()) { System.print("Enter int.scanner. // returns rest of line & eats the '\n' 280 . } catch (FileNotFoundException e) { e. while (scanner.next()). you can read the input one line at a time by using the newline character (\n) as a delimiter. int a = input. System.println(scanner. Here is the revised code for TextScanner that uses a newline character as the delimiter: try { Scanner scanner = new Scanner(new File(fileName)).separator")).regex. You can pass in a String or a java.close(). line: "). You can change the delimiter that is used to tokenize the input.useDelimiter (System. By default the delimiter pattern is whitespace.out. double.util. The Scanner breaks the contents of the File into tokens using a delimiter pattern.printStackTrace().nextInt(). which is the case until it reaches the end of the file.util. This method returns true if another token exists in the Scanner's input.nextDouble(). For example. } scanner.next(). word. The next() method returns a String that represents the next token. TextScanner creates a Scanner object from the File.out. // returns a String up to next whitespace String line = input. double x = input. } One more example of using Scanner public class ScannerTest { public static void main(String[] args) { Scanner input = new Scanner(System.nextLine(). scanner. String word = input.in).

System.io.java")). double.out. // close file output stream } catch(IOException e) { e.in)). class Redirecting { public static void main(String[] args) { try { BufferedInputStream in = new BufferedInputStream( new FileInputStream("Redirecting. BufferedReader br = new BufferedReader( new InputStreamReader(System.printStackTrace(). System.println(a + ":" + x + ":" + word + ":" + line).56 Great time had by all! -12:34.8 Redirecting Standard I/O The methods in System class allow you to redirect the standard input. and error IO streams using simple static method calls: setIn(InputStream) setOut(PrintStream) setErr(PrintStream) Redirecting output is especially useful if you suddenly start creating a large amount of output on your screen and it’s scrolling past faster than you can read it. // write it to another file } out.true)). } } } 281 . Here’s a simple example that shows the use of these methods: import java.close(). word.out").readLine()) != null) { System.} } System. output. //reads from the file String s.setIn(in).56:Great: time had by all! 11. Sample output: Enter int.out.println(s). Redirecting input is valuable for a command-line program in which you want to test a particular user-input sequence repeatedly. System.setErr(out). while((s = br. line: -12 34.*.setOut(out). PrintStream out = new PrintStream(new BufferedOutputStream( new FileOutputStream("test.

you must indicate whether you will be just reading the file or also writing to it.  int skipBytes(int)--Moves the file pointer forward the specified number of bytes 282 . (You have to be able to read a file in order to write it. The file pointer indicates the current location in the file.) The following code creates a RandomAccessFile to read the file named farrago. RandomAccessFile contains three methods for explicitly manipulating the file pointer. In addition to the normal file I/O methods that implicitly move the file pointer when the operation occurs. you can use the common read or write methods defined in the DataInput and DataOutput interfaces to perform I/O on the file. The RandomAccessFile class implements both the DataInput and DataOutput interfaces and therefore can be used for both reading and writing. 11. When the file is first created. such as paper and magnetic tape. The RandomAccessFile class in the java. Although such streams are incredibly useful. After the file has been opened. the file pointer is set to 0. on the other hand. and redirects standard output and standard error to another file. You can do this with a file name or a File object. A random access file. When you create a RandomAccessFile. RandomAccessFile supports the notion of a file pointer.This program attaches standard input to a file. RandomAccessFile is similar to FileInputStream and FileOutputStream in that you specify a file on the native file system to open when you create it. Calls to the read and write methods adjust the file pointer by the number of bytes read or written.9 Working with Random Access Files The input and output streams in this lesson so far have been sequential access streams--streams whose contents must be read or written sequentially. they are a consequence of a sequential medium. "r"). "rw"). indicating the beginning of the file. access to a file's contents. or random.io package implements a random access file.txt: new RandomAccessFile("farrago. And this one opens the same file for both reading and writing: new RandomAccessFile("farrago.txt".txt". permits nonsequential.

println("Now display four bytes interior to the file.println("Now open and read the file for random access“).println("Note that four bytes have been overwritten.write('W'+cnt).read()) != -1) System.getFilePointer()."). class files03{ public static void main(String[] args) { File junkFile = new File("junk. } System. inData. System. inData.read() ).out.print( (char)inData.")."). System.io. //Get current location of the file pointer.print((char)temp).out. //Set the file pointer to a location interior to // the file. //Now read and display four bytes. System. inData. cnt++) inData.*.out.out.out."). long filePointer = inData. cnt < 4. try{ RandomAccessFile inData = new RandomAccessFile(junkFile.println(“\nNow write four bytes interior to the file."rw"). int temp. for(int cnt = 0.println("Display the entire file as characters.out. while( (temp = inData.seek(filePointer-8). } catch(IOException e){} 283 .read()) != -1) { System. cnt < 4.txt").out. filePointer = inData.  void seek(long)--Positions long getFilePointer()--Returns the file pointer just before the specified byte the current byte location of the file pointer An example of using RandomAccessFile import java. for(int cnt = 0.out.").seek(0).print((char)temp). System. cnt++) System. inData. while( (temp = inData.out. //Note that it is necessary to reposition the file // pointer to the beginning of the file.close().seek(filePointer-4).println("Now display the entire file again.getFilePointer(). System.

The filter streams are FilterInputStream or FilterOutputStream.io DataInputStream and DataOutputStream classes. FilterInputStream.. filters it.io package contains only one subclass of FilterReader: PushbackReader. }// end main }//end class files03 definition 11. and passes on the filtered data to the caller. DataIODemo. //do something interesting here } Note that the readLine method has been deprecated in the DataInputStream.readLine()) != null) { .in)). and FilterOutputStream.) The java.System.io package are subclasses of FilterInputStream and FilterOutputStream and are listed here:      and DataOutputStream BufferedInputStream and BufferedOutputStream DataInputStream LineNumberInputStream PushbackInputStream PrintStream (This is an output stream. therefore we've wrapped it in a BufferedReader. some count data as it goes by. A filter stream filters data as it's being read from or written to the stream.10 Filter Streams The java.println("\nEnd of program"). attach the filter stream to another input or output stream when you create it. that reads and writes tabular data (invoices for 284 . you can attach a filter stream to the standard input stream. while ((input = d. String input. The write method in a writable filter stream filters the data and then writes it to the underlying stream.. Most filter streams provided by the java. Using Filter Streams To use a filter input or output stream. and others convert data to another form. as in the following code: BufferedReader d = new BufferedReader(new DataInputStream(System. Some streams buffer the data.out. How to Use DataInputStream and DataOutputStream This page shows you how to use the java. A filter stream is constructed on another stream (the underlying stream). For example. The read method in a readable filter stream reads input from the underlying stream. The filtering done by the streams depends on the stream. It features an example.io package provides a set of abstract classes that define and partially implement filter streams.

} out. the data looks like this.writeDouble(prices[i]).length.charAt(0).99 9. while ((chr = in.writeChar('\n').readChar() != lineSep) { desc. } 285 . out.writeChar('\t'). it's attached to named invoice1.writeInt(units[i]).writeChar('\t'). the number of units ordered.close().append(chr). desc = new StringBuffer(20). Next. out.getProperty("line. char lineSep = System. Then DataIODemo just reads the data back in using DataInputStream's specialized read methods. i ++) { out. must be attached to another a FileOutputStream that is set up to write to a file DataOutputStream out = new DataOutputStream( new FileOutputStream("invoice1.readInt(). i < prices.txt. although it is read and written in binary form and is non-ASCII: 19. Conceptually. a set up to read the file just written. invoice1. and a description of the item.readDouble().txt: output streams.99 12 8 Java T-shirt Java Mug DataOutputStream. in.separator"). The columns contain the sales price. DataIODemo uses DataOutputStream's specialized write methods to write the invoice data contained within arrays in the program according to the type of data being written: for (int i = 0. //throws out the tab char chr. like other filtered OutputStream. also must be attached to another InputStream. DataInputStream FileInputStream try { while (true) { price = in.readChar().readChar(). Next.txt")). out. //throws out the tab unit = in.merchandise). out. in. In this case. DataIODemo opens a DataInputStream on the file just written: DataInputStream in = new DataInputStream( new FileInputStream("invoice1.writeChars(descs[i]). The tabular data is formatted in columns separated by tabs. in this case. out.txt")).

total = total + unit * price.*.read()) != null) { .close(). "Java Pin". 29. which indicates that the end of the file has been reached.length.out. "Java Mug". "Java Key Chain" }.writeInt(units[i]). .txt")).io. Well. 4.99 }. out. i < prices. you see loops like this: while ((input = in.println("You've ordered " + unit +" units of " + desc + " at $" + price). For example. So DataInputStreams read methods throw an EOFException instead.System.writeChar('\t'). because -1 is a legitimate value that can be read from the input stream. for (int i = 0. When all of the data has been read.99. when data is read. readInt. the while (true) terminates. import java. DataIODemo displays a statement summarizing the order and the total amount owed and then closes the stream. double[] prices = { 19. out.99.99. null. . String[] descs = { "Java T-shirt". public class DataIODemo { public static void main(String[] args) throws IOException { // write the data out DataOutputStream out = new DataOutputStream(new FileOutputStream("invoice1. out. or one of the other methods that reads numbers. Note the loop that DataIODemo uses to read the data from the DataInputStream. Normally. out. in. 286 . } The read method returns a value.writeChars(descs[i]).println("For a TOTAL of: $" + total).99. you can't. Many of the DataInputStream read methods can't do this. int[] units = { 12. using readDouble. 3. i ++) { out.out. 50 }. 15. because any value that could be returned to indicate the end of file may also be a legitimate value read from the stream.writeDouble(prices[i]). 13. } } catch (EOFException e) { } System. out.writeChar('\t'). 9. "Duke Juggling Dolls". suppose that you want to use -1 to indicate end of file.writeChar('\n'). 8. When the EOFException occurs.

8800000000001 11. double total = 0.readChar().99 You've ordered 29 units of Java Pin at $3. // read it in again DataInputStream in = new DataInputStream(new FileInputStream("invoice1.readChar()) != lineSep) desc. total = total + unit * price.close().99 You've ordered 13 units of Duke Juggling Dolls at $15.println("You've ordered " + unit + " units of " +desc + " at $" + price). 287 . } } catch (EOFException e) { } System. However. System.ObjectInputStream and ObjectOutputStream-.99 For a TOTAL of: $892.readDouble(). double price.append(chr).io-. int unit. while ((chr = in.out.99 You've ordered 50 units of Java Key Chain at $4. // throws out the tab char chr.0.println ("For a TOTAL of: $" + total).99 You've ordered 8 units of Java Mug at $9. try { while (true) { price = in. StringBuffer desc.getProperty("line. in.11 Object Serialization Two streams in java.are byte streams and work like the other input and output streams.} out. in. in. char lineSep = System. desc = new StringBuffer(20).readInt().charAt(0).close(). they are special in that they can read and write objects. } } When you run the DataIODemo program you should see the following output: You've ordered 12 units of Java T-shirt at $19.out.separator").txt")). // throws out the tab unit = in.readChar().

Next. You can use these methods to write primitive data types to an ObjectOutputStream. the string Today and a Date object are written to the stream with the writeObject method of ObjectOutputStream. For example. Thus reading and writing objects is a process called object serialization. ObjectOutputStream must be constructed on another stream. ObjectOutputStream implements the DataOutput interface that defines many methods for writing primitive data types. s. s. First.writeObject(new Date()).writeObject("Today"). Thus. traverses its references to other objects recursively. You need to know about object serialization from two points of view. the following gets the current time in milliseconds by constructing a Date object and then serializes that object: FileOutputStream out = new FileOutputStream("theTime"). or writeUTF. How to Read from an ObjectInputStream 288 . The writeObject method throws a NotSerializableException if it's given an object that is not serializable. Serializing Objects Reconstructing an object from a stream requires that the object first be written to a stream. This code constructs an ObjectOutputStream on a FileOutputStream. thereby serializing the object to a file named theTime. such as writeInt. ObjectOutputStream s = new ObjectOutputStream(out).flush(). relationships between objects are maintained. In this way. the writeObject method serializes the specified object. you need to know how to serialize objects by writing them to an ObjectOutputStream and reading them in again using an ObjectInputStream.The key to writing an object is to represent its state in a serialized form sufficient to reconstruct the object as it is read. How to Write to an ObjectOutputStream Writing objects to a stream is a straightforward process. writeFloat. Object serialization is essential to building all but the most transient applications. s. You can use object serialization in the following ways: • • Remote Method Invocation (RMI)--communication between objects via sockets Lightweight persistence--the archival of an object for use in a later invocation of the same program. An object is serializable only if its class implements the Serializable interface. and writes them all.

the objects were archived in a file. Next. Like ObjectOutputStream. 289 . readFloat. String today = (String)s. Providing Object Serialization for Your Classes An object is serializable only if its class implements the Serializable interface. if you want to serialize the instances of one of your classes. Making instances of your classes serializable is easy. and readUTF. In this way. The readObject method deserializes the next object in the stream and traverses its references to other objects recursively to deserialize all objects that are reachable from it. Date date = (Date)s. Here's code that reads in the String and the Date objects that were written to the file named theTime in the previous example: FileInputStream in = new FileInputStream("theTime"). public interface Serializable { // there's nothing in here! }.readObject(). They include methods such as readInt. so the code constructs an ObjectInputStream on a FileInputStream. This is also straightforward.. Implementing the Serializable Interface Here's the complete definition of the Serializable interface: package java. the code uses ObjectInputStream's readObject method to read the String and the Date objects from the file. Note that the return value from readObject is an object that is cast to and assigned to a specific type. Thus.. The good news is that Serializable is an empty interface. ObjectInputStream must be constructed on another stream. Use these methods to read primitive data types from an ObjectInputStream. You just add the implements Serializable clause to your class declaration like this: public class MySerializableClass implements Serializable { .readObject(). it doesn't contain any method declarations. ObjectInputStream stream implements the DataInput interface that defines methods for reading primitive data types. The methods in DataInput parallel those defined in DataOutput for writing primitive data types. The objects must be read from the stream in the same order in which they were written. In this example. ObjectInputStream s = new ObjectInputStream(in).io.Once you've written objects and primitive data types to a stream. its purpose is simply to identify classes whose objects are serializable. you'll likely want to read them out again and reconstruct the objects. the class must implement the Serializable interface. it maintains the relationships between the objects. That is.

Several techniques are available to protect sensitive data in classes. 290 . Some classes may find it beneficial to allow writing and reading but to specifically handle and revalidate the state as it is deserialized. The class should implement writeObject and readObject methods to save and restore only the appropriate state. you must take care to protect sensitive information and functions.*.} You don't have to write any methods. Particularly sensitive classes should not be serialized. a file descriptor contains a handle that provides access to an operating system resource. double d. Therefore the serializing runtime must take the conservative approach and not trust the stream to contain only valid representations of objects. Since writing and reading (of private fields) cannot be superseded outside of the class. class MyClass implements Serializable { String s. the private state of the object is restored. The easiest is to mark fields that contain sensitive data as private transient. the class's transient fields are safe. Being able to forge a file descriptor would allow some forms of illegal access. If access should be denied. This method automatically writes out everything required to reconstruct an instance of the class. To avoid compromising a class. including the following:    Class of the object Class signature Values of all non-transient and non-static members. including members that refer to other objects You can deserialize any instance of the class with the defaultReadObject method in ObjectInputStream. For example. throwing a NotSerializableException will prevent further access. transient and static fields are not serialized or deserialized. To accomplish this. since restoring state is done from a stream. the object should not implement either the Serializable interface. you must provide either that the sensitive state of an object must not be restored from the stream or that it must be reverified by the class. During deserialization. int i. Marking the field will prevent the state from appearing in the stream and from being restored during deserialization. An example of Serialization : import java. Protecting Sensitive Information When developing a class that provides controlled access to resources.io. The serialization of instances of this class are handled by the defaultWriteObject method of ObjectOutputStream.

public MyClass(String s, int i, double d) { this.s = s; this.i = i; this.d = d; } public String toString() { return “s =” + s + “ , i =” + i + “, d =” + d; } } public class SerializationDemo { try { FileOutputStream fout = new FileOutputStream(“serial”); ObjectOutputStream os = new ObjectOutputStream(fout); os.writeObject(“Hello”); os.writeObject(new java.util.Date()); os.writeObject(new MyClass()); os.flush(); os.close(); } catch(Exception e) { System.out.println(e); } //object deserialization try { FileInputStream fin = new FileInputStream(“serial”); ObjectInputStream is = new ObjectInputStream(fin); String z = (String) is.readObject(); java.util.Date date = (java.util.Date) is.readObject(); MyClass obj = (MyClass) is.readObject(); is.close(); System.out.println(s); System.out.println(date); System.out.println(obj); } catch(Exception e) { System.out.println(e); } }

The System class provides three built in streams in java – in, out and err. All the api classes for performing input/output in java are a part of java.io package. There are two category of I/O classes – Byte stream and Character stream classes. There are separate classes that can be used for reading and writing into files. The File class can be used to get the properties of the file.


Chapter 12 : API classes in java.lang package
By default, each Java application/applet has access to the java.lang package. Inside java.lang are classes that represent primitive data types (such as int & char), as well as more complex classes. It contains classes pertaining to strings, string buffers, threads, and even the System class from which we obtain input and output streams.

12.1 Wrapper classes
Wrappers are used to enclose a simple datatype or a primitive object into an object. This is sometimes necessary because:
• • • • •

Simple datatypes are not part of the object hierarchy. Simple datatypes are passed by value and not by reference. Two methods can't refer to the same instance of a simple type. Some classes can only use members of another class and not a simple type. You can store a value of primitive type in a type-wrapper object whenever an object is required.

There are eight wrapper classes – one for each primitive data type. Primitive boolean byte char double float int long short Wrapper java.lang.Boolean java.lang.Byte java.lang.Character java.lang.Double java.lang.Float java.lang.Integer java.lang.Long java.lang.Short

All numeric wrapper classes are subclasses of the abstract class Number. The following figure shows the class hierarchy for the Number classes provided by the Java platform


BigInteger and BigDecimal extend the primitive data types to allow for arbitrary-precision numbers (numbers that might not fit into any of the primitive data types). Note that whereas the other classes are in the java.lang package, BigDecimal and BigInteger are in the java.math package. The Number class provides these methods
byte short int long float double byteValue(); shortValue(); intValue(); longValue(); floatValue(); doubleValue();

The classes define useful variables, such as MIN_VALUE and MAX_VALUE, that provide minimum and maximum value in the range of the data type. All wrapper objects are immutable. Once an object is created, the wrapped primitive value cannot be changed. Wrapper classes are final and hence cannot be sub classed. The Boolean class wrapper allows passing Boolean values (true and false) by reference. It contains the constants TRUE and FALSE, which define true and false Boolean objects. All the wrapper classes except Character have two constructors -- one that takes the primitive value and another that takes the String representation of the value. For instance:
Integer i1 = new Integer(50); Integer i2 = new Integer("50"); double d = 5.0; Double aD = new Double(d);

All wrapper classes have parseType methods eg parseInt(), parseShort, etc that take a String and parse it into the appropriate type. The six parser methods are parseInt, parseDouble, parseFloat, parseLong, parseByte, and parseShort. They take a String as the argument and convert it to the corresponding primitive. They throw a NumberFormatException if the String is not properly formed. For example,
double d = Double.parseDouble("4.23");

It can also take a radix(base) as the second argument: int i = Integer.parseInt("10011110",2); All wrapper classes (except Character) define a static method called valueOf(), which returns the wrapper object corresponding to the primitive value represented by the String argument. For example,


Integer I = Integer.valueOf("10011110",2);
Float f1 = Float.valueOf("1.5f");

Integer, Short, Byte and Long The Integer and Long classes also have the static methods toBinaryString(), toOctalString() and toHexString() which take an integer value and convert it to the appropriate String representation. The toHexString returns a string which is a hex string version of the number. It has a natural partner in the toBinaryString method which returns a string that represents the number in its binary version. The following example code will output the strings 100 followed by 10.
public class NumberFormats{ public static void main(String argv[]){ System.out.println(Integer.toBinaryString(4)); System.out.println(Integer.toHexString(16)); } }

Integer, and the longer form, Long, represent whole number values. Integers and Longs can be interchanged through the longValue() and intValue() methods, and can also be converted to floats and doubles using the floatValue() and doubleValue().
Integer my_integer = new Integer(256); Long my_long = my_integer.longValue();

One more example of converting a wrapper object value to primitive data type
Integer i = new Integer(20); byte b = i.byteValue();

Float and Double The constructors for Float and Double are shown below:
Float (double num) Float (float num) Float (String s) throws NumberFormatException Double (double num) Double (String s) throws NumberFormatException

Apart from the constants MIN_VALUE and MAX_VALUE these classes also have other constants like POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN and the following methods to test a value
public public public public boolean isNaN() static boolean isNaN(type value) boolean isInfinite() static boolean isInfinite(type value)


An example to show the use of isInfinite() and isNaN()
class InfNaN { public static void main(String args[]) { Double d1 = new Double(1/0.); Double d2 = new Double(0/0.); System.out.println(d1 + “ : ”+ d1.isInfinite() + “,” + d1.isNaN()); System.out.println(d2 + “ : ”+ d2.isInfinite() + “,” + d2.isNaN()); } }

This program generates the following output:
Infinity : true, false NaN : false, true

Both classes have methods to convert a value into a bit pattern or vice versa
public static int floatToIntBits(float value) public static float intBitsToFloat(int bits) public static long doubleToLongBits(double value)
public static double longBitsToDouble(long bits)

Floating point values, and the longer form, double, represent decimal (fractional) values. Floats and doubles can be interchanged through the doubleValue() and floatValue() methods, and can also be converted to integers and longs using the longValue() and intValue() methods. Its important to remember, however, that there will be a loss of precision, as integers and longs cannot retain the fractional component.
Float my_float = new Float(3.14); Double my_double = new Double (my_float.doubleValue()); // Print out double (3.14) System.out.println( "Double : " + my_double); // Print out integer (3) System.out.println( "Integer: " + my_double.intValue() );

Here's an example, called NumberDemo, that creates two Float objects and one Double object and then uses compareTo and equals to compare them:.
public class NumberDemo { public static void main(String args[]) { Float floatOne = new Float(14.78f - 13.78f); Float floatTwo = Float.valueOf("1.0"); Double doubleOne = new Double(1.0); int difference = floatOne.compareTo(floatTwo);


if (difference == 0) { System.out.println("floatOne is equal to floatTwo."); } else if (difference < 0) { System.out.println("floatOne is less than floatTwo."); } else if (difference > 0) { System.out.println("floatOne is greater than floatTwo."); } System.out.println("floatOne is " + ((floatOne.equals(doubleOne)) ? "equal" : "not equal") + " to doubleOne."); } }

The output from this program might surprise you a little:
floatOne is equal to oneAgain. floatOne is not equal to doubleOne.

Even though the values contained in floatOne and doubleOne are both numerically equal to 1, they are considered unequal because the objects are of different types. The numeric type-wrapper classes ( Byte, Integer, Double, Float, Long, and Short) each provide a class method named valueOf that converts a string to an object of that type. Character The Character class constructor takes a char type element as an argument:
Character c = new Character('A');

To obtain the char value contained in a Character object, call charValue() shown here,
char charValue()

The Character class contains a large set of character comparison routines, in the form of static methods.
static static static static static boolean boolean boolean boolean boolean isDigit( char c ); isLetter( char c ); isLetterOrDigit( char c ); isLowerCase( char c ); isUpperCase( char c );

static char toUpperCase( char c ); static char toLowerCase( char c );

A program is given below:


class IsDemo { public static void main(String args[]) { char a [] = {‘a’, ‘b’, ‘5’, ‘7’, ‘A’, ‘ for ( int i = 0; i < a.length ; i++) { if(Character.isDigit(a[i])) System.out.println(a[i]+ “is if(Character.isLetter(a[i])) System.out.println(a[i]+ “is if(Character.isWhitespace(a[i])) System.out.println(a[i]+ “is if(Character.isUpperCase(a[i])) System.out.println(a[i]+ “is if(Character.isLowerCase(a[i])) System.out.println(a[i]+ “is } } }

’}; a digit”); a letter”); whitespace”); uppercase”); lowercase”);

Character contains two methods for returning the numeric value of a character in the various number systems.
public static int digit(char ch, int radix) public static int getNumber(char ch)

and one method to return the character value of a number
public static char forDigit(int digit, int radix)

12.2 Autoboxing/Unboxing of Wrappers
In the previous section on wrapper classes for primitive type values, we discussed how to create an instance of a wrapper from a primitive value and conversely, how to obtain the primitive value held by the wrapper. This involves a a certain amount of clumsy code. For example, creating a Float object from a float primitive is straightforward:
float primitive_float = 3.0f; Float wrapper_float = new Float (primitive_float);

Going the other direction, however, requires explicitly calling the floatValue() method on the Float object:
float primitive_float = wrapper_float.floatValue();

If you are dealing with a lot of instances of wrappers and conversions, you will thus need to deal with a lot of method invocations. In J2SE 5.0, however, the code to create the wrapper object allows for this much simpler form:
Float wrapper_float = primitive_float;


Here, the "wrapping" is done automatically! There is no need to explicitly call the Float constructor. This "wrapping" is called "autoboxing" in the sense that the primitive value is automatically "boxed up" into the wrapper object. Autoboxing is available for all the primitive/wrapper types. Going the other way, from object type to primitive, is just as simple:
Integer wrapper_integer = 5; // primitive 5 autoboxed into an Integer int primitive_int = wrapper_integer; // automatic unboxing Integer into int

These shortcuts simplify coding and reduce errors in J2SE 5.0. For example, they can even be used in loop control and incrementing and decrementing operations.
int MAX = 100; // a primitive int type Integer counter = 1; // an Integer type Integer sum = 0; // ditto while (true) { sum += counter; if (counter == MAX) break; counter++; } System.out.println ("counter is now " + counter); System.out.println ("sum is now " + sum);

There is a lot of hidden autoboxing and unboxing going on in this simple-looking code. First, the Integer types counter and sum are autoboxed from the primitive values 1 and 0. Then, in the loop, they are unboxed to primitive values so the += operation can be applied and then reboxed to their "native" Integer types. To do the == comparison counter is unboxed so it can be compared with the int type MAX. If the break does not apply, then counter is unboxed, operated on with ++, and then reboxed. Autoboxing and unboxing work in a for loop as well:
Integer sum = 0; for (Integer counter=1; counter < MAX; counter++) { sum += counter; }

Note that both of these loops are likely to perform very slowly with all these autoboxing and unboxing operations. An optimizing compiler might be able to avoid some of the autoboxing and unboxing operations, but in general you should do long looping operations with primitive types unless there is a very good reason to use a wrapper type. Autoboxing and unboxing also work with Boolean and boolean types. For example,


atan(x).lang. The Math class cannot be instantiated as it has a private constructor. pow(x. toDegrees(x). There is nothing new there. ceil(x). tan(x) exp(x). Integer. asin(x). switch now also accepts Byte. then the first method1() is used. and Character types. log(x). Similarly. With the addition of autoboxing in 5. The reason is that existing code cannot suddenly start behaving differently when compiled and run under 5. it is conceivable that the int could be boxed into an Integer type and the second method1() used.y). rint(x). the if. The general rule is.y).0 versions must continue to hold. toRadians(x) Methods of java.4 and below. sin(x). cos(x).4 and below.y). the int is promoted to a long and the first method1() is used. while.it might make more sense to convert an int to an Integer than to promote it to a long. then the second method1() is used.boolean one = true.Math class abs 299 . floor(x). round(x) IEEEremainder(x.y). max(x. sqrt(x) abs(x). // autoboxing of primitive 'true' to Boolean type if (one && two) // auto unboxing do_something (). and do-while statements all expected boolean expressions. the old switch statement expects a byte. that is not what happens. random(). } long method1 (Integer i) { return i+2.y). Group Transcendental Exponential Rounding Miscellaneous Methods acos(x). Before 5. 12. While arguably reasonable. for compatibility reasons. the same behavior that applied in pre-5.0. Short.0. With autoboxing.0. If you call method1() with an Integer object parameter. min(x. short. All methods are of Math class are static. That might even be what you want to happen . // nothing new here Boolean two = true.3 Math class The Math class provides the important mathematical constants E and PI which are of type double. } If you call method1() with a primitive long parameter. int. atan2(x. The Math class also provides many useful math functions as methods. Through the use of unboxing. It cannot be subclassed as it is a final class. But what happens if you call method1() with an int parameter? In J2SE 1. Consider the two overloaded methods shown here long method1 (long l) { return l+1. Autoboxing and Overloading Autoboxing and unboxing can make method overloading interesting. or char type in Java 1. those flow control statements now also accept expressions that evaluate to Boolean types.

If the argument is NaN or infinity.floor(-.0.NaN): 1234.0): Math.floor(0.println(Math.59): Math.out.println(Math.println(Math.1)).println(Math.out. it returns the value as a negative Math.0 -0.abs(1234.println(Math.1) it will return a value of 2.0 NaN // counts up (towards zero) floor This method returns the largest (closest to positive infinity) double value that is not greater than the argument and is equal to a mathematical integer. Thus the following will simply print out 99. System.out.abs(Integer.out.out.abs(-0.floor(99)).03): Math. If the number is not negative you just get back the same number.ceil( 9. Here is a short program and its output public class MyMat{ public static void main(String[] argv){ System. Math.1) the result will be -1.abs(Float.01): Math.NEGATIVE_INFINITY): Math.ceil(10): Math.abs(-99)).NaN): 10. Thus if you pass ceil(1.ceil(Double.0 Infinity NaN If the value is equal to Integer.MIN_VALUE): -2147483648 ceil This method returns the next whole number up that is an integer. in which case.println(Math. System.It strips off the sign of a number and returns it simply as a number. returns the argument Math.1)). If you change that to ceil(-1.floor(-99)).floor(-99.01)). System. 300 .01): // counts up (away from Math.abs(Float. System. System.0.out.MIN_VALUE.0 10.0 zero) -9.ceil(-0.ceil(-9.59 0.

println(Math.5.1)).max(1.5.5 Math.0.max(-1.POSITIVE_INFINITY) : NaN The following code illustrates how these methods work public class MaxMin{ public static void main(String argv[]){ System. max() returns the largest of two values. System.5 Math. infinity.2)).min(-1.min(0.println(Math. 1.min(1. System.println(Math. System. System.out.-10)).out.} } And the output is -100.0 // zeros are not equivalent Math.println(Math. returns the argument.out.2)).println(Math.0 -1.Float. -0.0 If the argument is an integer. max and min min() returns the smallest of two values.0 -99.-10)).min(1.min(Float.NaN. returns the argument.out. Math.min(-1.0 99.5): 1. If the argument is NaN.0): -0.5): -1.out.max(-1.0 0. } } Here is the output -1 2 1 -10 1 round public static long round(double a) public static int round(float a) 301 . 1. negative or positive zero.

round(20)). if the argument is a negative infinity or less than the MIN_VALUE for the type. returns the MIN_VALUE. So.out. So for example if the input to round is x then : 2. If the argument is a positive infinity or greater than the MAX_VALUE for the type. if the value is more than half way towards the higher integer.49): 6.1)). Output: 1 -2 20 rint It rounds to the closest integer.round(Float.0.round(Float.MAX_VALUE): 2147483647 (Float.round(Float.0 -6. If the number is less than this the next lowest integer is returned.println(Math.01)). the value is rounded up to the next integer.out.rint(-5. returns zero.println(Math. favours the even integer.MAX_VALUE is 3.5): -1 Math.round(-1. 302 .rint( 5.println(Math.5): 2 Math.out.5): Math.round(1.0 <= x < 2. System.round(Double.NEGATIVE_INFINITY): -2147483648 Math.MAX_VALUE the round method returns Integer.0 the Math. System.MAX_VALUE Math.round( 1. If integers are equidistant.0 and 1.0 -5. If the value is Float.0 2. returns the MAX_VALUE.5.4028235E38) Here are some samples with output System.0 If the argument is not a number.rint( 5.5): Math.NaN): 0 Math.rint(-5.round(-2.0 5.0 random Returns a random number between 0.round(x)==3. Math.5 <= x < 3.POSITIVE_INFINITY): 9223372036854775807 Math.49): Math.round(x)==2.Rounds to the nearest integer. then Math.

sqrt(-45): 6.302585092994046 NaN -Infinity exp 303 .5): -0.2) 4.round(Math. Math.IEEEremainder keeps resulting values y units apart Math. returns negative infinity.0 log log() returns the natural logarithm of the argument. If the argument is positive infinity.5 0.log(0.0 -2.random()*100)).5 : -7 % 2.log(-10): Math. sqrt This method returns the positive square root of a number.5): Math.0 Math. Often a program will want to produce a random number between say 0 and 10 or 0 and 100.sqrt(45): Math.708203932499369 NaN IEEEremainder This method calculates the remainder as defined by IEEE-754. The remainder operator. If the argument is -0. 2.0): 2. The following code combines math code to produce a random number between 0 and 100.log(10): Math.IEEEremainder(-7. makes values symmetric around zero ie negative and positive values return corresponding remainders 7 % 2. Math.0 or 0. %.0.5 pow This method returns the first argument raised to the power of the second argument. It returns NaN if argument is negative Math. System.println(Math. returns NaN.IEEEremainder( 7. 2.5 : 2.Unlike some random number system Java does not appear to offer the ability to pass a seed number to increase the randomness. If the argument is less than zero.pow(2. returns positive infinity.out.

println("pow(" + x + ".exp(Float.println("sqrt(" + x + ") is " + Math.008 sqrt(11.45402 pow(11. System.out. 2. returns positive infinity. If the argument is NaN.exp(Float. System. " + y + ") is " + Math.exp() returns e to the power of the argument. If the argument is negative infinity. returns positive zero.println("log(" + x + ") is " + Math. 304 .41101 The trigonometric methods All results are returned in radians.POSITIVE_INFINITY): Math.log(x)).out.4131591025766 NaN Infinity 0. Math.635) is 3.pow(x.exp(x)). y)).76) is 874.71828 exp(11.635) is 2.out.println("exp(" + x + ") is " + Math.0 An example program using Math class: public class ExponentialDemo { public static void main(String[] args) { double x = 11.E). If the argument is positive infinity. System.out.635) is 112984 log(11. System.sqrt(x)). } } Here's the output you'll see when you run ExponentialDemo: The value of e is 2.NaN): Math. double y = 2.NEGATIVE_INFINITY): 148. returns NaN.76.println("The value of e is " + Math.exp(5): Math. System.out.635.exp(Float.635.

Math. if the result is negative zero. a) to polar (r.cos(90) -0. returns NaN.Method Description Returns the sine of the specified double value.0 double acos(double) Returns the arc cosine of the specified double value. Math. If the result is NaN. returns NaN. returns NaN.toDegrees(Math. If the result is negative zero.sin(90) 0.0 Math.toRadians(90) 1. returns -0.4480736161291701 double tan(double) Returns the tangent of the specified double value.995200412208242 double asin(double) Returns the arc sine of the specified double value. 305 . Math.0.5707963267948966 double atan(double) Returns the arc tangent of the specified double value. If the result is negative zero. returns NaN. returns -0. If the result is NaN or absolute value is greater than 1. If the result is NaN or infinity.atan(90) 1. It returns a value between -PI/2 and PI/2.8939966636005579 double sin(double) double cos(double) Returns the cosine of the specified double value.0. If the result is NaN or infinity. returns NaN.asin(-0) 0.0 and PI. returns -0. returns -0.5707963267948966 Math. It returns a value between -PI/2 and PI/2. returns NaN. If the result is NaN or infinity.0 Math.tan(90) -1. Math. If the result is NaN or absolute value is greater than 1.acos(-0) 1. If the result is negative zero.PI/2) 90. It returns a value between 0.0 Math. theta). Converts the argument to degrees or radians as indicated by the method name.0 An example of using trigonometric functions public class TrigonometricDemo { public static void main(String[] args) { double degrees = 45.5596856728972892 double atan2(double) double toDegrees(double) double toRadians(double) Converts rectangular coordinates (b.

tan(radians))) + " degrees").out.sin(radians)).out.println("The arc sine of " + Math.0 is -1.141592653589793 sine of 45.0 is NaN arc tangent of 45. destpos. As an example System.toDegrees(Math.println("The arc cosine of " + Math.toDegrees(Math. 306 . the system properties are initialized to contain information about the runtime environment.4 System class The System class provides access to the native operating system's environment through the use of static methods.0 is 0. When the runtime system first starts up.out.acos(Math.PI).8060754911159176 cosine of 45.tan(radians)). in milliseconds counted from January 1. srcpos.println("The sine of " + degrees + " is " + Math.0 is 1.currentTimeMillis() retrieves the system clock setting (as a long.toRadians(degrees). System.out. key/value pairs. } } The output of this program is as follows: The The The The The The The value of pi is 3. System.asin(Math.570408475869457 12.3620448762608377 arc sine of 45.sin(radians))) + “degrees"). System.out.0 is NaN arc cosine of 45.0 is -0. the current version of the Java runtime.double radians = Math.println("The tangent of " + degrees + " is " + Math.atan(Math. System.asin(radians) + " is " + Math.cos(radians)). and even the character used to separate components of a filename. System. len) The System class maintains a set of properties.println("The value of pi is " + Math.out.cos(radians)+ " is " + Math. System. including information about the current user.toDegrees(Math.tan(radians) + " is " + Math. 1970). that define traits or attributes of the current working environment. Some of the available methods are: currentTime() freeMemory() totalMemory() exit(int status) exec(String cmd) getOSName() arraycopy(src[]. System.out.println("The arc tangent of” +Math.5918127259718502 tangent of 45.println("The cosine of " + degrees + " is " + Math.cos(radians))) + “degrees"). dest[].

separator" "os. An example to get the user name : class UserNameTest { public static void main(String[] args) { String name.separator" "user.println(name). name = System.out.class.version" "path.path" "java.getProperty(“file.separator”).dir" "user. "/") Java classpath Java class version number Java installation directory Java vendor-specific string Java vendor URL Java version number Line separator Operating system architecture Operating system name Operating system version Path separator (for example. ":") User's current working directory User home directory User account name Your Java programs can read or write system properties through several methods in the System class.version" "line.arch" "os.separator" "java.name" Meaning File separator (for example.version" "java. For example.class. you can use the method System.name"). to get the file separator character of the OS. } } 307 .Here is a complete list of the system properties you get when the runtime system first starts up and what they mean: Key "file.home" "java.name" "os.vendor.url" "java.home" "user.getProperty("user. System. or you can get the whole set of properties all at once.vendor" "java. You can use a key to look up one property in the properties list. You can also change the set of system properties completely.

308 . // Get elapsed time in seconds float elapsedTimeSec = elapsedTimeMillis/1000F.The System class also provides very basic io streams for console read.currentTimeMillis(). 12. // Get elapsed time in minutes float elapsedTimeMin = elapsedTimeMillis/(60*1000F). // Do something . You cannot instantiate a Runtime object. // Get elapsed time in days float elapsedTimeDay = elapsedTimeMillis/(24*60*60*1000F).in.. // Get elapsed time in hours float elapsedTimeHour = elapsedTimeMillis/(60*60*1000F). You can get the reference of the current Runtime object by calling the getRuntime() method. To compute elapsed time // Get current time long start = System.currentTimeMillis()-start.exit(errorCode).println(string) displays a string to the current output device. // Terminate System. System. Once you obtain the reference to the current runtime you can call several methods that control the state and behavior of JVM.5 Runtime class The Runtime class encapsulates the runtime environment. // Get elapsed time in milliseconds long elapsedTimeMillis = System. System.out.read() reads a keystroke and returns an integer value.. write and error operations. // An error occurred errorCode = -1. Use of some methods of System class To terminate an application // No errors int errorCode = 0.

exec(“notepad”).exec(“notepad”).freeMemory().getRuntime().out. long heapMaxSize = Runtime. } System. } catch(Exception e) { System. To execute an application.out. //The heap cannot grow beyond this size. class ExecDemoFini { public static void main(String args[]) { Runtime r = Runtime. // Get maximum size of heap in bytes. Process p = null.totalMemory().getRuntime(). // Get current size of heap in bytes long heapSize = Runtime.println(“Notepad returned :” +p.out.exitValue()).getRuntime().println(e).waitFor(). } } } The abstract class Process encapsulates a process. } catch(Exception e) { System. The exitValue() returns the value returned by the subprocess when it is finished. 309 . try { p = r. long heapFreeSize = Runtime.println(e).that is a program in execution. This is typically 0 if no problems occur. The heap is the area in memory in which objects are created. try { p = r. The waitFor() method causes your program to wait until the subprocess finishes. //This size will increase // after garbage collection and decrease as new objects //are created.getRuntime().Runtime can be used to get the size of the heap.maxMemory(). you can use the exec method of the Runtime object class ExecDemo { public static void main(String args[]) { Runtime r = Runtime. Process p = null.getRuntime(). // Get amount of free memory within the heap in bytes. p. // Any attempt will result in an OutOfMemoryException. You can kill the subprocess created by the exec() method by destroy() method.

Objects of type Class are created automatically.println(“y is the object of type:” +clObj. //get class reference System. float b.getName()).println(“y’s superclass is :”+ clObj. } } The output of the program is as follows: x is object of type : X y is obtect of type : Y y’s superclass is X Summary You use an instance of one of the Number classes—Byte. } class Y extends X { double c.getName()).println(“x is the object of type:”+ clObj. Double. when classes are loaded. An example of using Class is as follows: class X { int a.getClass(). clObj = y. System.out.getName()). } class RTTI { public static void main(String args[]) { X x = new X(). 310 .out. Long. Generally. Y y = new Y().} } 12. You cannot explicitly declare a Class object.out. System.getSuperclass().getClass().6 Class class Class encapsulates the run-time state of an object or interface. clObj = clObj. Float. you obtain a Class object by calling the getClass() method defined by Object. The methods defined by Class are often useful in situations where runtime type information about an object is required. Integer. Class clObj = x. and Short—to contain a number of primitive type.

Prints: 0."). None of the above public static void main (String args[]) { System. This class includes the trigonometric functions. } } What is the result of attempting to compile and run the program? a.128 2. System.print(Byte. } 311 . Prints: 0.out. Prints: -127.out.print(Integer.65536 e. Questions 1. The valueOf method converts a string to a number.32768 b.MIN_VALUE+".MAX_VALUE)+". Finally. class JJF3 { d. shortValue.out.MAX_VALUE).toBinaryString(Byte. and so on.32767 c.out. Prints: 0. Prints: -32767."). random.256 c. Prints: 0. and similar methods convert one numeric type to another. and the toString method converts a number to a string.255 b.MAX_VALUE)+". Prints: -128. Math contains a method.65535 3.").MAX_VALUE)+".The Number classes include class methods and constants. The Math class contains a variety of class methods for performing mathematical functions. The MIN_VALUE and MAX_VALUE constants contain the smallest and largest values that can be contained by an object of that type.print(Short. None of the above public static void main(String args[]) { System. Prints: -32768.").print(Byte. such as rounding.out.out.print(Integer. class JJF2 { d. System. System. for generating random numbers.toOctalString(Byte.MAX_VALUE)).toHexString(Byte.toString(Byte. as well as basic arithmetic functions. Run-time error g. cosine.127 e.out.print(Integer. Compile-time error f.out. class JJF1 { public static void main (String args[]) { System. System.print(Short. such as computing sine.MAX_VALUE). Compile-time error f. } } What is the result of attempting to compile and run the program? a. which are useful in a variety of ways.MIN_VALUE+".").print(Integer. System. Math also includes functions for logarithm calculations. The byteValue. Run-time error g.

print(Long.").toHexString(Integer.MIN_VALUE)+".print(Integer.print(Integer.ffff b.7fff 5.out.ff c. }} What is the result of attempting to compile and run the program? a.ffff.127. 312 . Compile-time error h. Prints: 1111111.ffffff. Prints: 7fff. Prints: f.toHexString(Short.ff.MAX_VALUE)).ff c. // 2 i = (int [])c. c. None of the above public static void main(String args[]) { System. // 3 } } What is the result of attempting to compile and run the program? a.toHexString(Character.out.377.out.ffff.ffffffff c.ffffff.7f b.7fff e.print(Long. // 1 Cloneable c = i. } } What is the result of attempting to compile and run the program? a. class JJF5 { d. Prints: 8000.177. Compile-time error 4. Run-time error at line 2.7fffffff g. Prints: 7f. None of the above public static void main(String args[]) { System."). Prints: 00000000. b.toHexString(Integer.80000000 f. Prints: ff. System.out.toHexString(Byte.} What is the result of attempting to compile and run the program? a. class Green { d.MAX_VALUE)+".out. Prints: 7fff.ff. Compile-time error h.7f b.7fffff f.ffff e. class JJF4 { d. System. Prints: f. Prints: 80000000. Run-time error i. System."). d.8000 6. Prints: ffff. Prints: 11111111. None of the above public static void main (String args[]) { int[] i = null. Run-time error at line 1.256. Prints: 0000. Run-time error e. Run-time error i. Compile-time error at line 1. Compile-time error at line 2.MAX_VALUE)+".MAX_VALUE)). Prints: 7fffffff.ffffff g.print(Long.

System. None of the above 313 . Prints: true.true. c. None of the above } public static void main (String[] args) { float a = Float."+(c != c)). double b = Double."+(c == c)+".POSITIVE_INFINITY.true i.NaN.false Prints: true. double c = Double.false Prints: false.false Prints: false. class EBH011 { g.false. Compile-time error at line 3.true. f. } What is the result of attempting to compile and run the program? a. g.false Prints: true.false. h.true e.true. Run-time error at line 3. Run-time error j.false.POSITIVE_INFINITY. Prints: false.false.true.print((a == b)+". b.e. Compile-time error k. d.true Prints: true.out.true Prints: false. f. 7.

Methods are provided to enumerate through the elements of a vector. Stack.Chapter 13 : Utility & Legacy classes These classes are a part of java. but with two differences: Vector is synchronized and it contains many legacy methods that are not part of the collections framework. 13. 314 . Throws NoSuchElementException if no more element exists. Returns true if this enumeration contains more elements. Hashtable and Dictionary.2 Vector class The Vector class provides the capability to implement a growable array of objects. Vector extends AbstractList and implements the List interface of the Collections Framework. The fourth form creates a vector that contains the elements of Collection c. the keys of a hashtable.1 Enumeration interface An object that implements the Enumeration interface generates a series of elements. Methods of Enumeration interface public abstract boolean hasMoreElements() Tests if this enumeration contains more elements. 13.util package. The third form creates a vector whose initial capacity is specified by size and whose increment is specified by incr. false otherwise. Successive calls to the nextElement method return successive elements of the series. The increment specifies the number of elements to allocate each time that a vector is resized upward. Here are Vector constructors: Vector() Vector(int size) Vector(int size. There is one legacy interface called Enumeration. which has an initial size of 10. one at a time. public abstract Object nextElement() Returns the next element of this enumeration. int incr) Vector(Collection c) The first form creates a default vector. It is similar to the ArrayList in the Collection Framework. Enumerations are also used to specify the input streams to a SequenceInputStream. The second form creates a vector whose initial capacity is specified by size. There are five legacy classes in Java – Vector. Properties. and the values in a hashtable.

println(“Initial size :” + v.addElement(new Integer(12)). The number of elements currently in the vector is stored in elementCount. because allocations are costly in terms of time. v. System.45)). v. To obtain the element at a specific location call elementAt(). To obtain the first element in the vector call firstElement().util.out. It also demonstrates the Enumeration interface. System.out. You can add an element to the Vector by calling addElement(). increment is 2 Vector v = new Vector().*.All vectors start with an initial capacity. the vector automatically allocates space for that object plus extra room for additional objects. call removeElementAt(). This reduction is important.println(“Current capacity:”+v.addElement(new Integer(1)). System.out.println(“Capacity after 4 additions :” + v. System. By allocating more than just the required memory. The amount of extra space allocated during each reallocation is determined by the increment that you specify when you create the vector. To remove an element. It demonstrates several of the legacy methods defined by Vector.addElement(new Integer(2)). Vector defines these protected data members: int capacityIncrement.addElement(new Integer(11)).capapcity()).addElement(new Double(5. The following program uses a Vector to store various types of numeric objects.addElement(new Integer(7)).out. v.addElement(new Double(6.out. 315 .out. The array that holds the vector is stored in elementData. v. call lastElement(). If you don’t specify an increment. int elementCount. System.println(“Initial capacity :”+v.println(“Current capacity:”+v. To retrieve the last element. the vector’s size is doubled by each allocation cycle. v.addElement(new Integer(10)).08)). v. v.capacity()).out. System.addElement(new Integer(4)). You can obtain the index of an element using indexOf() and lastIndexOf().addElement(new Integer(3)).size()). Object elementData[].capapcity()).capapcity()).4)).addElement(new Double(9. After the initial capacity is reached the next time that you attempt to store an object in the vector. v. v. v. class VectorDemo { public static void main(String args[]) { //initial size is 3.capacity()).println(“First element:”+ (Integer)v.println(“Current capacity:”+v. the vector reduces the number of allocations that must take place. v. System. import java. The increment value is stored in capacityIncrement.firstElement()).

3 Stack class Java's Stack class extends the Vector class.out. System.out.nextElement() + “ } System. Some of the methods of Stack are shown below: boolean empty() Tests if this stack is empty.print(vEnum.out.elements().hasMoreElements()) { System.08 7 9.println(“\nElements in vector:”). The output of this program is shown here: Initial size: 0 Initial capacity : 0 Capacity after 4 additions: 5 Current Capacity: 5 Current Capacity: 7 Current Capacity: 9 First element: 1 Last element: 12 Vector contains: 3 Elements in vector: 1 2 3 4 5. } } ”).System. Object pop() Removes the object at the top of this stack and returns that object as the value of this function.println().out. Object push(Object item) Pushes an item onto the top of this stack. removal of it's top most element. Object peek() Looks at the object at the top of this stack without removing it from the stack.println(“Last element:”+ (Integer)v.lastElement()). } //enumerate the elements in the vector Enumeration vEnum = v. The Stack class provides operations that allow testing for zero elements. while(vEnum.contains(new Integer(3)) { System. and the addition of elements. inspection of it's top most element.45 6.out. if(v.println(“Vector contains 3”). A Stack represents a Collection of objects that are in LIFO (Last In First Out Order).4 10 11 12 13. 316 .

66).out. } } } The following the output produced by the program stack : [ ] push (42) stack : [42] push (66) stack : [42.pop(). showpush(st.println(a). try { showpop(st). } catch(EmptyStackException e) { System.out. System.int search(Object o) Returns the 1-based position where an object is on this stack.out.out.out. 42). Integer a = (Integer) st.println(“stack :” + st). 66] push (99) stack : [42. int a) { st. 99] pop -> 99 stack : [42. 66.println(“stack :” +st). showpush(st. class StackDemo { static void showpush(Stack st. System. } public static void main(String args[]) { Stack st = new Stack(). } static void showpop(Stack st) { System.push(new Integer(a)).out. 66] pop -> 66 stack : [42] 317 .println(“pop -> ”).println(“push (”+a+ “)”). System.println(“Empty Stack”). System.println(“stack : ”+st).out.*. showpush(st. showpop(st). System. showpop(st). 99). An example of using Stack import java.util. showpop(st).

Cloneable and Serializable interfaces. when the number of elements is greater than the capacity of hashtable multiplied by its fill ratio. The second version creates a hash table that has an initial space specified by size. 318 . deleted and found. Specifically. You can use the remove() method to delete a key/value pair. 13. This ratio must be between 0. you can store the value in a Dictionary object. The Dictionary class defines some abstract methods. The keys and values can each be returned as an Enumeration by the keys() and elements() methods.0.they are certainly not the most memory efficient means of storing data. float fillRatio) Hashtable(Map m) The first version is the default constructor. If you do not specify a fill ratio. The default load factor of 0. the fourth version creates a hash table that is initialized with elements in m. Hash tables are a common means of organising data. Hashtable inherits directly from Dictionary and implements the Map. Once the value is stored. Hash tables represent a sacrifice of memory for the sake of speed . then 0. you can retrieve it by using its key. Use get() to retrieve the value of a given key. respectively. but they provide very fast lookup times.pop -> 42 stack : [ ] pop -> empty stack 13. The size() method returns the number of key/value pairs stored in a dictionary and isEmpty() returns true when the dictionary is empty. Hashtable is the class which provides hash tables in Java. Finally.0 and 1. the put() method is used. so the designers of the Java programming language have provided a number of classes for easily creating and manipulating instances of hash tables.4 Dictionary class The Dictionary class is an abstract class. which maps keys to values. in which data can be quickly inserted.75 is used. and it determines how full the hash table can be before it is resized upward. To add a key and a value. A hash table can only store objects that override the hashCode() and equals() methods that are defined by the Object.75 is used. The Hashtable constructors are shown below: Hashtable() Hashtable(int size) Hashtable(int size. The third version creates a hash table that has an initial size specified by size and a fill ratio specified by fillRatio. because it is superceded by Map in the Collections Framework. Given a key and value. Dictionary is classified as obsolete. Any object can be used as a key and/or value. The capacity of the hash table is set to twice the number of elements in m. the hash table is expanded.5 Hashtable class A hash table is conceptually a contiguous section of memory with a number of addressable elements.

new Double(-19.22)).000 into Jane Doe’s account bal = (Double)balance. new Double(1378.22)). For example.put(“Todd Hall”.get(str)).nextElement(). balance. it is the type of object returned by System. new Double(99. System.hasMoreElements()) { str = (String)names.*.out.00)). } System.out.println().34)).getProperties() when obtaining environmental values.put(“Jane Baker”. while(names. Properties defines the following instance variables: Properties default.put(“John Doe”. class HTDemo { public static void main(String args[]){ Hashtable balance = new Hashtable(). balance.put(“John Doe”.get(“John Doe”)). An example of using Hashtable import java.put(“Ralph Smith”.println(str + “ : ” + balance.6 Properties class Properties is a subclass of Hashtable. //Deposit 1. System.get(“John Doe”) balance. It is used to maintain lists of values in which the key is a String and the value is also a String.keys(). new Double(123.If you want to allocate more space for your hash table before the load factor reaches the specified value then use the rehash() method like this: ht. String str.rehash(). } } 13. balance.util.out.08)). 319 .new Double(bal + 1000)).println(“John Doe’s new balance :” + balance. balance.put(“Tom Smith”. new Double(3434. //Show all balances in hash table Enumeration names = balance. The Properties class is used by many other Java classes. balance. double bal.

setProperty("maxLevel". with a header line from the String parameter. if you call getProperty(“foo”) on a given Properties object. props. "Macro Processor Properties"). String) method. then “default value” is returned. String value) String getProperty(String key) String getProperty(String key. props. "7"). String header) To create and put values in a Properties table This example creates a new Properties table and assigns a string value to four different keys.html"). The second creates an object that uses propDefault for its default values. and “foo”.setProperty("fileName". "*.stat")). a default value can be specified along with the key in the getProperty() method – such as getProperty(“name”. Java looks for “foo” in the default Properties object. Properties props = new Properties(). “default value”). It will write the properties to the output stream. props. This allows for arbitrary nesting of levels of default properties. To store a Properties table in a file Use the Properties store(OutputStream.$$$"). Properties defines these constructors Properties () Properties (Properties propDefault) The first version creates a Properties object that has no default values. does not exist. "C:\temp\work. String defaultValue) Enumeration propertyNames() void load(InputStream in) void store(OutputStream out.setProperty("noCopyPattern". One useful capability of Properties class is that you can specify a default property that will be returned if no value is associated with a certain key. you can pass another instance of Properties to be used as the default properties for the new instance. props. "true").This variable holds a default property list associated with a Properties object. When you construct a Properties object. props. Methods Object setProperty(String key. 320 .store(propOut. For example.setProperty("recursiveSearch". In both cases the property list is empty. If the “name” value is not found. Assuming you have variables and an OutputStream like: OutputStream propOut = new FileOutputStream( new File("props. In this case.

The java. boolean recursiveSearch = Boolean.getBoolean(props. defaultProps.5 introduces a new class named java.Formatter that allows you to do string formatting similar to the printf function in C. "false"). Object.util.Formatter class provides several constructors..7 Formatter class Java 1. Destinations include OutputStream. props.parseInt(props.getProperty("maxLevel"). and any class that implements the new Appendable interface.Formatter class includes the method format (String format. an instance of File.setProperty("sourceFile". int maxLevel = Integer. Properties defaultProps = new Properties(). To use default properties Create a Properties table with all of the default key/value pairs. The java.util. The program FormatWriteApp shows how we can use Formatter to send formatted numerical values to the console rather than using the printf() method.util. It depends heavily on the varargs feature being introduced in 1.serProperty("enableScrolling".getProperty("noCopyPattern"). Use this default table in the constructor for your regular properties table: Properties props = new Properties(defaultProps). args) The args parameters will be displayed in the output according to the specifiers in the format string in the first parameter. 13. ""). defaultProps..To load Properties from a file Use the Properties load(InputStream). 321 . You will probably want to get each property value and assign it to an internal variable and perhaps show it in the user interface.getProperty("recursiveSearch")). Here propsIn is the input stream. String noCopyPattern = props. method. For example.load(propsIn). each of which includes a parameter for the destination of the formatted output. For example.5.

format // Need to flush the data out of the buffer.import java.*. formatter.util. = 987654321.close (). %9d %n". a_boolean). Formatter formatter = new Formatter ((OutputStream)System. a_float). **/ public class FormatWriteApp { public static void main (String arg[]) { // Send formatted output to the System. formatter. = 983. %n").flush (). } // main } // class FormatWriteApp The output of this program look like: Text output with Formatter.format ("Text output with Formatter. formatter. = 1234567. = 114. formatter.util. = 1211. an_int). %9.format formatter.format formatter. boolean byte short int long float double a_boolean a_byte a_short an_int a_long a_float a_double = false.Formatter capabilities for * formatting primitive types.format ("Primitives converted to strings: %n"). %9d %n".io.297e-15.out stream. a_long). a_double).format formatter.6f.format formatter. import java. /** * Demonstrate the java. = -4. a_short).format formatter.*.format formatter. ("boolean ("byte ("short ("int ("long ("float ("double = = = = = = = %9b %n". Primitives converted to strings: boolean = false byte = 114 short = 1211 int = 1234567 long = 987654321 322 . a_byte). formatter.3f %n". %9d %n".2e %n".out). %9. %9d %n".

such as for a graphical text component. the System. if you simply want a formatted string. System. Let’s look at a simple example of creating a date using the system clock’s current date and time and returning a long value.600 = -4.30e-15 In the Formatter constructor. The Formatter uses internally a StringBuilder. For example. like this: Date midnight_jan2_1970 = new Date(24L*60L*60L*1000L). you can create a Formatter with the no-argument constructor. you might do this Date d1 = new Date(). The second constructor accepts one argument that equals the number of milliseconds that have elapsed since midnight. and don't want to send it to an output destination. Also. } } To create a Date object for a specific time. Date do not allow you to obtain the individual components of date or time. 323 . This is often referred to as the system time of the host environment of the Java Virtual Machine (JVM). January 1.util. public class DateExample1 { public static void main(String[] args) { // Get the system date/time Date date = new Date().println(date. 13. You can directly obtain the formatted string created by the Formatter by invoking the toString() method. 1970. and you can access the string that it creates via the toString() method. must be cast to OutputStream because otherwise there is an ambiguity over which constructor to use.out. import java.out argument. Date class has two constructors Date() Date(long milliseconds) The first constructor initializes the object with the current date and time. January 1. which references an instance of PrintStream. Greenwich Meantime to the constructor. You can return the number of milliseconds in the Date as a long. using the getTime() method.float double = 983.8 Date class The Date class encapsulates the current date and time. 1970. to time a block of code.getTime()).Date. pass the number of milliseconds since midnight.

January 1. (that is a Date object). which takes an identifier for the requested field as argument: int get( Calendar. the Calendar class defines a number of additional public static final variables holding the values for the fields. The Calendar class follows an unusual idiom for allowing access to the individual fields of the interpreted date instance. like this: Date midnight_jan2_1970 = new Date(). So. false if it's not. Greenwich Mean Time. false if it's not. midnight_jan2_1970.// timed code goes here Date d2 = new Date(). long elapsed_time = d2.getTime() . The before() method returns true if this Date is before the Date argument. For example if (midnight_jan2_1970. and seconds according to the local calendar.before(new Date())) { The after() method returns true if this Date is after the Date argument.) Besides the identifiers (or keys) for the fields..JANUARY ) {. January 1.. one would write code like this: if( calendar.setTime(24L*60L*60L*1000L).d1.get( Calendar. The Calendar class represents a point in time (a "Date"). Each Calendar instance wraps a long variable containing the number of milliseconds since the epoch for the represented point in time. (These identifiers are raw integers. 1970.} 324 . to test whether a certain date (represented by the Calendar instance calendar) falls into the first month of the year.getTime(). not wrapped into an enumeration abstraction. For example if (midnight_jan2_1970. 1970.MONTH ) == Calendar. GMT.MONTH ) The identifiers for the fields are defined in the Calendar class as public static final variables. System.9 Calendar class The abstract class Calendar converts a time in milliseconds since midnight.println("That took " + elapsed_time + milliseconds"). into days.after(new Date())) { 13. hours. to the setTime() method. You can change a Date by passing the new date as a number of milliseconds since midnight.out. minutes. Rather than offering a number of dedicated property getters and setters (such as getMonth()). it offers only one. interpreted appropriately for some locale and time zone.

SECOND)).SECOND. etc. representing the 13th month of the year. } } 13.get(Calendar. initializes the object with the current date and time in the default locale and timezone.get(Calendar.out. and so on). int dayOfMonth) GregorianCalendar (int year.MINUTE)+”/”+ c.out. System. which is required by some (nonGregorian) calendars. The default.get(Calendar.get(Calendar. It provides an implementation of the basic Calendar abstraction suitable for the interpretation of dates according to the conventions used commonly in the West.print(“Updated Time:”). System.print(“Time:”).HOUR)+”/”+ c. It adds a number of public constructors.print(“Date :”). int dayOfMonth.out. class CalendarDemo { public static void main(String args[ ]) { //Create a calendar initialized with the current date // and time in the default locale and timezone Calendar c = Calendar. int hours.set(Calendar.println(c.SECOND)). System. There are several constructors of GregorianCalendar class.set(Calendar.get(Calendar.out.DATE)+”/”+ (c.get(Calendar. irrespective of location (as opposed to more neutral names such as MONTH_1.YEAR)). int month.HOUR. int month..set(Calendar.println(c.out.Note that the months are called JANUARY.MINUTE. System. System. int dayOfMonth.get(Calendar.10). MONTH_2. boolean isLeapYear(int year) The getInstance() method of Calendar returns a GregorianCalendar object.println(c. 325 .00). c.util. //set the time and print it c.MONTH)+1)+”/”+ c.out. as well as some functions specific to Gregorian Calendars.HOUR)+”/”+ c. int minutes) GregorianCalendar (int year.00).get(Calendar.getInstance(). System.10 GregorianCalendar class The class GregorianCalendar is the only commonly available subclass of Calendar.MINUTE)+”/”+ c.*. FEBRUARY. int month. An example using Calendar class import java. such as isLeapYear(). There is also a field UNDECIMBER. Also there are some more like GregorianCalendar (int year. c.get(Calendar.

The TimeZone abstraction therefore needs to keep track not only of the additional offset to be applied if DST is in effect. required by Calendar to interpret dates according to the selected time zone.println(“Current year is Leap year”).print(“Date :”).out.isLeapYear(gc. int minutes.DATE)+”/”+ gc. System.YEAR)). System.get(Calendar. but implementation of any functionality 326 . Locale locale) Example import java.YEAR))) { System. The first version sets the time of midnight. this offset changes when daylight saving time (DST) is in effect.out. The abstract base class TimeZone provides basic methods to handle "raw" (without taking DST into account) and actual offsets (in milliseconds!). but also of the rules that determine when DST is in effect.HOUR)+”/”+ gc. in order to calculate the local time for any given date and time.get(Calendar. } else { System.out. The second version also sets the hours and the minutes.int hours. You can also construct a GregorianCalendar object by specifying either the locale and/or timezone.print(“Time:”).util. System. } } } 13. GregorianCalendar (Locale locale) GregorianCalendar (TimeZone timezone) GregorianCalendar (TimeZone timezone. The third version adds seconds.get(Calendar.11 TimeZone and SimpleTimeZone classes The TimeZone class and its subclasses are auxiliary classes.out.get(Calendar.println(gc.println(gc. Here year specifies the number of years that have elapsed since 1900. The month is specified by month. with zero indicating January.SECOND)). if(gc. month and year. The following constructors create objects initialized with the current date and time using the specified time zone and/or locale.println(“Current year is not a Leap year”). Clearly.out. class GregorianCalendarDemo { public static void main(String args[]){ GregorianCalendar gc = new GregorianCalendar().MONTH)+ ”/”+ gc. Semantically.out.*.MINUTE)+”/”+ gc.get(Calendar.get(Calendar.get(Calendar. int seconds) All three versions set the day. System. a time zone specifies a certain offset to be added to Greenwich Mean Time (GMT) also referred to as Coordinated Universal Time (UTC) to reach the local time.

.getAvailableIDs(). int hour12 = cal. // View every time zone for (int i=0.get(Calendar. such as SimpleTimeZone.get(Calendar.SECOND).11 int minutes = cal. TimeZone.23 // Get the current local hour-of-day cal. Time zones are unambiguously determined by an identifier string. // 0.SHORT). // Get the display name String shortName = tz. String longName = tz.inDaylightTime(today). // Get all time zone ids String[] zoneIds = TimeZone.get(Calendar.LONG). // 0.. i<zoneIds. 327 .get(Calendar.59 boolean am = cal.related to DST rules is left to subclasses. // 0. TimeZone. Also provided are static factory methods. int hour24 = cal.HOUR_OF_DAY)..getDisplayName(tz.setTimeZone(TimeZone.AM...getTimeZone(zoneIds[i]). to obtain TimeZone instances — either for a specific ID or the default for the current location.length.59 int seconds = cal.getDefault()). The base class provides the static method String[] getAvailableIDs() to obtain all installed "well-known" standard time zones. SimpleTimeZone also provides some public constructors and.HOUR_OF_DAY). // Get the current hour-of-day at GMT cal.getTimeZone("Hongkong")).AM_PM) == Calendar.MINUTE). hour24 = cal. such as a giving an explicit day in a month or a certain weekday following a given date. Display names come in two styles: LONG and SHORT. Each TimeZone also has a human-readable.setTimeZone(TimeZone. locale-dependent display name.getTimeZone("GMT")). surprisingly for an abstract class.getDisplayName(tz. // 0. i++) { // Get time zone by time zone id TimeZone tz = TimeZone.get(Calendar.inDaylightTime(today).23 An example to list all timezones Date today = new Date(). The latter class provides several ways to specify rules controlling the beginning and ending of DST. // 0. so does TimeZone.HOUR). An example of using TimeZone // Get the current time in Hong Kong Calendar cal = new GregorianCalendar(TimeZone.get(Calendar.

a French Canadian locale passed to a Calendar object asks that the Calendar behave correctly for the customs of Quebec. each locale-sensitive class maintains its own locale-specific information.inDaylightTime(today). Both use the standard localization mechanism."GB").getRawOffset(). } 13. While a global locale is not enforced. Java programs are not assigned a single global locale. Language names are two letter ISO-639 language codes and country names are two letter ISO-3166 country codes. there is no difference in how user and system objects maintain their locale-specific resources.12 Locale class In Java. // Does the time zone have a daylight savings time //period? boolean hasDST = tz. // Is the time zone currently in a daylight savings time? boolean inDST = tz. ""). It is up to the object accepting the locale to do the right thing. 328 . but was localized for the French language in general. it would use the French localization instead. Locale objects are generally created from a language name and a county name as follows: // A locale for Great Britain Locale greatBritain = new Locale("en". This naming scheme is not enforced by class Locale but is rather a convention used by all Java's International classes.abs(rawOffset / (60*1000)) % 60. an empty country string is given to the Locale constructor to signify a locale for the entire French language.useDaylightTime(). All locale-sensitive operations may be explicitly given a locale as an argument. Instead. For example. a locale is simply an identifier for a particular combination of language and region. A default locale also makes it possible to affect the behavior of the entire presentation with a single choice.// Get the number of hours from GMT int rawOffset = tz. Java locales act as requests for certain behavior from another object. In the second case above. it will try to find a "close" match with a locale for which it has been localized. It is not a collection of locale-specific attributes. Thus if a Calendar object was not localized for French Canada. int hour = rawOffset / (60*60*1000). a system wide default locale is available for programs that do not wish to manage locales explicitly. If the object has not been localized for a particular locale. // A locale for the French language Locale french = new Locale("fr". With this design. This greatly simplifies multilingual programs. int min = Math.

Locale supports a number of methods to provide user readable names for the locale and its country.Breaks on white space (" ". "JP"). For example. am.StringTokenizer is used to break Java String's into smaller components. Thus nameFR would be "japonais. String nameUS = japan. Today \"I am \" going to my home town" is tokenized on white space." The second call to getDisplayLanguage() returns the language of the locale japan.setDefault( new Locale("en". the following specifies the Locale object for Great Britain and can be used in place of new Locale("en". String sDelimiter) . but if bReturnTokens is set to true.."GB"): Locale. At start-up time. This allows multiple locales to be created for a single language and country combination." 13. localized for the given locale. boolean bReturnTokens) . String sDelimiter. You can create a StringTokenizer by using any one of the following three constructors: StringTokenizer(String sInput) .getDisplayLanguage(). "US") ). Thus nameUS would be "Japanese. the first call to getDisplayLanguage() returns the language of the locale japan. instead of hello.13 StringTokenizer class When working with any general-purpose programming language. "I am ". "\n").."FR")). going.Breaks on sDelimiter. In the above example.In addition. the Locale class contains a number of handy constants for creating Locale objects for commonly used languages and countries. java. going. StringTokenizer(String sInput. it's often necessary to break a large string into smaller components. language and variant fields. the default locale is automatically set by the Java runtime to match the host's current locale. ". StringTokenizer(String sInput.getDisplayLanguage(new Locale("fr".UK A Locale may also be created with an optional variant name. Today.Breaks on sDelimiter. If this is not possible. As an example. When the string "hello. then the delimiter is also returned as a token. called tokens. Locale japan = new Locale("ja".util. this feature could be used to create an "FR_FR_HOST" locale which would match the host's behavior for France rather than Java's portable behavior for France. localized for the default locale. "I. Today. String nameFR = japan. These names can also be localized: Locale. "\t". 329 . Locale contains a static getter and setter method for accessing the system's default locale. the en_US locale is used. the result is in tokens hello. The first constructor doesn't check whether the input string contains substrings.

publication.. One of the most famous sentences in American history begins with the words "Four score and seven years ago". as a token. publication. As long as there are. the StringTokenizer returns four tokens with values book. The third constructor won't work if a token itself is equal (in length and value) to the delimiter and is in a substring.hasMoreTokens()) { println(st. Once there are no tokens remaining. Therefore. suppose this sentence is stored in a variable named speech. When the string "book. the result is book. and date published instead of the six values book. StringTokenizer st = new StringTokenizer(speech).. it uses it's default field separator.The second constructor doesn't check the consecutive appearance of delimiters. publication. (the comma character). When the string "book. author. which is the same as its delimiter) on string . date published (with six tokens) instead of book.". ". date published (with five tokens). the println statement is skipped and the while loop is exited. and assumes that fields within the string are separated by whitespace characters (spaces. publication. publication. A simple snippet of code to break that sentence into individual words using Java's StringTokenizer class would look like this: String speech = "Four score and seven years ago". and date published. For our purposes. The feature of setting the parameter to true is important as it gives an idea about the presence of consecutive delimiters.date published" is tokenized (this string contains . while (st. } In this example. you must set the StringTokenizer's bReturnTokens parameter to true.\". ". author. publication. author.nextToken()). and the resulting output from this snippet of code looks like this: Four score and seven years ago The while loop test checks to see if there are any tokens left in the st object. the variable speech is passed into the StringTokenizer constructor method. "". Because StringTokenizer is not given a field separator value as an input parameter. author. To get six.\". the println statement is executed. author. . and carriage-return characters).date published" is tokenized on ". "". tabs. each time through the while loop a word is printed on a separate line. author.. like this: String speech = "Four score and seven years ago". 330 . where "" means string of length 0.

// read the first record of the database while ( (dbRecord = dis. we specify that the colon character should be the field delimiter (or field separator) when we call the StringTokenizer constructor. String dbRecord = null. After that. String lname = st. Each record contains information about a customer. import java.*. } void dbTest() { DataInputStream dis = null.dbTest(). The following two records are from a hypothetical customer file named customer. Homer:Simpson:Springfield:??? Hank:Hill:Arlen:Texas Because we know that the fields of each record are separated by the colon character.nextToken().nextToken(). import java. Within a record.util. it's a simple matter to break the record into it's four fields using the nextToken() method of the StringTokenizer class.println("City: " + city). like this: StringTokenizer st = new StringTokenizer(dbRecord.nextToken().io.nextToken(). System.println("Last Name: " + lname). String fname = st.println("State: " + state + "\n"). System. each field is separated by a colon character.*.txt. class TokenTest { public static void main (String[] args) { TokenTest tt = new TokenTest(). tt. and the city and state of their address. System.out. String state = st.out. String city = st.println("First Name: " + fname). last name. FileInputStream fis = new FileInputStream(f). try { File f = new File("customer.readLine()) != null) { StringTokenizer st = new StringTokenizer(dbRecord.In this example a text file is used. } } 331 . including their first name. ":"). BufferedInputStream bis = new BufferedInputStream(fis).out. It shows how to break a record (separated by colon characters) into tokens typically called "fields".txt").out. System. ":"). dis = new DataInputStream(bis).

getMessage()). make sure we close it if (dis != null) { try { dis. characters are assigned one of three categories. a StreamTokenizer object expects its input to come from an InputStream class. If you need a more powerful tokenizer. This means that every possible input character is assigned a significance.*. import java.they should be aggregated when they are adjacent to another word character Ordinary characters -.catch (IOException e) { // catch io errors from FileInputStream or readLine() System. 13. StreamTokenizer is a table-driven lexical analyzer.out.println("Uh oh. Like the StringTokenizer. you might look at the StreamTokenizer class instead. TT_Number and Word.io. we simply test the current token's type agaist the class integer constant TT_EOF (this has a value of -1).they should be returned immediately to the parser Having created an instance of the class streamTokenizer we can use the nextToken method to read tokens from the input stream. but that is where the similarity ends.getMessage()). } catch (IOException ioe) { System. 332 .their lexical significance is limited to separating words Word characters -.println("IOException error trying to close the file: " + e. this class converts the input stream into chunks that your parsing code can interpret. } } // end if } // end finally } // end dbTest } // end class The simple method we've shown here is a powerful way of breaking a String into tokens. got an IOException error: " + e. and the scanner uses the significance of the current character to decide what to do.out.14 StreamTokenizer class As the name of the class suggests. Note also that we do not need to know how big the file is in advance in this case. The StreamTokenizer class can recognize various comment styles of programming languages. and offers a number of control flags that can be set to various states.close(). TT_EOL. These are:    Whitespace characters -. In the implementation of this class. } finally { // if the file opened okay. There a four possible predefined types of token: TT_EOF.

println("TT_WORD: sval = " + inStream. int numberOfTokens = -1. // Output result and close file System.out.out. int tokenType = 0. } /* OUTPUT TTYPE: its value. case StreamTokenizer. default: System.println("Number of tokens = " + numberOfTokens). numberOfTokens++.inputStream). StreamTokenizer inStream) { switch (ttype) { case StreamTokenizer.TT_WORD: System.println("TT_EOL").java"). case StreamTokenizer. 333 .TT_EOL: System.sval).*. break.import java.nval).nextToken().out. StreamTokenizer inputStream = new StreamTokenizer(file).println("Unknown: nval = " + inStream. outputTtype(tokenType.out. break. */ Method to output the ttype of a stream token and private static void outputTtype(int ttype. case StreamTokenizer.println("TT_NUMBER: nval = " + inStream.TT_NUMBER: System. class TokenizerExample5 { public static void main(String[] args) throws IOException { FileReader file = new FileReader("HelloWorld. // Process the file and output the number of tokens in the file do { tokenType = inputStream. break. } while (tokenType != StreamTokenizer.out. break.println("TT_EOF").TT_EOF: System.out.util.nval +" sval = " + inStream.TT_EOF).sval).

nextGaussian() Returns random int >= 0 and < n Returns random int (full range) Returns random long (full range) Returns random float >= 0.util. x is a Random object. Random r = new Random(long seed). To use the Random class create an object of this class (giving a seed to the constructor if you wish).nextInt(6) + 1.nextBoolean() double d = r.Random.} } } break.0 and standard deviation 1.nextInt() long l = r. public class RandomNumber { public static void main(String[] args) { Random generator = new Random(). //Default seed comes from system time.nextLong() float f = r. 334 . // For reproducible testing Random methods The most common methods are those which return a random number. except nextGaussian(). 13. Random constructors Random r = new Random().nextInt(int n) int i = r.nextDouble() boolean b = r. A program to generate a random double random import java.random() method and Random class.nextFloat() double d = r.0 and < 1. int i = r.0 Example: Generating a number from 1 to 6 Because nextInt(6) returns a number from 0-5. In these examples. int spots = randGen.0 Returns random double (true or false) Returns random number with mean 0.0 Returns random double >=0.0 and < 1.15 Random class Java provides two mechanisms for creating random numbers – Math. it's necessary to add 1 to scale the number into the range 1-6. These methods return a uniform distribution of values. then call one of the methods below to get a new random number. static Random randGen = new Random().

util package schedules instances of a class called TimerTask.or(bits2).xor(bits2). // And'ing two bitsets bits.get(0).out.16 BitSet class A BitSet class creates a special type of array that holds bit values. bits. System. bits2.set(2). // Or'ing two bitsets bits. // Create the bitset BitSet bits = new BitSet(). The BitSet class implements a bit-vector of an arbitrary size. } } 13. b = bits.length()). // Retrieving the value of a bit boolean b = bits.get(2). 4).and(bits2). This example demonstrates how to create and use a BitSet. // 100 = decimal 4 // false // true // 1110 // 0100 // 1010 // 0101 // 0001 // 1111 13. // Set a bit on bits. The BitSet class represents a set of bits.nextDouble(). thus it can be used to create a thread of execution. // Flip all bits in the bitset bits. // Andnot'ing two bitsets bits. // Setting a range of bits BitSet bits2 = new BitSet().set(1. 335 .println("A random double number: " + num1).andNot(bits2). // Xor'ing two bitsets bits. // Clear a bit bits.clear(1). TimerTask implements the Runnable interface. It automatically grows dynamically.17 Timer and TimerTask classes The Timer class in the java. which is also known as a bitfield.flip(0.double num1 = generator.

The run method contains the code that performs the task. For example. Create a thread by instantiating the Timer class.println("Task scheduled.Timer to schedule a task to execute once 5 seconds have passed.println("Time's up!").cancel(). System. you see this: Time's up! This simple program illustrates the basic parts of implementing and scheduling a task to be executed by a timer thread. Five seconds later.schedule(new RemindTask(). Instantiate the timer task object (new RemindTask()). the following code schedules a task for execution at 11:01 p. seconds*1000). 336 . the subclass is named RemindTask. */ public class Reminder { Timer timer. This example uses the schedule method.util. } } When you run the example. //Terminate the timer thread } } public static void main(String args[]) { new Reminder(5).: //Get the Date corresponding to 11:01:00 pm today. } class RemindTask extends TimerTask { public void run() { System. public Reminder(int seconds) { timer = new Timer().util. Another way of scheduling a task is to specify the time when the task should execute. you first see this: Task scheduled.import java. /** * Simple demo that uses java.m.out. In this example.*. • • • • Implement a custom subclass of TimerTask. with the timer task as the first argument and the delay in milliseconds (5000) as the second argument."). timer. timer.out. Schedule the timer task for execution.

which makes the entire program (and all its threads) exit. After all the timer's scheduled tasks have finished executing. calendar. calendar. • • • • Invoke cancel on the timer.HOUR_OF_DAY. because the program needs to keep running until the timer's task executes. if it has changed. long schedule(TimerTask task. you should use one of the schedule methods when smoothness is important and a scheduleAtFixedRate method when time synchronization is more important. calendar. Secondly. Performing a task repeatedly Here are all the Timer methods you can use to schedule repeated executions of tasks: schedule(TimerTask task. Invoke the System. 0).18 Observable class The Observable class is used to create subclasses that other parts of your program can observe. timer. it must call 337 . observing classes are notified. You can terminate a timer thread in four ways. When an object of such a subclass undergoes a change.schedule(new RemindTask(). remove all references to the Timer object. invoking the cancel method from the timer task's run method. long period) task. Date time = calendar.set(Calendar. Date scheduleAtFixedRate(TimerTask scheduleAtFixedRate(TimerTask delay.getTime(). it must call setChanged(). Date firstTime.set(Calendar. a program keeps running as long as its timer threads are running. Make the timer's thread a "daemon" by creating the timer like this: new Timer(true). timer = new Timer(). such as from a timer task's run method.set(Calendar. Observing classes must implement the Observer interface which defines the update() method. 1). Making the timer thread a daemon wouldn't work. If the only threads left in the program are daemon threads. First. Eventually.Calendar calendar = Calendar.SECOND. long period) task. the program exits. long period) When scheduling a task for repeated execution. Stopping Timer Threads By default. the timer's thread will terminate. 23). The update() method is called when an observer is notified of a change in an observed object. when it is ready to notify observers of this change. The Reminder example uses the first scheme. long delay. 13.getInstance(). An object that is being observed must follow two simple rules.MINUTE. You can do this from anywhere in the program.exit method. time). long period) time.

When the value in the Watcher is changed the notifyObserver passes the changed value to the BeingWatched Object. The update() method is called when a change in the observed object takes place.*. Watcher observing = new Watcher(). An example of using Observer. You can use the second parameter for passing any type of object that is appropriate for your application. This class is being monitored by BeingWatched. There can be more than one observers.println(“update() called. setChanged(). value is:”+ (String)arg). and arg is the value passed by notifyObservers(). notifyObservers(value). If the object calls notifyObservers without having previously called setChanged.notifyObservers(). } } class ObserverDemo { public static void main(String args []) { BeingWatched observed = new BeingWatched(). you must implement the Observer interface. this object is passed to Observer’s update() method as its second parameter. Here Watcher implements Observer. Notice that notifyObserevers() has two forms: one that takes an argument and one does not. This interface defines only the one method shown here: void update (Observable observOb. This causes the update() method in the observing object(s) to be called. observOb is the object being observed. Otherwise null is passed to update(). import java. } } // This is the class being observed class BeingWatched extends Observable { String value. void changeValue(String value) { this. no action will take place. Object arg) { System.out. 338 .value = value.util. If you call the notifyObservers() with an argument. The observed object must call both setChanged() and notifyObservers() before update() will be called. The Observer Interface To observe an observable object. class Watcher implements Observer { public void update (Observable obj. Object arg) Here.

getSymbol())./** Add the observing to the list of observers for observed object.getInstance(Locale. } } The output is shown here. Symbol : $ Default fractional digits : 2 339 .4 has added the Currency class.addObserver(observing).US).changeValue(args[0]).util.getDefaultFractionDigits()). It defines no constructors. This class encapsulates information about a currency.println(“Symbol :” + c.*. observed. class CurDemo { public static void main (String args []) { Currency c = Currency. } } 13. System.19 Currency class Java 2 version 1.out.println(“Default fractional digits :”+ c.out. The following program demonstrates the use of Currency: import java. System. */ observed.

and then another l.it indicates that any one of the letters enclosed within the brackets (in this case.regex package. this regular expression will match text that begins with an uppercase or lowercase w. and not for words that simply contain these 4 characters in sequence.examine the one at the start) looks for word characters. but they do divide the expression into groupings. Let's step it up a notch. either an uppercase 'W' or a lowercase 'w') is acceptable. This effectively rules out williamstown as a match because the second l in williamtown is not followed by a word boundary -. The interesting part is the [Ww] grouping -. then l.util. 14. locate and manipulate complex patterns of text. The above regular expression will actually match 2 occurrences of will -the name Will and the first 4 characters of text in williamstown.1 What is a Regular Expression? A regular expression is a series of metacharacters and literals that allow you to describe substrings in text using a pattern. A word boundary will match the likes of spaces. Here is such a pattern: [Ww]ill This one's pretty straightforward.\w+)? The (\w+) grouping (it appears twice -. The + indicates that one or more word characters must appear (not necessarily the same one). Here's an improved version: \b[Ww]ill\b The \b is how we describe a word boundary. How could we find all occurrences of the text 'Will'. as denoted by the \w. and is followed by the literals i. 340 . tabs. you can easily describe.)(\w+)(\. and the beginning and end points of a line. This must be followed by a literal @ character.it's followed by an i.Chapter 14 : Regular Expression Processing Using regular expressions and the java. So. Consider the following sentence: My name is Will and I live in williamstown. These metacharacters actually form a miniature language in their own right. We may only have wanted to search for will and Will. The parentheses are not actually required here. regardless of whether or not an upper or lowercase 'w' was used? With regular expressions you can describe this requirement by composing a pattern made from a series of metacharacters and literals. Let's examine one more regular expression (\w+)@(\w+\.

net. The period has been escaped using a backslash because the period character is itself a regex metacharacter (a wildcard that matches any character).\w+)* as 'match a period followed by one or more word characters.net.net francisfordcoppola@myisp. our regular expression is intended to match email addresses. we use * to denote that the preceding metacharacter. So. As an example. A few examples that meet the requirements so far: billy@webworld. but expects a period to follow in order to make a match. \w\d* would match a word character followed by zero or more digits.com barney@comcorp. A few examples that meet the requirements of the complete regular expression: fred@vianet. as you've no doubt realised already.we're looking for a period followed by one or more word characters. Let's take a look at a few examples that would meet the requirements so far: billy@webworld. so the * applies to the whole group.iinet. and match that combination zero or more times'. In our example.com joe@optus. The (\w+) grouping is identical to the first grouping -. you can interpret (\.Based on this first portion of our example regex. we use parentheses to group together a series of metacharacters.au wilma@mjinteractive.it looks for one or more word characters. joe@optus.au Java Safe Regular Expressions 341 . But what's with the * after the closing parentheses? In the world of regular expressions.com The (\. You must always escape metacharacters in this way if you want to match on their literal meaning. the (\w+)@ portion. So. here are a few examples that meet the requirements so far: billy@ joe@ francisfordcoppola@ The (\w+\.) grouping is similar. literal or group can occur zero or more times. francisfordcoppola@myisp.\w+)* grouping should mostly make sense at this point -.

The Pattern class has a number of flags that you can use as a second argument to its compile() method.Any backslash delimited metacharacters in java will need to be escaped. you can combine multiple flags by using the java | (vertical bar) operator. You will sometimes want to tell the regex engine that your target string is not a single line of code. So. and not just a subsequence of it. 14.2 Pattern class This class lets you compile your regular expression -.compile(emailRegEx). if you wanted to compile a regex with multiline and case insensitivity support. our example email address regex would have to be rewritten as follows: String emailRegEx = "(\\w+)@(\\w+\\.this effectively optimises it for efficiency and use by multiple target strings (strings which you want to test the compiled regular expression against).MULTILINE ). boolean matches() 342 . // Compile and get a reference to a Pattern object.)(\\w+)(\\. This is because the backslash character has its own special meaning in Java. which simply determines whether the character sequence matches the pattern. The simplest pattern matching method is matches(). This is called the input sequence.compile(myRegEx. you could do the following: Pattern.\\w+)*".\\w+)*".)(\\w+)(\\. you can use Pattern. For instance.3 Matcher class Once you have created a Pattern object. Pattern pattern = Pattern. For example. you will use it to create a Matcher.CASE_INSENSITIVE to tell the regex engine to match ASCII characters regardless of case. it contains several lines that have their own termination characters. Pattern. Once you have a Pattern object you can use it to get a reference to a Matcher object. If you need to. Take note that the Pattern object was retrieved via the Pattern class's static compile method -you cannot instantiate a Pattern object using new. Consider the following example: String emailRegEx = "(\\w+)@(\\w+\\. rather. This is done by calling the matcher() factory method defined by Pattern as shown here Matcher matcher(CharSequence str) Here str is the character sequence that the pattern will be matched against.CASE_INSENSITIVE | Pattern.MULTILINE is another useful one. 14. Pattern.

Understanding Groups Matcher. The above example is continued below: String targetString = "You can email me at g_andy@example. The index one past the end of the current match is obtained by calling end().out. The while loop runs conditionally based on the results of the Matcher class's find() method. Take a look at the output: Found a match: g_andy@example. Matcher matcher = pattern. while (matcher. it was simply a matter of using the Matcher's start() and end() methods to find out where the matched substrings occurred in the target string. it prints the matched email address.println("End position: " + matcher.net Start position: 42 End position: 58 As you can see. and the substring location information. But what if you were also interested in subsections. You can obtain a string containing the last matching sequence by calling group().find()) { System. Each call to find() begins where the previous one left off.println("Found a match: " + matcher.out.group() will retrieve a complete match from the target string.end()). at which point it will return true. // Get a Matcher based on the target string. In the body of our while loop we retrieved the matched substring using the Matcher class's group() method. or 'subgroups' of the matched text? In our email example.start()).com Start position: 20 End position: 38 Found a match: andy@example. } First up. // Find all the matches. Our while loop executes twice: once for each email address in our target string.out.matcher(targetString). returned by the group() method.println("Start position: " + matcher.To determine if a subsequence of the input sequence matches the pattern use find(). Have a look at a revised version of our Matcher driven while loop: 343 . System. System. Be careful: any attempts to use the matcher before calling find() will result in the unchecked IllegalStateException being thrown at runtime. notice that we used the Pattern class's matcher() method to obtain a Matcher object.net to get more info".group()).com or andy@example. You can obtain the index within the input sequence of the current match by calling start(). This method will parse just enough of our target string to make a match. On each occasion. it may have been desirable to extract the host name portion of the email address and the username portion.

} As you may recall..group() or.I suppose MTV is okay too BackReferences 344 .println(matcher.println("Found a match: " + matcher.replaceAll("xxxx") ). the more specific Matcher.group(1) + " and the ISP is " + matcher. groups are represented as a set of parentheses wrapped around a subsection of your pattern.group(2)). // Blot out all references to the BBC. Here is the output for the above example: Found a match: g_andy@example. A minor oversight in this example is that the period itself is captured as part of the subgroup returned by group(2)! Keep in mind that subgroups are indexed from left to right based on the order of their opening parentheses.compile(thePattern.group(0). System. The Username is andy and the ISP is example.out. Further groups can be found using the same group(int index) method. As you can see. When crafting your own regular expressions it is..find()) { System. of course. in particular. Matcher matcher = pattern. as in the example. Here' the output: I like to watch xxxx and xxxx .matcher(target). String target = "I like to watch bBC1 and BbC2 . The Username is " + matcher. Have a look at the following code: // Matches 'BBC' words that end with a digit. // The target string. This is particularly important when you are working with groups that are nested within other groups. The Matcher class has a number of interesting methods: String replaceAll(String replacementString) and String replaceFirst(String replacementString). located using Matcher. Pattern. The Username is g_andy and the ISP is example.CASE_INSENSITIVE). represents the entire match. Pattern pattern = Pattern. are worth a mention here. // Compile regex and switch off case sensitivity.out. String thePattern = "bbc\\d". group(1) retrieves the username portion of the email address and group(2) retrieves the ISP portion.com.I suppose MTV is okay too". Found a match: andy@example. // Get the Matcher for the target string. The first group. The replaceAll() method takes a replacement string and replaces all matches with it.while (matcher.group(0) + ". The replaceFirst() method is very similar but will replace only the first occurrence of a match. up to you how you logically subgroup your patterns.net.

only much more powerful. You can use the boolean matches(String regex) method to quickly determine if a string exactly matches a particular pattern. the third parenthesised group will only match when the character at this position is the same as the character in the first parenthesised group. The Matcher object's replacement methods (and the String class's counterparts) also support a notation for doing backreferences in the replacement string. String replacement) methods allow you to do quick and dirty text replacements. that kind of thing. Basically. These last two methods are.4 String Class RegEx Methods The Java String class has been updated to take advantage of regular expressions.StringTokenizer. but in many cases. tremendously useful. It works in the same way. you would simply substitute \1 with \2 if you wanted to backreference the second group. mum. the String[] split(String regEx) and String[] split(String regEx. 14. int limit) methods let you split a string into substrings based on a regular expression. matcher. Here's a pattern that will do the job: (\w)(\w)(\1) In this case. String replacement) and String replaceAll(String regex. in concept. similar to the java. this means that you can refer to a subgroup from an earlier part of a match later on in the pattern. Of course. There are 5 such methods available.util. Imagine that you needed to inspect a target string for 3-letter words that started and ended with the same letter -. sos. And finally.replaceAll("$2") would replace all matches in a target string with the value matched by the second subgroup of the regular expression. So. The appropriately named String replaceFirst(String regex. but uses a dollar sign instead of a backslash.Backreferences allow you to access captured subgroups while the regex engine is executing. Basically.wow. the (\1) group contains a backreference to the first match made in the pattern. It's simple. 345 .

The abstract base class DateFormat does not define static methods for formatting (date to text) or parsing (text to date). Instead. MEDIUM.1 DateFormat class While Calendar and related classes handle the locale-specific interpretation of dates. and FULL (in increasing order of verbosity). The abstract base class DateFormat does not require (and does not permit) the definition of arbitrary. Locale locale) The String format(Date) and Date parse(String) methods then perform the transformation. static final DateFormat getDateInstance() static final DateFormat getDateInstance(int style) static final DateFormat getDateInstance(int style. it defines four different format styles: SHORT. formatted according the conventions of the default locale. programmer-defined date formats. an additional localization issue arises: not only the language.Chapter 15 : API classes in java. Given a locale and a style.out. Also available are (abstract) methods for piece-wise parsing or formatting. LONG. to allow handling of alternatives to Date in subclasses. as are the employed TimeZone and NumberFormat objects. additional factory methods are available to obtain instances treating only the time or date part. The commands DateFormat df = DateFormat. taking an additional ParsePosition or FieldPosition argument.format( new Date() ). The Calendar object used internally to interpret dates is accessible and can be modified. The DateFormat utility tries to manage these differences for the application programmer. print the current date and time (as returned by "new Date()"). Since the standard formats always include both date and time. There are two versions for each of these methods. When representing points in time.: Month/Day/Year.getDateTimeInstance(). The output will look different in different countries.). etc. the DateFormat classes assist with the transformation of dates to and from human-readable strings. but also the date format is locale-dependent (U. The class defines several public static 346 . Instead. System. the programmer can rely on the class to use an appropriate date format. respectively. the locale and style can no longer be changed once the DateFormat has been instantiated.println(now). Note that concrete subclasses may choose to break this idiom.Month.text 15.Year. One takes or returns a Date instance and the other takes or returns a general Object. Germany: Day.S. However. String now = df. it defines several static factory methods to obtain instances (of concrete subclasses) initialized for a given locale and a chosen style.

getDateInstance(DateFormat.UK).println("First flight was " + s).*. String s = df. 17).format(date)). DateFormat df = DateFormat. converting it to a Date.out.US). public class Flight { public static void main(String[] args) { GregorianCalendar firstFlight = new GregorianCalendar (1903.LONG.JAPAN).out. import java.out.getDateInstance(DateFormat.getDateInstance(DateFormat. Date d = firstFlight. and getting and outputting the corresponding String in the following program: import java. Locale.KOREA). System. System. Locale. } } One more example that specifies the date style and locale import java.MEDIUM.LONG).getDateInstance(DateFormat.SHORT. df = DateFormat. df = DateFormat. System.text.println(“UK :”+ df.text.getTime(). } } Sample output is shown below: 347 .util.format(d). public class DateFormatDemo { public static void main (String args[]) { Date date = new Date(). Calendar.println(“Japan :”+df. System.format(date)).FULL.util. DateFormat df = DateFormat.format(date)).variables with names ending in _FIELD to identify the various possible fields for use with FieldPosition In the following example the getTime() method of GregorianCalendar returns a Date corresponding to the GregorianCalendar object.out.out. Locale.getDateInstance(DateFormat. You can put the whole process of creating a GregorianCalendar object.*.format(date)).println(“US :”+ df.*. Locale. df = DateFormat.*. System.println(“Korea :”+df. import java.DECEMBER.

UK).text. } } Sample output from the program is shown here: Japan : 20:25 UK : 20:25:14 CDT Canada : 8:25:14 o’clock PM CDT The DateFormat class also has a getDateTimeInstance() method that can format both date and time information.LONG. DateFormat df = DateFormat. May 8. import java. df = DateFormat.JAPAN). additionally allowing the definition of arbitrary dateformatting patterns. public class TimeFormatDemo { public static void main(String args[]) { Date date = new Date(). LONG or FULL. An example of using it is shown below: import java.out.println(“Canada :”+df. System.println(“UK :”+df.*.CANADA).2 SimpleDateFormat class The only commonly available concrete subclass of DateFormat is SimpleDateFormat. SHORT.Locale.out. These are int constants which cause different details about the time to be presented.format(date)).FULL. df = DateFormat.*.out.getTimeInstance(DateFormat. The argument locale is one of the static references of Locale.getTimeInstance(DateFormat.format(date)).SHORT. 2002 The getTimeInstance() method returns an instance of DateFormat that can format time information. 348 . MEDIUM. System. Locale.Japan : 02/05/08 Korea: 2002-05-08 UK: 08 May 2002 US: Wednesday.format(date)).Locale. It is available in these versions: static final DateFormat getTimeInstance() static final DateFormat getTimeInstance(int style) static final DateFormat getTimeInstance(int style. The pattern can be specified as an argument to the constructors of this class or set explicitly. It provides all of the aforementioned functionality. Locale locale) The style argument is one of the following values: DEFAULT. 15. System. If the style and/or locale is not specified defaults are used.getTimeInstance( DateFormat.util.println(“Japan :”+df.

String logEntry = formatter.out.*. the number of times a pattern letter is repeated determines how many digits are presented. System. Date now = new Date(). For numbers.text. } } One more example to format and parse it back. Text information is displayed in an abbreviated form if the pattern letter is repeated less than four times.format(now). SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMM dd hh:mm"). Three or more repetitions of M cause the month to be displayed as a text string. String rptDate = sdf. Otherwise unabbreviated form is used.The constructor normally takes a formatting string made from the following symbols: Char a d h k m s w y z : Meaning Char Meaning AM or PM D Day of year Day of month E Day of week Hour (1-12) F Day of week in month Hour (1-24) G Era (AD or BC) Minute H Hour in Day (0-23) Second K Hour in Day (0-11) Week of year M Month Year S Millisecond Timezone W Week of month Separator / Escape character SimpleDateFormat(String formatString) In most cases. M or MM causes the month to be displayed as one or two digits.*. import java. One example of using SimpleDateFormat import java. the number of times a symbol is repeated determines how that data is presented. 349 .println(rptDate+"\n"). public class test { public static void main (String args[]) { Date date = new Date().format(date).util. // Create a formatter with the following pattern: //Hour(0-23):Minute:Second SimpleDateFormat formatter = new SimpleDateFormat( "HH:mm:ss" ).

1998. You can change symbols that represent names for months. days of the week.out.parse( logEntry ). String [] defaultDays = symbols. April 10. you can change them with the DateFormatSymbols. 15.printStackTrace().// To read the string back in try { Date sometime = formatter.println(). Here is the source code: DateFormatSymbols symbols = new DateFormatSymbols( new Locale("en".3 DateFormatSymbols class The format method of the SimpleDateFormat class returns a String composed of digits and symbols. for (int i = 0. among others. For example."US")). The first element in the array argument of setShortWeekdays is a null String." If the symbols encapsulated in SimpleDateFormat don't meet your needs. The following table lists the DateFormatSymbols methods that allow you to modify the symbols: DateFormatSymbol Methods Example of a Symbol the Method Modifies setAmPmStrings PM setEras AD setMonths December setShortMonths Dec setShortWeekdays Tue setWeekdays Tuesday setZoneStrings PST Setter Method The following example invokes setShortWeekdays to change the short names of the days of the week from lowercase to uppercase characters. The full source code for this example is in DateFormatSymbolsDemo.print(defaultDays[i] + " "). Therefore the array is one-based rather than zero-based. The SimpleDateFormat constructor accepts the modified DateFormatSymbols object as an argument. 350 . It is thrown when the beginning of the input string cannot be parsed. } System. and time zones. i++) { System.getShortWeekdays()." the symbols are "Friday" and "April. } catch ( ParseException exc ) { exc.length. in the String "Friday. i < defaultDays.out. } Note the ParseException that needs to be caught.

a currency formatter. for (int i = 0. SimpleDateFormat formatter = new SimpleDateFormat("E".getCurrencyInstance(). your number will automatically use the comma as the decimal separator and the period as the grouping separator--just the opposite of the custom in the US. i < modifiedDays.out. symbols). nf = NumberFormat. pf = NumberFormat. "THU".format(amount)). String result = formatter.getNumberInstance(). "TUE".out. Here's an example: NumberFormat nf. The preceding code generates this output: Sun SUN WED Mon MON Tue TUE Wed WED Thu THU Fri FRI Sat SAT 15. pf. The three factory methods you use to create built-in format objects are the getNumberInstance(). If your application is run in Germany. "SAT"}. "FRI".getShortWeekdays(). passing either a double primitive value or a Double object. For example.println (“Total amount: "+fmt. NumberFormat fmt = NumberFormat. "WED". cf. "MON".length. and getPercentInstance(). i++) { System. "SUN".4 NumberFormat class Using Java's NumberFormat class.format(today). To use your NumberFormat object.println(result). Date today = new Date(). You have your choice of three built-in formatting styles: a generic number formatter.setShortWeekdays(capitalDays).println().getCurrencyInstance(). you simply call its format() method. You don't use the new operator to construct your NumberFormat objects. 351 . instead you use very specific methods called factory methods. String [] modifiedDays = symbols. cf = NumberFormat. The first step is to create a NumberFormat object. } System.out.String[] capitalDays = {“". System.print(modifiedDays[i] + " ").getPercentInstance(). getCurrencyInstance(). symbols. you can automatically format numbers according to the local conventions in use where your application is run.out. and a percentage formatter. for instance. System.

246 345.21 DM de_DE $9. When you invoke the format method. String currencyOut = currencyFormatter. it returns a String that includes the formatted number and the appropriate currency sign. and their corresponding wrapper objects. The following code example formats a Double according to Locale. You format currencies in the same manner as numbers.println(currencyOut + " " + currentLocale. 352 . invoke the getPercentInstance method.876. NumberFormat currencyFormatter = NumberFormat.format(currency). The output from this example shows how the format of the same number varies with Locale: 345 987.987.543. Of course.out. System.You can use the NumberFormat methods to format primitive-type numbers.543. However. You can also use the methods of the NumberFormat class to format percentages.toString()).246 fr_FR de_DE en_US If you're writing business applications.format(amount). you'll probably need to format and to display currencies. The output generated by the preceding lines of code is as follows: 9 876 543.876. The methods belonging to the NumberFormat class format currencies but do not convert them. a decimal fraction such as 0. This code example shows how to format currency in a locale-specific manner: Double currency = new Double(9876543.out.21 DM. NumberFormat numberFormatter = NumberFormat.876. such as Double.21 F fr_FR 9. because the numeric values are all the same. To get the locale-specific formatter. except that you call getCurrencyInstance to create a formatter.21 F is not equivalent to 9. String amountOut = numberFormatter. such as double. 9 876 543.543. Double amount = new Double(345987.75 is displayed as 75%. The following code sample shows how to format a percentage.246 345.21).getCurrencyInstance(currentLocale). With this formatter. bear in mind that the NumberFormat class is unaware of exchange rates. Invoking the getNumberInstance method returns a locale-specific instance of NumberFormat. System.toString()). The format method accepts the Double as an argument and returns the formatted number in a String.21 en_US At first glance this output may look wrong to you.getNumberInstance(currentLocale).println(amountOut + " " + currentLocale.246).987.

prefixes and suffixes.getPercentInstance(currentLocale). A DecimalFormatSymbols object can be optionally specified when creating a DecimalFormat object. The format method accepts a double value as an argument and returns the formatted number in a String: DecimalFormat myFormatter = new DecimalFormat(pattern). The example that follows creates a formatter by passing a pattern String to the DecimalFormat constructor. This class allows you to control the display of leading and trailing zeros. For example: "$#.($#. ' Interpretation A digit // leading zeros show as 0 A digit // leading zeros show as absent The locale-specific decimal separator The locale-specific grouping separator (comma) The locale-specific negative prefix Shows value as a percentage Separates a positive number format (on left) from an optional negative number format (on right) Escapes a reserved character so it appears literally in the output You specify the formatting properties of DecimalFormat with a pattern String. The pattern determines what the formatted number looks like. The applyPattern() method can be used to change this pattern. If one is not specified.out. a DecimalFormatSymbols object suitable for the default locale is used.75). System. These classes offer a great deal of flexibility in the formatting of numbers. grouping (thousands) separators. % .5 DecimalFormat class You can use the DecimalFormat class to format decimal numbers into locale-specific strings.println(value + " " + pattern + " " + output). and the decimal separator. Decimal format patterns consists of a string of characters from the following table.00. 15.Double percent = new Double(0.format(value).00)" Char 0 # . but they can make your code more complex. String percentOut = percentFormatter. String output = myFormatter.##0.##0. NumberFormat percentFormatter = NumberFormat. Applications that require highly customized number formatting and parsing may create custom DecimalFormat class objects by passing a suitable pattern to the DecimalFormat() constructor method. you can use the DecimalFormatSymbols in conjunction with the DecimalFormat class. such as the decimal separator. If you want to change formatting symbols. . 353 .format(percent).

## 000000.out. Note that it immediately precedes the leftmost digit in the formatted output. represents the formatted number. The format method handles this by rounding up. and the period is a placeholder for the decimal separator.###. Here is an example of how DecimalFormat can be used: import java. public class test { public static void main (String args[]) { int numb = 3. The value has three digits to the right of the decimal point. the comma is a placeholder for the grouping separator. DecimalFormat df = (DecimalFormat)nf. because the 0 character is used instead of the pound sign (#). } } The preceding example created a DecimalFormat object for the default Locale. The first character in the pattern is the dollar sign ($).78 9 123456. DecimalFormat df = new DecimalFormat("000"). The value is the number.###.getNumberInstance(loc).println(rptNumb+"\n").78 9 123456. The pattern specifies leading and trailing zeros.The output for the preceding lines of code is described in the following table.78 12345. but the pattern has only two.*. String output = df.345.000 $###.### ¥12.67 12345.78 9 123.79 ###. Here's an example: NumberFormat nf = NumberFormat. rptNumb = df.67 ###.67 \ u00A5###. The pattern is the String that specifies the formatting properties. df. Output from DecimalFormatDemo Program value pattern output 123456. that is to be formatted.780 $12. which is a String.### 000123. The pattern specifies the currency sign for Japanese yen (¥) with the Unicode value 00A5.text.###. If you want a DecimalFormat object for a nondefault Locale. a double . you instantiate a NumberFormat and then cast it to DecimalFormat.format(value). 354 . System. String rptNumb.### 123.67 Explanation The pound sign (#) denotes a digit.456.345.applyPattern(pattern).format(numb). The output.

. unusualSymbols. which is in the second column.out. allow the end users to define their own formatting patterns.###. and the percent sign.###". However.toString()).789 123. English.###. in the pattern ###.S. String bizarre = weirdFormatter. unusualSymbols).setDecimalSeparator('|').###.456.### ###. some applications.println(bizarre). The unusual format is the result of the calls to the setDecimalSeparator. setGroupingSeparator.### ###. Running the previous code example results in the output that follows. varies with Locale: ###. This convention is fine.) static methods to output a single number or string with formatting descriptions similar to the printf function in C. the grouping separator.789 123 456. among others.678).456. unusualSymbols.###.setGroupingSize(4). the minus sign. For example.setGroupingSeparator('^'). DecimalFormat weirdFormatter = new DecimalFormat(strange. In these cases you'll want to invoke the applyLocalizedPattern method on the DecimalFormat object. 355 . and setGroupingSize methods.print(.789 en_US de_DE fr_FR So far the formatting patterns discussed here follow the conventions of U.## the comma is the thousands-separator and the period represents the decimal point. You can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method.### 123.out.##0.println(pattern + " " + output + " " + loc. provided that your end users aren't exposed to it. The next example demonstrates the DecimalFormatSymbols class by applying a strange format to a number. DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(currentLocale). The formatted number. These symbols include the decimal separator. When run. System. String strange = "#. this example prints the number in a bizarre format: 1^2345|678 15.format(12345.6 Format class The class Format provides several overloaded Format. For these applications the formatting patterns specified by the end users should use localized notation. such as spreadsheets and report generators. weirdFormatter.System.

class FormatDemo { public static void main(String args[]) { double q = 1.0. String str = new Format("0. // Can change the format pattern: qValStr = new Format ("%0.0 = " + qValStr).out.println ("1.out. This can be done in a convenient single line approach by appending the method invocation to the instantiation operation as shown here: double q =10.5f").For example.0.3f").5g"). where arg is a number type. System. An instance of the format must first be created with the desired formatting description.0 = " + qValStr).0/2.3333 To send formatted outputs directly to a string.format(q) which results in the string variable str referencing "3.4f".println ("1.0. // q = 3.0/3.0/3.0/4567.out. qValStr = new Format ("%0.*.333e+000".0.format (q).2e"). // q = 1000. System.text.println ("1000.0/3. The following program shows the use of Format class.0/3.0/3. // The # symbol indicates trailing blanks q = 1. System.println ("1. qValStr = new Format ("%0.0. the class provides several overloaded format(arg) methods.0/2. q).0 = " + qValStr).print("0.format (q).format (q). Format. // Create an instance of the format pattern // and then create the string with the method format String qValStr = new Format ("%0. import java. will result in an output of 3.0.3e").0/3. double q =10. System. 356 .0/3.format (q).0 = " + qValStr).out.

0 = 0.333 1. } } Output of this program: 1.out. you can design a custom format using patterns.2e").33e+002 3.5 1000.0/0. qValStr = new Format ("%0.0.0/3.0 = 3.out. 357 .println ("0.3e").0/3. qValStr = new Format ("%0.format (q).0 = " + qValStr).0/0. // NaN q = 0.0 = NaN Summary To format a number to display to an end user.0/0.0/0. When using NumberFormat.0 = " + qValStr). // Negative infinity q = -1.0/0.println ("-1.0/0.57e-004 -1.0/3. Or. System.text package.0 = 0.0 = 0.0/4567. you use the NumberFormat class in the java. System.33333 1. System. you can get a default format for decimal numbers.0.0 = " + qValStr).format (q).out.0/4567.qValStr = new Format ("%0. or currency. percentages.println ("3.0/2.0 = 6.0 = -Inf 0.3e").format (q).

All this makes Java programs unnecessarily hard to read and maintain. To use a generic you supply an actual type argument for each type parameter and in doing so constrain the generic type to act only on the argument types. Generics allow you to define a class or interface once and instantiate it with a variety of types.Chapter 16 : Collections Framework and Generics 16. Using generics. a collection is no longer treated as a list of Object references. but you would be able to differentiate between a collection of references to Integers and collection of references to Bytes. since you cannot have collections of primitive data types you must convert the int to the corresponding reference type (i. It is your responsibility. Now. A generic (also known as a parametrized type) is a type that has one or more type parameters. class BasicGeneric <A> { 358 . Defining and Using Generic Types To define a generic. and are more likely to fail with runtime errors. A collection with a generic type has a type parameter that specifies the element type to be stored in the collection.java contains a very simple generic class called BasicGeneric. to keep track of what types of objects your collections contain. A Java collection is a flexible data structure that can hold heterogeneous objects where the elements may have any reference type. when the element is extracted from the collection an Object is returned that must be cast to an Integer in order to ensure type safety. Collections typically represent data items that form a natural group. type parameters are uppercase letters. By convention. The type parameters are a comma separated list of identifiers delimited by angle brackets. however. consider adding an int to a collection. 16. and to transmit data from one method to another. and a second class called GenSample that calls it.1 What is a Collection? A collection (sometimes called a container) is simply an object that groups multiple elements into a single unit. you include type parameters following the type name. retrieve and manipulate data. As an example. either as the type of arguments in the method's parameter list or as the type of its return value. the need for developers to keep track of what type of elements collections contain. Collections are used to store. GenSample.2 Generics The motivation for adding generics to the Java programming language stems from the lack of information about a collection's element type. Integer) before storing it in the collection.e. and the need for casts all over the place. The type parameters then appear in the type's methods.

getData(). return data02. } } public class GenSample { public String test01(String input) { String data01 = input. BasicGeneric does not work with any specific type. BasicGeneric <Integer> basicGeneric = new BasicGeneric<Integer>(data01). System. } public A getData() { return data. But when you declare an instance of this class.println(sample. But it is quite sensible when you begin to understand generics. String data02 = basicGeneric. } public static void main(String [] args) { GenSample sample = new GenSample(). you must specify the type with which you want to work: BasicGeneric<String> basicGeneric 359 . System. } } Here you can see the brackets that surround the capital letter A: <A>. we don't assign a type to A. As a result.test02(12)). } public int test02(int input) { Integer data01 = new Integer(input). Integer data02 = basicGeneric. return data02.data = data.test01("This generic data")).private A data.getData(). BasicGeneric<String> basicGeneric = new BasicGeneric<String>(data01).out.println(sample. Notice also that the class declares a variable of type A – data. This syntax specifies that the class is a generic type. public BasicGeneric(A data) { this.out. This syntax can be confusing at first glance. It is a generic type.

Implementations: concrete implementations of the collection interfaces. a collections framework frees you to concentrate on the important parts of your program. high-quality implementations of useful data structures and algorithms. It reduces the effort to learn and use new APIs: Many APIs naturally take collections on input and output. like searching and sorting. you will have specified the type of A. each such API had a little "sub-API" devoted to manipulating its collections. In the past. All collections frameworks contain three things: • • • Interfaces: abstract data types representing collections. Finally. these interfaces generally form a hierarchy. In essence. It increases program speed and quality: The collections framework does this primarily by providing high-performance. It allows interoperability among unrelated APIs: The collections interfaces will become the "lingua franca" by which APIs pass collections back and forth. Benefits of Collection Framework • • • • It reduces programming effort: By providing useful data structures and algorithms. Interfaces allow collections to be manipulated independently of the details of their representation. and that type only. These algorithms are said to be polymorphic because the same method can be used on many different implementations of the appropriate collections interface.util package. rather than the low-level plumbing required to make it work. In essence. After you declare an instance of BasicGeneric. The collections framework is a part of java. which is to say that it will return a generic type. so you had to learn each one from scratch and it was easy to make mistakes 360 . But that does not mean that the function will not have a type at run time. because you're freed from the drudgery of writing your own data structures. and your GUI toolkit expects a Collection of column headings. Also. because the various implementations of each interface are interchangeable. In object-oriented languages like Java. our APIs will interoperate seamlessly even though they were written independently. these are reusable data structures. Algorithms: methods that perform useful computations. By facilitating interoperability among unrelated APIs. or even at compile time. on objects that implement collection interfaces. programs can be easily tuned by switching collection implementations. 16.The method getData() returns a value of type A. There was little consistency among these ad-hoc collections sub-APIs. After that. If my network administration API furnishes a Collection of node names. algorithms are reusable functionality. you'll have more time to devote to improving the quality and performance of the rest of the program. BasicGeneric will act as if it were declared from the very beginning to work with that specific type.3 What Is a Collections Framework? A collections framework is a unified architecture for representing and manipulating collections. the collections framework frees you from writing oodles of adapter objects or conversion code to connect APIs.

The basic purpose of these interfaces is to allow collections to be manipulated independently of the details of their representation. Some types of collections allow duplicate elements. 16.4 Collection Interfaces The core collection interfaces are the interfaces used to manipulate collections..• • when using them. Set 361 . When you declare a <code> Collection instance you can and should specify the type of object contained in the collection. and others do not. It reduces effort to design new APIs: This is the flip-side of the previous advantage: designers and implementers don't have to reinvent the wheel each time they create an API that relies on collections. Collection The Collection interface is the root of the collection hierarchy. The core collections interfaces are shown below: Note that all of the core collection interfaces are generic. The <E> syntax tells you that the interface is generic.. It fosters software reuse: New data structures that conform to the standard collection interfaces are by nature reusable. thus reducing errors at runtime. Specifying the type allows the compiler to verify (at compile time) that the type of object you put into the collection is correct. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces. The same goes for new algorithms that operate on objects that implement these interfaces. such as Set and List. The Collection interface is the least common denominator that all collections implement. and is used to pass collections around and to manipulate them when maximum generality is desired. They just use the standard collections interfaces. For example. With the advent of standard collections interfaces. and to pass them from one method to another. the problem goes away. The core collection interfaces are the heart and soul of the collections framework. Some are ordered and others unordered. the declaration of the Collection interface is: public interface Collection<E> .

362 .A Set is a collection that cannot contain duplicate elements. and inspection operations. As you might expect. queues provide additional insertion. In other words. this interface models the mathematical set abstraction. it allows you to convert the type of the collection. extraction. 16. SortedSet A SortedSet is a Set that maintains its elements in ascending order. whatever the given collection's subinterface or implementation type. Map A Map is an object that maps keys to values. This constructor. by convention all general-purpose collection implementations have a constructor that takes a Collection argument. which order elements according to a supplied comparator. or the processes running on a machine. List A List is an ordered collection (sometimes called a sequence). order elements in a FIFO (first-in-first-out) manner. Besides basic Collection operations. It is used to represent sets like the cards comprising a poker hand. Among the exceptions are priority queues. all new elements are inserted at the tail of the queue. Every Queue implementation must specify its ordering properties. Lists can contain duplicate elements. or the elements' natural ordering. It is the Map analogue of SortedSet. The user can access elements by their integer index (position). The user of a List generally has precise control over where in the List each element is inserted. initializes the new collection to contain all the elements in the specified Collection. In a FIFO queue. The SortedMap interface is used for apps like dictionaries and telephone directories. Queues typically.5 The Collection Interface The Collection interface is used to pass around collections of objects where maximum generality is desired. known as a conversion constructor. the courses making up a student's schedule. For example. Other kinds of queues may use different placement rules. SortedMap A SortedMap is a Map that maintains its mappings in ascending key order. The Set interface extends Collection and contains no methods other than those inherited from Collection. Maps cannot contain duplicate keys: Each key can map to at most one value. the head of the queue is that element that would be removed by a call to remove or poll. Whatever the ordering used. but do not necessarily. Queue A collection used to hold multiple elements prior to processing.

import java. or another kind of Collection. initially containing all the elements in c: List<String> list = new ArrayList<String>(c). It guarantees that the Collection will contain the specified element after the call completes. } } 363 . Similarly.add(“A”).println(“Size of al after additions:” + al. al.println(“Initial size of al :”+al. System.add(“F”).util.out. al.println(“Contents of al : ” + al). al. to check whether a given object is in the collection (contains). The following program shows a simple use of ArrayList. //add elements to arraylist al.remove(“F”). to add and remove an element from the collection (add. and then objects of type String are added to it.size()). and to provide an iterator over the collection (iterator). The list is then displayed. isEmpty).size()).remove(“E”). and returns true if the Collection changes as a result of the call. al.println(“Contents of al:”+al). which may be a List. The following idiom creates a new ArrayList (an implementation of the List interface). that you have a Collection<String> c. //Remove elements from arraylist al.out.add(“B”). The add method is defined generally enough so that it makes sense for collections that allow duplicates as well as those that don't. given that a Collection represents a group of objects.out. remove). System. assuming that it contains the element to start with. System. al.add(“D”). the remove method is defined to remove a single instance of the specified element from the Collection. //display the array list System.Suppose. The interface has methods to tell you how many elements are in the collection (size. class ArrayListDemo { public static void main(String args[]) { //create an array list ArrayList al = new ArrayList().add(“C”).size()). System. The interface does about what you'd expect.out.add(“E”). al. Some of the elements are removed and the list is displayed again. for example. and to return true if the Collection was modified as a result.println(“Size of al after deletions :” +al.*. a Set. An arraylist is created .out.

The following code uses the for-each construct to print out each element of a collection on a separate line: for (Object o : collection) System. You get an Iterator for a collection by calling its iterator method. and to remove elements from the collection selectively. if desired.A.add(new Integer(10)).B. The hasNext method returns true if the iteration has more elements.*. al.The output of this program is shown here: Initial size of al : 0 Size of al after additions : 6 Contents of al : [C. for(Object o : al) { System. al.E. al.D] Traversing Collections There are two ways to traverse collections: with the for-each construct and using iterators. For-Each Construct The for-each construct allows you to concisely traverse a collection or array using a for loop The for Statement. 364 .add(new Float(1.println(o).out.B.out. The remove method removes from the underlying Collection the last element that was returned by next.A. The following code shows an example import java.D.util.0)). class ArrayListDemo2 { public static void main(String args[]) { ArrayList al = new ArrayList().F] Size of al after deletions : 4 Contents of al : [C. and the next method returns the next element in the iteration.println(o). The remove method may be called only once per call to next and throws an exception if this rule is violated. } } } Iterators An Iterator is an object that enables you to traverse through a collection.add(“ABC”).

if(((String)element). //add elements to arraylist al.next().out. al. The for-each construct hides the iterator.add(“D”).add(“C”).C. though in most cases such implementations would be less efficient.println().add(“E”).remove().print(element+ “ ”). An example that shows the use of Iterator: //Demonstrate Iterators import java. Therefore.hasNext()) { Object element = itr.Note that Iterator. al.out.util.B. The bulk operations are: 365 . al. while(itr.remove is the only safe way to modify a collection during iteration. the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.D] Collection Interface Bulk Operations The bulk operations perform an operation on an entire Collection. System. You need to iterate over multiple collections in parallel. } } The output of this program is as follows : A B C D E [A. //use Iterator to display contents of al Iterator itr = al. You need to replace elements in a list or array as you traverse it. You could implement these shorthand operations using the basic operations.add(“A”). } } System. al. class IteratorDemo { public static void main(String args[]) { ArrayList al = new ArrayList().*. the for-each construct is not usable for filtering.println(al). System.equals(“E”)) { itr. Use an iterator instead of the for-each construct when: • • • You need to remove the current element.iterator(). so you cannot call remove.add(“B”).out.

al.• • • • • containsAll: Returns true specified Collection. it retains in the target Collection only those elements that are also contained in the specified Collection.add(new Integer(1)). retainAll: Removes from the target Collection all its elements that are not also contained in the specified Collection.add(new Integer(3)). For example. class ArrayListToArray { public static void main(String args[]){ ArrayList al = new ArrayList(). The simple form with no arguments creates a new array of Object. The addAll.println(“Contents of al:”+al). The more complex form allows the caller to provide an array or to choose the runtime type of the output array. import java.add(new Integer(4)). suppose that c is a Collection.toArray(new String[0]).out.util. al. //get array Object [] ia = al. al. That is. addAll: if the target Collection contains all of the elements in the Adds all the elements in the specified Collection to the target Collection. The array operations allow the contents of a Collection to be translated into an array. and retainAll methods all return true if the target Collection was modified in the process of executing the operation.toArray(). //add elements to array list al. removeAll: Removes from the target Collection all its elements that are also contained in the specified Collection. Collection Interface Array Operations The toArray methods are provided as a bridge between collections and older APIs that expect arrays on input. System. The following snippet dumps the contents of c into a newly allocated array of String whose length is identical to the number of elements in c: String[] a = c.toArray(). clear: Removes all elements from the Collection.add(new Integer(2)). int sum=0. removeAll. 366 . An example of converting an ArrayList into an array.*. The following snippet dumps the contents of c into a newly allocated array of Object whose length is identical to the number of elements in c: Object[] a = c. Suppose that c is known to contain only strings (perhaps because c is of type Collection<String>).

returning a set of the same generic type as the one passed in: 367 . TreeSet.out. i < ia.} } //sum of array elements for(int i=0. Set also adds a stronger contract on the behavior of the equals and hashCode operations. orders its elements based on their values.) initially containing all the elements in c Here is a minor variant of this idiom that preserves the order of the original collection while removing duplicate element: Collection<Type> noDups = new HashSet<Type>(c). Here is a generic method that encapsulates the above idiom.4] Sum is: 10 16. The output of the program is shown below: Contents of al: [1. TreeSet. } System. c. The following one-liner does the trick: Collection<Type> noDups = new HashSet<Type>(c). and adds the restriction that duplicate elements are prohibited. but is substantially slower than HashSet. LinkedHashSet spares its clients from the unspecified. LinkedHashSet.length . It models the mathematical set abstraction. orders its elements based on the order in which they were inserted into the set (insertion-order). Two Set instances are equal if they contain the same elements. The Java platform contains three general-purpose Set implementations: HashSet. i++) { sum += (Integer)ia.println(“Sum is:”+sum). Here's a simple but useful Set idiom.6 The Set Interface A Set is a Collection that cannot contain duplicate elements. and you want to create another Collection containing the same elements but with all duplicates eliminated. which is implemented as a hash table with a linked list running through it. and LinkedHashSet HashSet. cannot contain duplicate. The Set interface contains only methods inherited from Collection. generally chaotic ordering provided by HashSet. allowing Set instances to be compared meaningfully even if their implementation types differ.3. at a cost that is only slightly higher. It works by creating a Set. which stores its elements in a red-black tree. which stores its elements in a hash table. which by definition. is the best-performing implementation but it makes no guarantees concerning the order of iteration. Suppose you have a Collection.2.

If the program uses any nonstandard operations that are present in the original implementation type but 368 .println("Duplicate: " + a). all such variables and parameters must be changed in order to change the collection's implementation type. This is a strongly recommended programming practice. } Set Interface Basic Operations The size operation returns the number of elements in the Set (its cardinality).add(a)) { System.println(s. The iterator method returns an Iterator over the Set.size()+" distinct words:" + s). and a list of the words with duplicates eliminated: import java.util.out. The isEmpty method does exactly what you think it does. as it gives you the flexibility to change implementations merely by changing the constructor. saw. came] Note that the code always refers to the collection by its interface type (Set). The add method adds the specified element to the Set if it's not already present.out. } } Now let's run the program: java FindDups i came i saw i left The following output is produced: Duplicate: i Duplicate: i 4 distinct words: [i.public static <E> Set<E> removeDups(Collection<E> c) { return new LinkedHashSet<E>(c). left. and returns a Boolean indicating whether the element was added. Here's a program that takes the words in its argument list and prints out any duplicate words. the remove method removes the specified element from the Set if it's present and returns a Boolean indicating whether the element was present. If either the variables used to store a collection or the parameters used to pass it around are declared to be of the collection's implementation type rather than its interface type. for (String a : args) { if (!s. the number of distinct words.*. rather than by its implementation type (HashSet). } } System. Similarly. public class FindDups { public static void main(String args[]) { Set<String> s = new HashSet<String>().

the set difference of s1 . If you want the program to print the word list in alphabetical order. The resulting idioms follow: Set<Type> union = new HashSet<Type>(s1). or set difference of two sets nondestructively (without modifying either set). 369 . i.) s1. Making this trivial one-line change causes the command line in the previous example to generate the following output: java FindDups i came i saw i left Duplicate word: i Duplicate word: i 4 distinct words: [came. The implementation type of the Set in the preceding example is HashSet. Suppose s1 and s2 are Sets. The implementation type of the result Set in the preceding idioms is HashSet.s2 is the set containing all the elements found in s1 but not in s2.) s1. which makes no guarantees as to the order of the elements in the Set.removeAll(s2). merely change the set's implementation type from HashSet to TreeSet. intersection. left.retainAll(s2): Transforms s1 into the intersection of s1 and s2.) s1. (The intersection of two sets is the set containing only the elements that are common to both sets.retainAll(s2). However.removeAll(s2): Transforms s1 into the (asymmetric) set difference of s1 and s2.) To calculate the union. difference. the best all-around Set implementation in the Java platform. Set<Type> difference = new HashSet<Type>(s1). Set<Type> intersection = new HashSet<Type>(s1).addAll(s2): Transforms s1 into the union of s1 and s2.containsAll(s2): Returns true if s2 is a subset of s1. as already mentioned. (For example. Here's what the bulk operations do: • • • • s1. union. the caller must copy one set before calling the appropriate bulk operation. which is. (The union of two sets is the set containing all the elements contained in either set. any general-purpose Set implementation could be substituted. saw] Set Interface Bulk Operations The bulk operations are particularly well suited to Sets. when applied to sets.addAll(s2). intersection. Referring to collections only by their interface prevents you from using any nonstandard operations.not in the new one. they perform standard set-algebraic operations. (s2 is a subset of s1 if set s1 contains all the elements in s2. the program will fail.

which we know how to compute. } // Destructive set-difference uniques. Suppose that you want to know which words in the argument list occur only once and which occur more than once but that you do not want any duplicates printed out repeatedly.out. Here's how the resulting program looks: import java.add(a). tmp. came] Duplicate words: [i] A less common set-algebraic operation is the symmetric set difference: the set of elements contained in either of two specified sets but not in both. for (String a : args) { if (!uniques.addAll(s2). the program yields the output: Unique words: [left. System. Set<String> dups = new HashSet<String>(). Set Implementations 370 .removeAll(dups).Let's revisit the FindDups program. Set<Type> tmp = new HashSet<Type>(s1). } } } When run with the same same argument list used earlier (i came i saw i left). one containing every word in the argument list and the other containing only the duplicates.println("Unique words: " + uniques).util. The words that occur only once are the set difference of these two sets.removeAll(tmp). The following code calculates the symmetric set difference of two sets nondestructively: Set<Type> symmetricDiff = new HashSet<Type>(s1).println("Duplicate words: " + dups). System.out. symmetricDiff. This effect can be achieved by generating two sets. saw. symmetricDiff.retainAll(s2)). Set Interface Array Operations The array operations don't do anything special for Sets beyond what they do for any other Collection.*.add(a)) { dups. public class FindDups2 { public static void main(String args[]) { Set<String> uniques = new HashSet<String>().

hs.F] 16. the List interface includes operations for the following: 371 .add(“D”).util. } } The output from this program is shown here: [A. } } The LinkedHashSet extends HashSet and maintains a linked list of entries in the set in the order in which they were inserted. import java. ts.add(“C”). An example of TreeSet is shown below: import java. An example of using HashSet. hs. Access and retrieval times are quite fast which makes TreeSet an excellent choice when storing large amounts of sorted information that must be found quickly. TreeSet stores objects in ascending order.add(“C”). hs.add(“F”).println(hs).out. ts. ts.D.C. hs.add(“B”). class HashSetDemo { public static void main(String args[]) { //create a hash set HashSet hs = new HashSet().add(“A”).util.println(ts).add(“A”).add(“E”). hs. System.add(“B”). In addition to the operations inherited from Collection. Lists may contain duplicate elements.HashSet extends AbstractSet and implements the Set interface.add(“D”). System. class TreeSetDemo { public static void main(String args[]) { TreeSet ts = new TreeSet(). It creates a collection that uses a hash table for storage.B.*. ts.7 The List Interface A List is an ordered Collection (sometimes called a sequence).add(“E”). ts.out.E. ts.*.

which is generally the better-performing implementation. Comparison to Vector If you've used Vector. Consider this assignment statement: gift[5] = "golden rings".times(v. Search: Search for a specified object in the list and return its numerical position. i). you're already familiar with the general flavor of List. The List equivalent is: v. The Java platform contains two general-purpose List implementations. When you consider that these two operations are the List analogue of square brackets for arrays. Vector has been retrofitted to implement List. the method add(int. You may already have noticed that the set method. E).times(v.• • • • Positional Access: Manipulate elements based on their numerical position in the list.get(k))). have been given much shorter names. For consistency's sake. int). Range-view: Perform arbitrary range operations on the list.elementAt(j). Commonly used Vector operations such as elementAt and setElementAt. which replaces the Vector method setElementAt. List Iteration: Extend Iterator semantics to take advantage of the list's sequential nature.times(a[k]). The Vector equivalent is: v.setElementAt("golden rings". it becomes apparent that shorter names are highly desirable. 372 . 5).get(j). v. List fixes several minor API deficiencies in Vector.setElementAt(v. "golden rings"). Also. ArrayList. The List equivalent is: gift. and LinkedList which offers better performance under certain circumstances.elementAt(k)). also reverses the order of the arguments. The Vector equivalent is: gift. reverses the order of the arguments so that they match the corresponding array operation. Consider the following assignment statement: a[i] = a[j]. which replaces insertElementAt(Object.set(5.set(i.

Here's a non-destructive form of this idiom. Positional Access and Search Operations The basic positional access operations (get. takes advantage of ArrayList's standard conversion constructor.set(j. lastIndexOf(setSize) have been replaced by a single range-view operation (subList). The remove operation always removes the first occurrence of the specified element from the list. a. The set and remove operations return the old value that is being overwritten or removed. } 373 . Two List objects are equal if they contain the same elements in the same order. The addAll operation inserts all of the elements of the specified Collection starting at the specified position.addAll(list2). The elements are inserted in the order they are returned by the specified Collection's iterator.get(i). int i.The various range operations in Vector (indexOf.get(j)).addAll(list2). Thus. set. assuming you're already familiar with them from Collection. Collection Operations The operations inherited from Collection all do about what you'd expect them to do. tmp). Here's a little method to swap two indexed values in a List: public static <E> void swap(List<E> a. add and remove) behave just like their longernamed counterparts in Vector (elementAt. insertElementAt and removeElementAt) with one noteworthy exception. int j) { E tmp = a. a. List strengthens the requirements on the equals and hashCode methods so that two List objects can be compared for logical equality without regard to their implementation classes.set(i. This call is the positional access analogue of Collection's addAll operation. Like the Set interface. the Vector counterparts (setElementAt and removeElementAt) return nothing (void). Note that the idiom. which produces a third List consisting of the second list appended to the first: List<Type> list3 = new ArrayList<Type>(list1). setElementAt. which is far more powerful and consistent. a. list3. the following idiom concatenates one list to another: list1. The search operations indexOf and lastIndexOf behave exactly like the identically named operations in Vector. The add and addAll operations always append the new element(s) to the end of the list. in its non-destructive form.

regardless of its implementation type. repeatedly swapping a randomly selected element into the current position. Collections.util.out. The resulting List is not a general-purpose List implementation.Of course there's one big difference. i . for (String a : args) { list. rnd.shuffle(list). randomly permutes the specified List using the specified source of randomness. Taking advantage of Arrays. } This algorithm.nextInt(i)). System. The Arrays class has a static factory method called asList that allows an array to be viewed as a List. public class Shuffle { public static void main(String args[]) { List<String> list = new ArrayList<String>().util. Unlike most naive attempts at shuffling.*.out. } Collections. public class Shuffle { public static void main(String args[]) { List<String> list = Arrays. in that it doesn't implement the (optional) add and remove operations: Arrays are not resizable. and vice-versa. Changes in the List write through to the array. } } An example that demonstrates the use of various algorithms 374 . The following program uses this algorithm to print the words in its argument list in random order: import java.println(list). Random rnd) { for (int i = list.asList and calling the library version of shuffle that uses a default source of randomness. you get the following tiny program. i > 1. new Random()). Here's another polymorphic algorithm that uses the swap method above: public static void shuffle(List<?> list.shuffle(list.println(list).*. it's fair (all permutations occur with equal likelihood.asList(args). assuming an unbiased source of randomness) and fast (requiring exactly list.size()-1 swaps). } } We can make this program even shorter and faster. This method does not copy the array. It's a bit subtle: It runs up the list from the bottom. i--) swap(list.size(). This is a polymorphic algorithm: It swaps two elements in any List. whose behavior is identical to the previous program: import java.1. which is included in the Java platform's Collections class.add(a). System.

*.hasNext()) { System.iterator().println().import java.print(“Sorted:”). System. display(array).print(li. al. i++) { array[i] = -3 * i. } //display.out. Collections. //create a reverse order Comparator Comparator r = Collections.add(new Integer(-20)).out. i< 10. //display randomized list itr = al.min(al)).print(“Original contents:”).add(new Integer(20)). sort and display System.out.add(new Integer(8)). class ArraysDemo { public static void main(String args[]) { //allocate and initialize array int array[] =new int[10].add(new Integer(-8)).println(“Minimum:”+Collections.out.println(“List shuffled:”). for(int i=0.println(“List sorted in reverse:”).hasNext()) { System.r).out. } } An example that shows the use of Arrays class import java.sort(array).print(li.out.println(“Maximum:”+Collections. //Sort list using comparator Collections. al. } System.next()+ “ ”). //Get iterator Iterator itr = al.shuffle(al). } System.util.out. class AlgorithmDemo { public static void main(String args[]) { ArrayList al = new ArrayList().iterator(). System. System.max(al)). 375 .sort(al.out. al.util.out.out.*. System. while(itr. System.println(). display(array). while(itr. Arrays.reverseOrder(). al.next()+ “ ”).

//sort and display Arrays. i.out.print(index).fill(array. Here's the standard idiom for iterating backwards through a list: for (ListIterator<Type> i = list.previous(). that allows you to traverse the list in either direction.-1). The hasPrevious and the previous operations are exact analogues of hasNext and next.length.i<array. display(array).2.6.hasPrevious().out. called a ListIterator. } } The output is as follows: Original contents : 0 –3 –6 –9 –12 –15 –18 –21 –24 –27 Sorted : -27 –24 –21 –18 –15 –12 –9 –6 –3 0 After fill: -27 –24 –1 –1 –1 –1 –9 –6 –3 0 After sorting again: -27 –24 –9 –6 –3 –1 –1 –1 –1 0 The value –9 is at location 2 Iterators The Iterator returned by List's iterator operation returns the elements of the list in proper sequence. 376 . display(array).binarySearch(array.out. and remove) do exactly the same thing in both interfaces.print(“The value –9 is at location:”). The previous operation moves the cursor backwards. List also provides a richer iterator. //binary search for –9 System. } static void display(int array[]) { for(int i= 0 .print(array[i]+ “ ").listIterator(list.print(“After fill:”). System. and obtain the current position of the iterator. The former operations refer to the element before the (implicit) cursor. whereas next moves it forwards. System.out.i++) { System.println().out.//fill and display Arrays. modify the list during iteration. The three methods that ListIterator inherits from Iterator (hasNext. next.size()). int index = Arrays. whereas the latter refer to the element after the cursor.sort(array). } System.print(“After sorting again:”). ) { Type t = i. System.-9).out.

This implies the behavior of the two boundary cases: a call to previousIndex when the cursor is before the initial element returns -1.} . The List interface has two forms of the listIterator method.next()==null : o.next())) { return i. // Object not found } 377 . i. the cursor is always between two elements. The n+1 valid index values correspond to the n+1 gaps between elements. and a call to nextIndex when the cursor is after the final element returns list. from 0 to n. there are n+1 valid values for index. These calls are typically used either to report the position where something was found or to record the position of the ListIterator so that another ListIterator with identical position can be created. The first call to previous returns the same element as the last call to next. the first call to next after a sequence of calls to previous returns the same element as the last call to previous. the one that would be returned by a call to previous and the one that would be returned by a call to next. Intuitively speaking. To make all of this concrete..equals(i..size(). } } return -1. Similarly. The figure below shows the five possible cursor positions in a list containing four elements. The index refers to the element that would be returned by an initial call to next. ) { if (o==null ? i. from the gap before the first element to the gap after the last one. The form with no arguments returns a ListIterator positioned at the beginning of the list. It should also come as no surprise that the number returned by nextIndex is always one greater than the number returned by previousIndex. but you have to be a bit careful.hasNext().previousIndex(). Calls to next and previous can be intermixed. the form with an int argument returns a ListIterator positioned at the specified index. here's a possible implementation of List. and previousIndex returns the index of the element that would be returned by a subsequent call to previous. inclusive. In a list of length n.indexOf: public int indexOf(E o) { for (ListIterator<E> i = listIterator(). Note the argument to listIterator in the preceding idiom. It should come as no surprise that the nextIndex method returns the index of the element that would be returned by a subsequent call to next. An initial call to previous would return the element whose index was index-1.

The set method overwrites the last element returned by next or previous with the specified element. i < toIndex. The ListIterator interface provides two additional operations to modify the list: set and add.){ if (val==null ? i. We have to special-case an val value of null in order to prevent a NullPointerException.next())) { i.remove(). subList(int fromIndex. The following polymorphic algorithm uses set to replace all occurrences of one specified value with another: public static <E> void replace(List<E> s. } } } Range-View Operation The range-view operation..set(newVal).next()==null : val.listIterator(). E val. } } } The only bit of trickiness in this example is the equality test between val and i. The Iterator interface provides the remove operation to remove from the Collection the last element returned by next. i.equals(i.next.add(e).listIterator(). For ListIterator. this operation removes the last element returned by next or previous. E val. This method is illustrated in the following polymorphic algorithm to replace all occurrences of a specified value with the sequence of values contained in the specified list: public static <E> void replace(List<E> s.previousIndex() though it is traversing the list in the forward direction.next())) { i. to toIndex. The reason is that i. inclusive. E newVal) { for (ListIterator<E> i = s. The add method inserts a new element into the list. and we want to return the index of the element that we just examined. i++) { . i.Note that the indexOf method returns i.hasNext(). returns a List view of the portion of this list whose indices range from fromIndex. for (E e : newVals) i. immediately before the current cursor position. int toIndex). List<E> newVals) { for (ListIterator<E> i = s..nextIndex() would return the index of the element that we are about to examine. This half-open range mirrors the typical for loop: for (int i = fromIndex.next()==null : val. exclusive.equals(i. } 378 .hasNext(). ) { if (val==null ? i.

such as ArrayList. works with the List returned by subList.util. Any operation that expects a List can be used as a range operation by passing a subList view instead of a whole List. the returned List is backed by the List on which subList was called.subList(deckSize .subList(fromIndex. it returns a new List (the "hand") containing the specified number of elements taken from the end of the specified List (the "deck"). int j = list.clear(). deckSize). Here's a polymorphic algorithm whose implementation uses subList to deal a hand from a deck. the following idiom removes a range of elements from a list: list. public static <E> List<E> dealHand(List<E> deck. so changes in the former List are reflected in the latter. int cardsPerHand = Integer. For many common List implementations. That is to say. This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). toIndex). Any polymorphic algorithm that operates on a List.size().lastIndexOf(o). such as the replace and shuffle examples above. handView.n.clear(). List<E> handView = deck.subList(fromIndex. return hand. The elements returned in the hand are removed from the deck. List<E> hand = new ArrayList<E>(handView).parseInt(args[0]). 379 . toIndex).parseInt(args[1]). toIndex). the performance of removing elements from the end of the list is substantially better than that of removing elements from the beginning. import java. } Note that this algorithm removes the hand from the end of the deck. class Deal { public static void main(String[] args) { int numHands = Integer. Note that the above idioms return the index of the found element in the subList. For example.subList(fromIndex. not the index in the backing List. int n) { int deckSize = deck. Similar idioms may be constructed to search for an element in a range: int i = list.indexOf(o).*.As the term view implies.shuffle to generate hands from a normal 52-card deck. The program takes two command line arguments: the number of hands to deal and the number of cards in each hand. Here's a program using the dealHand method in combination with Collections.

println(dealHand(deck. i<numHands."queen". 380 ."3"."7".add(rank[j] + " of " + suit[i]). some care must be exercised when using it. ace of hearts] Although the subList operation is extremely powerful. ace of clubs. Note that it is legal to modify a sublist of a sublist and to continue using the original sublist (though not concurrently). jack of hearts."5". king of diamonds] [4 of diamonds. ace of spades. i <suit. jack of spades. for (int i=0. 9 of clubs] [8 of spades. 3 of hearts. it's highly recommended that you use the List returned by subList only as a transient object: to perform one or a sequence of range operations on the backing List. Here's a summary of these algorithms.// Make a normal 52-card deck String[] suit = new String[] {"spades"."2". 4 of spades. } } } Running the program produces the following output: java Deal 4 5 [8 of hearts. queen of hearts] [7 of spades. The longer you use the sublist instance. i++) { System. Thus.length. j <rank. queen of diamonds."6". List Algorithms Most of the polymorphic algorithms in the Collections class apply specifically to List. cardsPerHand)).length. j++) { deck. for (int i = 0."8"."jack". "9". 6 of clubs. "hearts". 5 of spades.out. List<String> deck = new ArrayList<String>(). 2 of diamonds. } } Collections."10". the greater the probability that you'll compromise it by modifying the backing List directly or through another sublist object. i++) { for (int j = 0. String[] rank = new String[] {"ace". "clubs"}."king"}.shuffle(deck). The semantics of the List returned by subList become undefined if elements are added to or removed from the backing List in any way other than via the returned List. Having all these algorithms at your disposal makes it very easy to manipulate lists. 3 of spades. 6 of diamonds."4". "diamonds".

order elements in a FIFO (first-in-first-out) manner. but not necessarily. rotate: Rotates all of the elements in a List by a specified distance. Other kinds of queues may use different placement rules. 381 . which provides a fast. The offer method. copy: Copies the source List into the destination List.           sort: Sorts a List using a merge sort algorithm. replaceAll: Replaces all occurrences of one specified value with another. fill: Overwrites every element in a List with the specified value. and inspection operations. Every Queue implementation must specify its ordering properties. removal. queues provide additional insertion. The regular structure of the interface is illustrated in the following table: Queue Interface Structure Throws exception Returns special value add(e) Insert Remove remove() Examine element() offer(e) poll() peek() Queues typically. which is intended solely for use on bounded queues. all new elements are inserted at the tail of the queue. swap: Swaps the elements at specified positions in in a List. Among the exceptions are priority queues. Besides basic Collection operations. Each Queue method exists in two forms: one throws an exception if the operation fails. indexOfSubList: Returns the index of the first sublist of one List that is equal to another. In a FIFO queue. 16. The add method. depending on the operation).8 The Queue Interface A Queue is a collection for holding elements prior to processing.) shuffle: Randomly permutes the elements in a List. Whatever ordering is used. (A stable sort is one that does not reorder equal elements. the head of the queue is the element that would be removed by a call to remove or poll. in which case it throws IllegalStateExcepion. the other returns a special value (either null or false. which order elements according to a their values. differs from add only in that it indicates failure to insert an element by returning false. which Queue inherits from Collection. reverse: Reverses the order of the elements in a List. lastIndexOfSubList: Returns the index of the last sublist of one List that is equal to another. stable sort. inserts an element unless it would violate the queue's capacity restrictions. binarySearch: Searches for an element in an ordered List using the binary search algorithm.

remove()). while(!queue.sleep(1000). The remove and poll methods differ in their behavior only when the queue is empty. Under these circumstances. a priority queue is used to sort a collection of elements. The LinkedList implementation (which was retrofitted to implement Queue) is an exception.add(i). element throws NoSuchElementException while peek returns false. For historical reasons. but you should refrain from taking advantage of this. Then the values are removed from the queue and printed at one second intervals. but it illustrates the behavior of priority queues: static <E> List<E> heapSort(Collection<E> c) { Queue<E> queue = new PriorityQueue<E>(c).isEmpty()) { System.*. as null is used as a special return value by the poll and peek methods.out. Exactly which element gets removed is a function of the queue's ordering policy. List<E> result = new ArrayList<E>(). The program is artificial in that it would be more natural to do the same thing without using a queue. i--) queue. 382 .isEmpty()) result. i >= 0. In the following example program.util. Queue implementations generally do not allow insertion of null elements. but it illustrates the use of a queue to store elements prior to subsequent processing: import java. The queue is preloaded with all the integer values from a number specified on the command line to zero. while poll returns null. Queue<Integer> queue = new LinkedList<Integer>(). The element and peek methods return.add(queue. in that there is no reason to use it in favor of the sort method provided in Collections. but do not remove. while (!queue. it permits null elements. } } } In the following example. in descending order. a queue is used to implement a countdown timer. Again this program is artificial. public class Countdown { public static void main(String[] args) throws InterruptedException { int time = Integer.parseInt(args[0]). Thread.println(queue. remove throws NoSuchElementException. They differ from one another in precisely the same fashion as remove and poll: if the queue is empty.remove()).The remove and poll methods both remove and return the head of the queue. Queue implementations generally do not define element-based versions of the equals and hashCode methods but instead inherit the identity-based versions from Object. the head of the queue. for (int i = time.

println(“ll after deleting first and last:”+ ll).out.removeLast().removeFirst(). System.D] change: [B.remove(“F”). “A2”).out.println(“ll after change:” + ll).B. The following program illustrates several methods supported by LinkedList.remove(2). //add elements to linked list ll.E] of ll after deletion: [A.addLast(“E”).get(1). //remove elements from linked list ll. System.addFirst(“F”).add(“C”). ll. ll.D.set(1. //remove first and last elements ll.println(“Contents of ll after deletion:” + ll).add(“A”). 383 .out.out. System.Dchanged] 16.add(“D”). System. } } The output of this program is shown here Original Contents ll after ll after contents of ll : [F. import java. ll.A. ll.E] deleting first and last: [B. ll. ll.*.D.B. ll.C.println(“Original contents of ll:”+ll). ll.util. ll. A map cannot contain duplicate keys: Each key can map to at most one value.(String)val+ “changed”).add(“B”).} return result.add(1. //get and set value Object val = ll.9 The Map Interface A Map is an object that maps keys to values. class LinkedListDemo { public static void main(String args[]) { //create a linked list LinkedList ll = new LinkedList().

The frequency table maps each word to the number of times it occurs in the argument list. Given its name.println(m. Integer>(). Map fixes a minor deficiency in the Hashtable interface. Map allows you to iterate over keys. you're already familiar with the general flavor of Map.out. values. Also.put(a. Also. Map provides a safe way to remove entries in the midst of iteration. m. Hashtable was retrofitted to implement Map. System. (Of course Map is an interface. which returns true if the Hashtable contains a given value. Comparison to Hashtable If you've used Hashtable. as the key is the primary access mechanism for a Hashtable. size.out. Here's a program to generate a frequency table of the words found in its argument list.util. (freq == null ? 1 : freq + 1)). Map Finally.get(a). Collection views greatly enhance the expressiveness of the interface. you'd expect this method to return true if the Hashtable contained a given key. while Hashtable is a concrete implementation. Hashtable does not provide the third option. containsValue. } } The only thing tricky about this program is the second argument of the put statement. and isEmpty) behave exactly like their counterparts in Hashtable. TreeMap. and LinkedHashMap. That argument is a conditional expression that has the effect of setting the frequency to one if the 384 . The Map interface eliminates this source of confusion by renaming the method containsValue. and LinkedHashMap. this improves the consistency of the interface: containsValue parallels containsKey. Integer> m = new HashMap<String. TreeMap. Map Interface Basic Operations The basic operations (put. containsKey. Hashtable did not. Their behavior and performance are precisely analogous to HashMap. } System. get. public class Freq { public static void main(String args[]) { Map<String.size() + " distinct words:"). Hashtable has a method called contains.println(m).*.) Here are the major differences: • • • provides Collection views instead of direct support for iteration via Enumeration objects.The Java platform contains three general-purpose Map implementations: HashMap. import java. // Initialize frequency table from command line for (String a : args) { Integer freq = m. or key-value pairs.

For example. 385 . The following one-liner creates a new HashMap initially containing all of the same key-value mappings as m: Map<K. it has a second. me=1. you could make the program print the frequency table in the order the words first appear on the command line simply by changing the implementation type of the map to LinkedHashMap. delegate=1. In addition to its obvious use of dumping one Map into another. it=2. Like the Set and List interfaces. me=1. delegate=1. is=2. it=2. is=2. V>(m). regardless of the other Map's implementation type. to=3. Try running this program with the command: java Freq if it is to be it is up to me to delegate The program yields the following output: 8 distinct words: {to=3. Making this fourcharacter change causes the program to generate the following output from the same command line: 8 distinct words: {be=1. if=1. Two Map instances are equal if they represent the same key-value mappings. The putAll operation is the Map analogue of the Collection interface's addAll operation. All you have to do is change the implementation type of the Map from HashMap to TreeMap. delegate=1} This flexibility provides a potent illustration of the power of an interface-based framework. if=1. Doing so results in the following output: 8 distinct words: {if=1. to=3. suppose you have a Map. it=2. all Map implementations provide constructors that take a Map object and initialize the new Map to contain all the key-value mappings in the specified Map. be=1. be=1.word has never been seen before or one more than its current value if the word has already been seen. is=2} Suppose you'd prefer to see the frequency table in alphabetical order. This standard Map conversion constructor is entirely analogous to the standard Collection constructor: It allows the caller to create a Map of a desired implementation type that initially contains all of the mappings in another Map. up=1. more subtle use. By convention. V> copy = new HashMap<K. named m. up=1. me=1. Map Interface Bulk Operations The clear operation does exactly what you think it does: it removes all the mappings from the Map. Map strengthens the requirements on the equals and hashCode methods so that two Map objects can be compared for logical equality without regard to their implementation types. up=1} Similarly.

in combination with the Map conversion constructor. result. and with an iterator: // Filter a map based on some property of its keys for (Iterator<Type> i=m. V> newAttributeMap( Map<K. (Yet again.keySet(). assuming that the backing map supports element removal to begin with.next(). With all three Collection views. Map<K. V> overrides) { Map<K.putAll(overrides). return result. as well as the Iterator. This Collection is not a Set. V> Map<K.util do. this assumes that the backing Map supports element removal. the putAll operation. and clear operations.remove(). There's no reason that a Map can't always return the same object each time it is asked for a given Collection view. calling an Iterator's remove operation removes the associated entry from the backing Map. as multiple keys can map to the same value.iterator().out. V>(defaults).keySet()) System. retainAll.isBogus()) i.println(key). i. The Collection views support element removal in all its many forms: the remove. The Collection views provide the only means to iterate over a Map.hasNext(). This is precisely what all the Map implementations in java. many people worry that these idioms may be slow because the Map has to create a new Collection instance each time a Collection view operation is called.Suppose a Map is used to represent a collection of attribute-value pairs. At first. V> result = new HashMap<K. Here's a static factory method demonstrating this technique: static <K. provides a neat way to implement attribute map creation with default values. } Collection Views The Collection view methods allow a Map to be viewed as a Collection in these ways:   keySet: the Set of keys contained in the Map. ) if (i. Here's an example illustrating the standard idiom for iterating over the keys in a Map with a for-each construct: for (KeyType key : m. values: The Collection of values contained in the Map.) 386 . removeAll.remove operation. V>defaults.

containsAll(attrs)) { Set<K> illegal = new HashSet<K>(attrs).keySet()).retainAll(m2.removeAll(attrs). commonKeys. if(!attrs. and two sets representing required attributes and permissible attributes. } return valid.keySet(). (The permissible attributes include the required attributes.The Collection views do not support element addition under any circumstances. Set<K> attrs = attrMap.containsAll(requiredAttrs)) { Set<K> missing = new HashSet<K>(requiredAttrs). V> boolean validate(Map<K. Set<K> requiredAttrs. System. Suppose that you want to remove all the key-value pairs that one Map has in common with another: 387 .println("Illegal attributes: " + illegal).. Here are a few that do. valid = false.. Fancy Uses of Collection Views: Map Algebra When applied to the Collection views. System. and it's unnecessary for the entrySet view.keySet())) { . that is. V> attrMap.out. A similar idiom gets you the common values. It would make no sense for the keySet and values views. illegal.keySet). don't modify the backing Map. Set<K>permittedAttrs) { boolean valid = true. removeAll and retainAll) are a surprisingly potent tool.equals(m2. missing.removeAll(permittedAttrs). } Suppose that you want to know all the keys common to two Map objects: Set<KeyType>commonKeys = new HashSet<KeyType>(m1. valid = false. } if (!permittedAttrs. as the backing Map's put and putAll provide the same functionality.keySet(). All the idioms presented thus far have been nondestructive.out.) The following snippet determines whether the attribute map conforms to these constraints and prints a detailed error message if it doesn't: static <K.println("Missing attributes: " + missing). the bulk operations (containsAll. Suppose that you want to know whether two Map objects contain mappings for all the same keys: if (m1. } Suppose you have a map that represents a collection of attribute-value pairs.

16.m1.keySet()).removeAll(Collections.removeAll(managers. a static factory method that returns an immutable Set with the single.entrySet(). represent precisely the employees that we're looking for. Suppose you want to remove from one Map all the keys that have mappings in another: m1. m. then. Set<Employee> slackers = m.singleton. Employee>(managers). managers. The following snippet tells you exactly what you want to know: Set<Employee> individualContributors = new HashSet<Employee>(managers.keySet()).removeAll(m2. Now suppose you want to know who all the "individual contributors" (or nonmanagers) are. specified element. managers. that maps each employee in a company to the employee's manager. Simon: Employee simon = . .removeAll(m2. The following code tells you all of the employees whose manager no longer works for the company: Map<Employee. individualContributors. What happens when you start mixing keys and values in the same bulk operation? Suppose that you have a Map. Thus.10 Object Ordering A List l may be sorted as follows: Collections.values(). Suppose that you want to fire all the employees who report directly to some manager.sort(l).values(). and it removes from the temporary copy all entries whose (manager) value is a key in the original Map. the remaining entries in the temporary Map comprise all the entries from the original Map whose (manager) values are no longer employees..removeAll(managers.keySet().keySet()). The keys in the temporary copy.entrySet()). you may have a bunch of employees whose managers no longer work for the company (if any of Simon's direct-reports were themselves managers). 388 . We'll be deliberately vague about the types of the key and the value objects. Employee> m = new HashMap<Employee. This example is a bit tricky.values()).. It doesn't matter. so long as they're the same. Once you've done this. First.keySet(). it makes a temporary copy of the Map.singleton(simon)). Note that this idiom makes use of Collections. Remember that the original Map has an entry for each employee.

none of classes listed here permit interclass comparison. or a positive integer as the receiving object is less than. The compareTo method compares the receiving object with the specified object and returns a negative integer. BigDecimal Boolean File String Date CollationKey Natural Ordering UnSigned numerical Signed numerical Boolean. which allows objects of that class to be sorted automatically. it will be sorted into chronological order. Integer.FALSE < Boolean. If the specified object cannot be compared to the receiving object. Collections. zero. Float. lastName.TRUE System-dependent lexicographic on path name Lexicographic Chronological Locale-specific lexicographic If you try to sort a list whose elements do not implement Comparable.sort will throw a ClassCastException. Elements that can be compared to one another are called mutually comparable. If it consists of Date elements. The Comparable interfaces provides a natural ordering for a class. Collections. The following class representing a person's name implements Comparable: import java. Short. BigInteger. Double.util. public final class Name implements Comparable<Name> { private final String firstName. it will be sorted into alphabetical order. Although elements of different types be mutually comparable. Writing Your Own Comparable Types The Comparable interface consists of a single method: public int compareTo(T o). equal to. This is all you really need to know about the Comparable interface if you just want to sort lists of comparable elements or to create sorted collections of them.sort(list) will throw a ClassCastException . 389 . The following table summarizes some of the more important Java platform classes that implement Comparable: Classes Implementing Comparable Class Character Byte. if you try to sort a list whose elements cannot be compared to one another. Long.*. How does this happen? String and Date both implement the Comparable interface. or greater than the specified object.If the list consists of String elements. Similarly. the method throws a ClassCastException.

lastName = lastName. the class is somewhat limited: It doesn't support middle names.equals(lastName). Name 390 . especially for objects that will be used as elements in Sets. return n. This is essential for any class that redefines the equals method.equals(firstName) && n. } public String firstName() { return firstName. The constructor checks its arguments for null. or as keys in Maps. Nonetheless. Name n = (Name) o.public Name(String firstName. so that none of the other methods will ever throw a NullPointerException. return (lastCmp != 0 ? lastCmp : firstName. it illustrates several important points: • • • • objects are immutable.lastName). it demands both a first and a last name.firstName = firstName. } public boolean equals(Object o) { if (!(o instanceof Name)) return false.compareTo(n. } public int compareTo(Name n) { int lastCmp = lastName. The hashCode method is redefined.) The equals method returns false if the specified object is null. String lastName) { if (firstName == null || lastName == null) { throw new NullPointerException().firstName)). and it is not internationalized in any way. or of an inappropriate type. } } To keep the example short. } public String toString() { return firstName + " " + lastName. All other things being equal. The compareTo method throws a runtime exception under these circumstances. } public int hashCode() { return 31*firstName.lastName. (Equal objects must have equal hash codes.compareTo(n.hashCode() + lastName.firstName.hashCode(). Both of these behaviors are required by the general contracts of the respective methods. These collections will break if you modify their elements or keys while they're in the collection. this. } this. immutable types are the way to go. This ensures that all Name objects are well formed. } public String lastName() { return lastName.

where last names take precedence over first names. Just to show that it all works. "Marx"). This is always a good idea. This is exactly what you want in a natural ordering. because it's quite typical.asList(nameArray). Since this section is about element ordering. It would be very confusing if the natural ordering were unnatural! Take a look at how compareTo is implemented. the last name). If there were more parts. 391 . John Lennon. Collections. The various collection types' toString methods depend on the toString methods of their elements. Attempting to sort a list of objects that violate these restrictions has undefined behavior. In this case.println(names). In this case. the part is a String. "Grouch") }. "Marx"). System. there are only two parts: first name and last name. new Name("Groucho". If the most significant parts are equal.• The toString method has been redefined to print the Name in human-readable form. Technically speaking. which we won't go over now because they're fairly technical and boring and are better left in the API documentation. let's talk a bit more about Name's compareTo method. Groucho Marx. } } If you run this program. and the natural (lexicographic) ordering is exactly what's called for. new Name("Oscar". at which point you'd return the result of the comparison. It implements the standard name-ordering algorithm. keys and values. "Lennon"). here's what it prints: [Oscar Grouch. these restrictions ensure that the natural ordering is a total order on the objects of a class that implements it. so read the documentation for Comparable if you're writing a class that implements it. this is necessary to ensure that sorting is well-defined. First. you'd proceed in the obvious fashion. List<Name> names = Arrays. new Name("Karl". It's really important that all classes that implement Comparable obey these restrictions.util. Karl Marx] There are four restrictions on the behavior of the compareTo method.out. you compare the most significant part of the object (in this case.sort(names). you go on to compare the next-most-significant parts. which represents equality. you can just use the natural ordering of the part's type. public static void main(String[] args) { Name nameArray[] = { new Name("John". If the comparison results in anything other than zero. here's a program that builds a list of names and sorts them: import java. you're done: you just return the result.*. comparing parts until you found two that weren't equal or you were comparing the least-significant parts. Often. especially for objects that are going to get put into collections.

the compare method throws a ClassCastException.Comparators What if you want to sort some objects in an order other than their natural order? Or what if you want to sort some objects that don't implement Comparable? To do either of these things. The compare method compares its two arguments.compareTo(e1. equal to. public int number() { . // Employee Database static final Collection<Employee> employees = . you'll need to provide a Comparator.. returning a negative integer. the boss has asked us for a list of employees in order of seniority.. class EmpSort { static final Comparator<Employee> SENIORITY_ORDER = new Comparator<Employee>() { public int compare(Employee e1. Much of what was said about Comparable applies to Comparator as well. This means that we have to do some work. Suppose that you have a class called Employee: public class Employee implements public Name name() { . T o2).. . an object that encapsulates an ordering. Unfortunately.....util. public static void main(String[] args) { 392 .. except that the former gets both objects passed in as arguments. If either of the arguments has an inappropriate type for the Comparator. Here's a program that will produce the required list: import java. or a positive integer as the first argument is less than. zero. Like the Comparable interface.. but not much. or greater than the second. . the Comparator interface consists of a single method: int compare(T o1. for the same reason: a Comparator must induce a total order on the objects it compares.hireDate()).hireDate(). Employee e2) { return e2. public Date hireDate() { .. Writing a compare method is nearly identical to writing a compareTo method. } }. The compare method has to obey the same four technical restrictions as Comparable's compareTo method. } Comparable<Employee> { } } } Let's assume that the natural ordering of Employee instances is Name ordering (as defined in the previous example) on employee name.*.

This means that this comparator equates objects that the equals method does not. it's fatal. tweak it so that the only elements that are seen as equal when using compare are those that are also seen as equal when compared using equals. It relies on the natural ordering of Date applied to the values returned by the hireDate accessor method. if (dateCmp != 0) return dateCmp. the hire date). 393 . Collections. There is one negative int that remains negative when negated.MIN_VALUE == Integer.compareTo(e1. as the latter is not guaranteed to work! The reason for this is that the compareTo method can return any negative int if its argument is less than the object on which it is invoked.println(e). but when you're using the Comparator to order a sorted collection. Note that the Comparator passes the hire date of its second argument to its first. SENIORITY_ORDER). Here's the Comparator that results: static final Comparator<Employee> SENIORITY_ORDER = new Comparator<Employee>() { public int compare(Employee e1. If you use this Comparator to insert multiple employees hired on the same date into a TreeSet. Another technique that people sometimes use to achieve this effect is to maintain the argument order but to negate the result of the comparison: //Don't do this!! return -r1. The way to do this is to do a two-part comparison (as we did for Name). In particular.hireDate()). because it generates an ordering that is not compatible with equals. The Comparator in the program is reasonably straightforward. Employee e2) { int dateCmp = e2. return (e1. Strange as it may seem. but it does have one deficiency: it cannot be used to order a sorted collection.number() ? 0 : 1)). only the first one will be added to the set. where the first part is the one that we're interested in (in this case. this doesn't matter. such as TreeSet.compareTo(r2. To fix this problem.number() ? -1 : (e1.number() < e2.number() == e2. rather than vice versa.hireDate().MIN_VALUE The Comparator in the preceding program works fine for sorting a List. The reason is that the employee who was hired most recently is least senior: sorting in order of hire date would put the list in reverse seniority order. -Integer. the employee number is the obvious attribute.out. System. The second will be seen as a duplicate element and will be ignored. You should always use the former technique in favor of the latter.sort(e. any two employees who were hired on the same date will compare as equal.} } List<Employee>e = new ArrayList<Employee>(employees). simply tweak the Comparator so that it produces an ordering that is compatible with equals.hireDate(). In other words. When you're sorting a List. and the second part is an attribute that uniquely identifies the object. In this case.hireDate()).

Don't do it unless you're absolutely sure that no one will ever have a negative employee number! This trick does not work in general. bstr = (String)b.util.iterator(). //add elements to tree set ts. astr = (String)a. ts. An example of using Comparator: import java. //A reverse comparator for Strings class MyComp implements Comparator { public int compare(Object a. System. //Get an iterator Iterator i = ts.add(“B”). ts.bstr. ts. as the signed integer type is not big enough to represent the difference of two arbitrary signed integers. ts. ts.empNumber(). } //no need to override equals } class CompDemo { public static void main(String args[]) { //create a tree set TreeSet ts = new TreeSet(new MyComp()). The resulting comparator violates one of the four technical restrictions that we keep talking about (transitivity) and produces horrible.}.r2. } One last note: You might be tempted to replace the final return statement in the Comparator with the simpler: return r1.hasNext()) { Object element = i.add(“F”). i . This is not a purely theoretical concern. If i is a large positive integer and j is a large negative integer.compareTo(astr).add(“E”). //reverse comparison return bstr.println(element + “ ”).next(). people get burned by it.add(“C”). } 394 .empNumber() .*.add(“D”).j will overflow and will return a negative integer.out. Object b) { String astr. //display elements while(i. subtle bugs.add(“A”).

the SortedSet interface provides operations for: • • • Range view: Allows arbitrary range operations on the sorted set. not its runtime type. it returns a set that sorts its elements according to their natural order.} } System. Set Operations The operations that SortedSet inherits from Set behave identically on sorted sets and normal sets with two exceptions: • The Iterator returned by the iterator operation traverses the sorted set in The array returned by toArray contains the sorted set's elements in order. Comparator access: Returns the Comparator. in order. If null is passed to this constructor. and if so. the toString method of the Java platform's SortedSet implementations returns a string containing all the elements of the sorted set. order. if any. It would have been better to check dynamically if the specified collection were a SortedSet instance. In TreeSet. Note that it is the compile-time type of the argument.println(). Endpoints: Returns the first or last element in the sorted set. As the following output shows.out. sorted according to the elements' natural order or according to a Comparator provided at SortedSet creation time. SortedSet implementations also provide by convention a constructor that takes a Comparator and returns an empty set sorted according to the specified Comparator. this constructor creates an instance that sorts its elements according to their natural order. that determines which of these two constructors is invoked (and whether the sorting criterion is preserved). In addition to the normal Set operations. all general-purpose Collection implementations provide a standard conversion constructor that takes a Collection. SortedSet implementations are no exception. 395 . it also provides a constructor that takes a SortedSet and returns a new TreeSet containing the same elements sorted according to the same criterion. • Although the interface doesn't guarantee it.11 The SortedSet Interface A SortedSet is a Set that maintains its elements in ascending order. the tree is now sorted in the reverse order F E D C B A 16. Standard Constructors By convention. used to sort the set. Because TreeSet took the approach that it did. to sort the new TreeSet according to the same criterion (comparator or natural ordering).

A range view of a sorted set is really just a window onto whatever portion of the set lies in the designated part of the element space.println(from + ": " + dictionary. } Suppose that you want to view a closed interval. Sorted sets provide three range-view operations. the endpoints are objects and must be comparable to the elements in the sorted set. Changes to the range view write back to the backing sorted set. Range views of a sorted set remain valid even if the backing sorted set is modified directly. ch <= 'z'.size(). Thus. using the set's Comparator or the natural ordering of its elements.valueOf(ch). The first." are contained in a SortedSet of strings called dictionary: int count = dictionary. If the element type allows for the calculation of the successor of a given value in the element space.clear(). System.subSet("doorbell". the following one-liner tells you how many words between "doorbell" and "pickle. the following one of code tells you how many words between "doorbell" and "pickle. unlike range views on lists. A similar trick can be used to print a table telling you how many words begin with each letter: for (char ch = 'a'.subSet("doorbell".out. Rather than indices. the successor of a string s in String's natural ordering is s + "\0" (that is. and vice versa. but there is one big difference. it's okay to use range views on sorted sets for long periods of time. Thus.subSet("f".Range-View Operations The range-view operations are somewhat analogous to those provided by the List interface." including "doorbell" and "pickle. "pickle\0"). "g"). the range is half open. subSet. Similarly. s with a null character appended). Although it isn't entirely obvious." including "doorbell" but excluding "pickle. including its low endpoint but excluding the high one. whichever the set uses to order itself. Thus. String to = String. takes two endpoints. as is the case for lists.size(). like subList. ) { String from = String. Like subList. merely request the subSet from lowEndpoint to successor(highEndpoint). "pickle"). which contains both of its endpoints.size()). to)." are contained in the dictionary: count = dictionary. instead of an open interval. This is feasible because the endpoints of a range view of a sorted set are absolute points in the element space rather than specific elements in the backing collection. 396 .valueOf(ch++).subSet(from. the following one-liner removes all the elements beginning with the letter "f": dictionary.

the following code allows you to view the dictionary as two disjoint "volumes" (a — m and n — z): SortedSet<String> volume1 = dictionary.size(). headSet and tailSet. or null if the set is sorted according to the natural order of its elements. beginning with the specified object and continuing to the end of the backing SortedSet. both of which take a single Object argument. which contains neither endpoint." excluding both: count = dictionary. but this is very inefficient. The former returns a view of the initial portion of the backing SortedSet. "pickle"). The following idiom obtains the first element that is less than a specified object o in the elementspace: Object predecessor = ss. It is used by the SortedSet constructor. called (not surprisingly) first and last. Comparator Accessor The SortedSet interface contains an accessor method called comparator that returns the Comparator used to sort the set. One thing you'd like to do with a SortedSet is to go into the interior of the set and iterate forward or backward. This is a fine way to go one element backward from a point in the interior of a sorted set.A similar technique can be used to view an open interval.headSet("n"). The open-interval view from lowEndpoint to highEndpoint is the half-open interval from successor(lowEndpoint) to highEndpoint. SortedSet<String>> volume2 = dictionary. requiring a lookup for each element returned.subSet("doorbell\0". Endpoint Operations The SortedSet interface contains operations to return the first and last elements in the sorted set. Unfortunately. up to but not including the specified object. It could be applied repeatedly to iterate backward.headSet(o). The SortedSet interface contains two more range-view operations. there's no easy way to go backwards. last allows a workaround for a deficiency in the SortedSet interface. 397 .last(). To calculate the number of words between "doorbell" and "pickle. The latter returns a view of the final portion of the backing SortedSet. It's easy enough to go forward from the interior: Just get a tailSet and iterate over it.tailSet("n"). This method is provided so that sorted sets can be copied into new sorted sets with the same ordering. Thus. In addition to their obvious uses.

SortedMap implementations are no exception. Note that it is the compile-time type of the argument.13 Relationships Among Generics You might expect that a Stack<Object> is a supertype of a Stack<String>. if any. 16. used to sort the map.12 The SortedMap Interface A SortedMap is a Map that maintains its entries in ascending order.16. The 398 . this constructor creates an instance that orders its entries according to their keys' natural order. Comparator access: Returns the Comparator. to sort the new map according to the same criterion (comparator or natural ordering). The Map interface provides operations for the normal Map operations and for: • • • Range view: Performs arbitrary range operations on the sorted map. the toString method of the Collection views in all the Java platform's SortedMap implementations returns a string containing all the elements of the view. in order. sorted according to the keys' natural order. In TreeMap. Map Operations The operations that SortedMap inherits from Map behave identically on sorted maps and normal maps with two exceptions: • • The Iterator returned by the iterator operation on any of the sorted map's Collection views traverse the collections in order. The arrays returned by the Collection views' toArray operations contain the keys. no such relationship exists for instantiations of generic types. because Object is a supertype of String. values. and if so. Standard Constructors By convention. It would have been better to check dynamically if the specified Map instance were a SortedMap. all general-purpose Map implementations provide a standard conversion constructor that takes a Map. If null is passed to this constructor. Although it isn't guaranteed by the interface. Because TreeMap took the approach that it did. that determines whether the SortedMap constructor is invoked in preference to the ordinary map constructor. or according to a Comparator provided at SortedMap creation time. In fact. it returns a set that sorts its mappings according to their keys' natural order. not its runtime type. or entries in order. Endpoints: Returns the first or the last key in the sorted map. it also provides a constructor that takes a SortedMap and returns a new TreeMap containing the same mappings as the given SortedMap. SortedMap implementations also provide by convention a constructor that takes a Comparator and returns an empty map sorted according to the specified Comparator. sorted according to the same criterion.

printall(list).println(o). } } List<Object> list = new ArrayList<Object>().out. . //error If you try this you will notice that the last statement produces a compilation error. Since ArrayList<String> is not subtype of Collection<Object> it cannot be passed as argument to the print method even though the two types are instantiations of the same generic type with type arguments related by inheritance. . List<Object> 16.14 Wildcard Types To get around the puzzle posed by the first version of the printAll method you can specify that the argument to printAll is a collection whose element type matches anything.out. Suppose you would like to write a method that prints out a collection of objects..println(o).. written as Collection<?>: public void printAll(Collection<?> c) { for (Object o : c) { System. On the other hand. printall(list).. } } You might choose to create a list of strings and use this method to print all the strings: List<String> list = new ArrayList<String>(). //this works is compatible with Collection<Object> because the two types are instantiations of a generic supertype and its subtype and the instantiations are for the same type argument. regardless of the type of objects contained in the collection: public void printAll(Collection<Object> c) { for (Object o : c) { System.println(o). namely Object.lack of a super-subtype relationship among instantiations of a generic type when the type arguments possess a super-subtype relationship can make programming polymorphic methods challenging. } } 399 .out.. instantiations of generic types related by inheritance for the same type argument are compatible: public void printAll(Collection<Object> c) { for (Object o : c) { System.

You can always extract objects from this collection because the returned type is always guaranteed to be Object.15 Defining and Using Generic Methods Not only types can be parameterized. this method has limited usefulness: for example.. The syntax for declaring method type parameters is the same as the syntax for generics. you could express the type parameter of the shape collection as a wildcard. it cannot be called with Collection<Circle>. the wildcard should be bounded by the superclass Shape as follows: void drawAll(Collection<? extends Shapes> shapes) { .. T obj) 400 . you cannot add objects to this collection. because ? stands for some unknown type and it's not possible to know if the type of the object you want to add is a subtype of the unknown type. You can also constrain (or bound) the wildcard by a type. A wildcard with a lower bound is specified as <? super Type> and stands for all types that are supertypes of Type. In summary. } This allows drawAll to accept collections of any subclass of Shape. since we know that the type argument will be some type of shape.The ? type is known as a wildcard type. The type parameter section is delimited by angle brackets and appears before the method's return type. The only exception is null. Rectangle. It is also possible to constrain a wildcard with a lower bound. } } Since we have seen that it is not legal to pass in a subtype of Shape (for example. 16. However. For example the following Collections class method fills a List of type <? super T> with objects of type T: static <T> void fill(List<? super T> list. Static and non-static methods as well as constructors can have type parameters. which is a member of every type. methods can be parameterized too. suppose you have a class hierarchy consisting of a geometric shape (Shape) and its subtypes (Circle. Circle) as the type argument for the generic collection passed to drawAll. However. For example. a wildcard with an upper bound is specified as <? extends Type> and stands for all types that are subtypes of Type. Note that just as it is not possible to add an object to a collection of unknown type. The drawing program that references these objects invokes a method drawAll to draw a collection of these shapes: public void drawAll(Collection<Shapes> shapes) { for (Shape s: shapes) { s. Bounded wildcards are useful when you have partial knowledge about the type argument. and so on). it is also not legal to add an object to a collection of an unknown type that has a bound. To enable passing a subtype of Shape as the type argument.draw().

fill(list. filler). } 401 . One difference between generic types and generic methods is that generic methods are invoked like regular methods..add(""). The type parameters of generic methods generally are independent of any class or interface-level type parameters. as in this invocation of the fill method: public static void main(String[] args) { List<String> list = new ArrayList<String>(10). The type parameters are inferred from the invocation context. i < 10.. . i++) { list.Generic methods allow you to use type parameters to express dependencies among the types of one or more arguments to a method or its return type (or both). for (int i = 0. Collections. } String filler = args[0].

if neither is present. the single None of the above argument is indeed an array of components of type String. '\'' (single quote). The Java Language Specification requires that the main method must accept a single argument that is an array of components of type String.Answers Chapter 2 No. All of these are keywords of the Pascal None of the above programming language. then an array with the specified dimension is created with all elements set to the default values. then a compile-time error is generated. '\"' (double quote). '\r' (carriage return). If both are present. Java avoids the possibility of an incompatible dimension expression and initializer by not allowing both to appear in the 16 Answer 1 a 2 g 3 l 4 d f h 5 6 b d a e 402 . '\f' (formfeed). but none are Java keywords. so none of '\u0000' to '\uffff' 0 to the char values are negative and the minimum 65535 value is zero. If only the dimension expression is present. The first 4 6 8 letter can not be a number. '\\' 1 (backslash). then a compile-time error is generated. '\t' (horizontal tab). '\n' (newline).e.1. The first letter of an identifier can be any Unicode character that is a Java letter. In each of the three class declarations. Please note that the square brackets within an array declaration may appear as part of the type or part of the declarator (i. you must memorize the escape sequences! Just remember "big farms need red tractors". Remark The escape sequences are as follows: '\b' (backspace). A char is a 16 bit unsigned value. If only the initializer is present. then an array will be created that has the required dimensions to accommodate the values specified in the initializer. Yes. 1 5 An array creation expression must have either a dimension expression or an initializer. array name). The maximum value is 2 . Similarly. The dollar sign $ and underscore _ are considered Java letters.

8. '\061' ) are declared in octal format. or char then the left operand is promoted to a 32 bit int and all four bytes are shifted. a1[0][2] = a1[1st subarray][third component] = 3. Answer 7 a Prints: 3. The sign of an integral numeric type is changed by inverting all of the bits and by adding one. A compile-time error is generated at 5. and each is a reference to a subarray of type int[].6}. The compiler will generate an error as a result of the attempt to access the local variables before a value has been assigned.9. The first three ( 061. then the shift 1 f Compile-time error 2 j Compile-time error 3 f None of the above 4 5 d e Prints: true. they are not automatically initialized. The fifth ('\u0031') is a Unicode escape sequence. The initializer creates an array containing three components. because it needs either a dimension expression or an initializer. All of the declarations are legal. If the promoted type of the left-hand operand is of type int. Each subarray contains components of type int.8 Remark same array creation expression.true Prints: 10 403 . {4. The fourth (0x0031) is declared as a hexadecimal literal. and the declaration contains the initializer {{1. because either the dimension expression or the initializer must be removed. '\61'. A compile-time error is generated by the array creation expression for a1. An array variable a1 is declared. so the elements of the array referenced by a1 are of type int. short. The array access expression.10}}.{7. Answer Remark Variables declared inside of a block or method are called local variables. If the left-hand operand of the shift operator is of type byte.3}. Both operands of the conditional and operator and the conditional or operator must be of type boolean.4.No. Chapter 3 No.5.2.

Chapter 4 No. 1 c 3 Answer Remark The length member of the array type is an attribute. Generally speaking. Answer 6 c Prints: 5 7 b Prints: 2. can be rewritten as the single statement. a compound assignment expression of the form E1 op= E2 can be rewritten as E1=(T) ((E1)op(E2)) where T is the type of E1. inclusive. The tricky feature of this question is the reversal of i and j to produce the deceptive array access expression. the identity. then the least significant six bits of the right hand operand are used. the shift distance is 33.9}}. The expression used to assign variable b1 is equivalent to the expression used to assign variable b2.8. For integral types. In this case. and the five least significant bits are 00001. so the 2 b Prints: 147258369 3 c Prints: v w x x y z z 404 . If the argument of the print statement had been a1[i][j] then the output would have been 123456789. A compile-time error is generated as a result of the attempt to access length as though it were a method.5. The array access expression. The output is 147258369. {{1. so the shift distance is one bit.{4.true 8 b Prints: FFT Remark distance is always within the range of 0 to 31. a1[j][i]. Note: If the type of the left hand operand is long. and is specified by the least significant 5 bits of the right-hand operand.No. is always true. Further evaluation produces a=(int) ((1)+(2 + 2)). The remainder operator returns the remainder of the division operation. (y == ((y/x)*x+(y%x))).2. Cases one and three have no break statement.3}. Suppose the left operand were divided by the right operand. a1[0][1] = a1[first subarray][second element] = 2.6}. int a=1 followed by a += ++a + a++. The array variable a1 is declared with the initializer. The results demonstrate that the conditional operator (?:) groups from right-toleft. The two statements.{7. a=(int)((1)+(++a + a++)).

On the final pass. d and e is zero. 4 c Prints: 61433 Chapter 5 No. success. The main methods of GRC2 and GRC3 are not declared public and can not be invoked from the command line. success. Compile-time error Local variables are not initialized automatically. In this example. so 3 is added to x. so 5 is subtracted from x.No. the value of x is 1. b. On the first pass through the loop. so the variable. Answer An attempt to run GRC7 from the command line results in an error at runtime. is incremented to the value. the value of x is 3 and the variable. An attempt to run GRC2 from the command line fails. so 1 is subtracted from x. the value of x is 4. An attempt to run GRC8 from the command line results in an error at runtime. Remark 1 d e f The JLS requires the main method to be declared static. The result is an error at run-time. On the third pass. compile-time error. the value of x is 6. the value of x is 3. 3 e 4 5 c c The local variable y has not been initialized so Compile-time error at the attempt to access the variable results in a line 5. and must be initialized explicitly before 405 . The numeric sum of variables a. On the fourth pass. The zero is converted to a String and Prints: 0null concatenated with s. An attempt to run GRC9 from the command line results in an error at runtime. each of the three main methods are not declared static. On the second pass. is incremented from zero to one. Answer Remark next case is also executed and x and z are printed twice. 2 e f The JLS requires the main method to be declared public. so control passes out of the loop. The boolean expression of the do loop is now false. c. An attempt to run GRC3 from the command line fails. 2.

No. The assignment expression. m(double i). the reference pet2 remains unchanged in the main method. The index for the first element of an array is zero so the first argument printed by this program is the second argument on the command line following the name of the class. so both methods. we can say that m(float i) is more specific than m(double i). For that reason. A method invocation conversion can widen an argument of type float to match a method parameter of type double. the more specific of the two. The local variable i3 will not be initialized if i1 is less than or equal to zero. char or byte.Cat 9 d 4 Remark attempting to access the value. short. requires an explicit cast to type int. the more specific of the two. The arguments of the method invocation expressions. If one of the two operands of a numeric expression is of type long and if the other operand is of type int. m(float i) and m(double i). Although the reference variable r2 is assigned the value of reference variable r1 in method m1. The reference parameter r1 can be used to modify the state of the instance referenced by pet1. a = c + a. Answer 6 b Prints: BCD 7 a Prints: float. then it will be promoted 406 . m(double i). so any argument that can be passed to m(float i) can also be passed to m(double i) without generating a compile-time type error. so the result is a compile-time error. m(float i).float 8 c Prints: Bird. A method invocation conversion can widen an argument of type int or long to match either of the two method parameter types float or double. are of types int and long respectively. m(a1) and m(b1). Since both methods are applicable. m(float i) is chosen rather than the less specific. are applicable to the two method invocation expressions. but r2 can not be used to force pet2 to reference a different instance. Object references are passed by value: the invoked method gets a copy of the object reference. Since both methods are applicable. is chosen over the less specific.

"return c2.". the value of c2 is assigned at run time to the value of the argument. Since the char type variable c2 is not a compile-time constant. 10 b 11 f g h 12 d Remark to type long. and if the value falls within the range of type byte. so it can not be assigned to type byte without an explicit cast.No. variable c2 is not a compile-time constant. Compile-time error at There is a compile-time error at 2. so the value of c2 can not be changed within method m2. and the result of the expression will be of type long. In method m2. The char 2 type variable c2 is not a compile-time constant. For that reason. the statement. The return statement attempts to return the value of the char type variable c2. In method m2. The value of method parameter c2 is set at run time to the value of the argument that is provided when m2 is invoked at line 3. the value of variable c2 is not Answer 407 . the method parameter c2 is not a compile-time constant. short. If a char value is a compile-time constant. Although the reference parameters i1 and i2 are reassigned inside of m1. or char. The compiler will implicitly do a narrowing conversion for an assignment statement if the right hand operand is a compile time constant of type byte. A compiletime error occurs if the type of the expression is not assignable to the declared result type of the method. then the char value is assignable to type byte. Instead. (Note: The rule does not apply to the shift operator. The method parameter c2 is declared final. short.3 impact outside of m1. the change has no Prints: 1. is a return statement with an expression.) The type long result can not be assigned to a variable of type int without an explicit cast. Array references are passed by value: the invoked method gets a copy of the array reference. c2. char. because the value of c2 is not known at compile time. or int and the value 6 7 8 falls within the range of the variable on the left and if the variable is of type byte. The declared result type of method m2 is byte.

Since Red is not Blue or a subclass of Blue. the expression color2 instanceof Blue is rejected at compile-time. so c1 is a compile-time constant. A field is a class member. color1. private. the expression j error color1 instanceof Color would evaluate to true at runtime. the expression color1 instanceof Color would evaluate to true at run-time. x instanceof T. Answer Remark assignable to the return type of method m2 without an explicit cast. While the declaration of method m2 produces a compile-time error.No. Please note: The expression. A non-static field is sometimes called an instance variable. is accepted at compile-time. The type of the object instance referenced by color1 is Red. If the program had been able to compile and run. The abstract modifier may be applied to methods but not to fields Answer 1 2 408 . The c private d protected access modifiers. the expression. The local variable c1 is declared final and the value is set at compile time. would be false at run-time. color1 instanceof Blue. Since Color is a superclass of Blue. Since Red is not a subclass or a superclass of Blue. is of type Color. A variable declaration that is immediately contained by b final a block such as a method body is called a local variable. color1 instanceof Blue would evaluate to false at run-time. A static field is sometimes called a class variable. Since Red is a subclass of Color. can be applied to a field. The expression. so the value of the compile-time constant c1 is assignable to the return type of method m1 without an explicit cast. The reference. Remark The type of the reference color2 is Red. protected and public. produces a compile-time error whenever the cast expression (T)x produces a compiletime error. A final field can not have its value assigned e public more than once. the declaration of method m1 does not. Chapter 6 No. color1 instanceof Blue. the expression. The value \u0001 falls within the range of type byte. The reference color1 refers to an instance of Compile-time type Red.

The dimensions of the subarrays have not been specified. therefore. private and protected. and each is able to reference a subarray. then the class must also be declared abstract. are not applicable to any class that is not a member class. and invokes its superclass constructor. The size of the subarrays has not been specified. The class declaration. has no throws clause. As a result. Since class A does not have a noparameter constructor. 5 c d 3 4 5 e 6 b Prints: A11 Remark If no constructor is declared explicitly. a reference to the array 409 . protected or public. the attempt by class B to invoke the no parameter constructor of A would fail. private. Class B does not have an explicit constructor declaration. The declaration A11[] a1 = new A11[1] declares a variable a1 that references an array that contains one component of type A11. the array referenced by a3 contains three reference variables. an anonymous class can not be declared abstract. The initial value of each subarray reference is null. no modifier). Since class A has an explicitly declared constructor. a compiler error is generated at marker 2. 3 4 A local class can be b declared abstract. Class Basics4 {}. and each is able to reference a subarray. then C may be declared with the public modifier or with package access (i. because all of the letters of the reserved word class must be lower case. then the compiler will implicitly create a default constructor that accepts no parameters. The declaration A11[][] a2 = new A11[2] [] declares a variable a2 that references an array that contains two components of type A11[]. the array referenced by a2 contains two reference variables. so the compiler attempts to create a default constructor.e. An abstract class can never be declared final. At line 5. anonymous class or a member of an enclosing class or interface.No. generates a compile-time error. The declaration A11[][][] a3 = new A11[3] [][] declares a variable a3 that references an array that contains three components of type A11[][]. The initial value of the subarray references is null. The other two access modifiers. If a class declaration contains an abstract method. A local class can be abstract. However. An abstract class can not be instantiated. the compiler will not create an implicit default constructor. Compile-time error at 2. In other words. Answer The compiler attempts to create a b default d constructor for class B. In other words. A class can be declared abstract even if it does not contain an abstract method. An anonymous class can not be extended. If a class C is declared as a member of an enclosing class then C may be declared using no access modifier or any of the three access modifiers. if class C is not a local class.

Every element of the multi-dimensional array referenced by a3 contains a reference to a single instance of class A11. both B and C must declare Exception in their throws clause. The print method invokes the toString method on the instance. each component of the array referenced by a3 is a reference to the array referenced by a2. Since the constructors for B and C invoke the constructor for A implicitly. The implicitly created constructor accepts no parameters and has no throws clause. so the reference may be cast to type Sub. after line 6. Answer Remark referenced by a1 is assigned to each of the two components of the array referenced by a2. a3[0] = a3[1] = a3[2] = a2. 1 e Answer None of the above Remark Line 4 does not generate a compile-time error. 410 . Both class A and B are declared in the same package. a reference to the array referenced by a2 is assigned to each of the three components of the array referenced by a3. 2 d Compile-time error at 3. A11. 1 c Compile-time error at 3. and produces the output. Chapter 7 No. and the array referenced by a1 contains a reference to an instance of class A11. In other words. At line 6. The constructors for class B and class C both invoke the constructor for A. so class B has access to the public. The constructor for class A declares Exception in the throws clause. and package access methods of class A. because the default constructor does not declare Exception in the throws clause. The reference named base actually refers to an instance of type Sub. a2[0] = a2[1] = a1. A compiletime error is generated at marker 3. and each element of the array referenced by a2 is a reference to the array referenced by a1. protected.No. Chapter 8 No. Answer Remark The compiler creates a constructor for class C implicitly.

The escape sequence \n should be used instead. Similarly. With assertions disabled it prints 210210-1 Chapter 10 No. under normal operating circumstances.1 Remark Both Error and Exception are subclasses of Throwable.127 Remark A byte is an 8 bit signed value. The outer finally block is executed as control passes out of the try statement. so the minimum short value is -(2 ) and the maximum value is (2 . 3 4 \u000d is interpreted as a line terminator. so the minimum byte value is -(2 ) and the maximum value is (2 1). then an assert statement can be placed after the default label to verify that an unexpected condition has not not occurred. but all above of the declarations here use single quotes.1). the default label of a switch statement should not be reached.true 3 b Prints: 0. 1 Answer d Prints: -128. 7 7 15 15 2 b Prints: -32768. 1 c d Answer Remark The compiler interprets \u000a as a line terminator. 2 e Chapter 12 No.No.32767 411 . None of the String literals are declared using double quotes. The escape sequence \r should be used instead.0. The nested catch clause is able to catch a Level2Exception or any subclass of it.1.1. If. 2 d Answer Prints: true. A short is a 16 bit signed value. 4 With assertions enabled it prints 210210 followed by an b e AssertionError message. The switch statement throws a Level1Exception that can not be caught by the nested catch clause.0. so the nested finally block is executed as control passes to the first of the two outer catch clauses.

The second octal digit represents the next three bits of the binary value. Note that the Integer. The Integer.127. A short is a 16 bit signed value. The right hex digit represents the right most four bits of the binary value. An int is a 32 bit signed value. Answer 3 a Prints: 1111111. A char is a 16 bit unsigned value. The left most bit of a signed value is the sign bit. In this case. An eight bit binary value is represented as two hexadecimal digits.toOctalString method does not print a leading zero as is required for an octal literal value. An eight bit binary value is represented as three octal digits. The first of the three digits represents the left most two bits of the binary value.false. NaN is 412 . The left most bit is the sign bit. so only seven bits are printed. int[].7f 4 c Prints: 7f. A byte is an 8 bit signed value.7fff 5 f Prints: 80000000.7fffffff 6 g None of the above 7 f Prints: true.true Remark A byte is an 8 bit signed value. The sign bit is set to zero for positive numbers and is set to one for negative numbers. The int array object referenced by the Cloneable reference. the left most two bits are zero and one. The null literal is converted to an int array type with the value null. so any array reference can be assigned to a reference of type Cloneable. The sign bit is zero for positive numbers and one for negative numbers.toBinaryString method does not print leading zeros. All array types implement the Cloneable interface. The left most bit is the sign bit. The maximum byte value in hexadecimal format is 7f and in decimal format is 127. The left hex digit represents the left most four bits of the binary value. The positive infinity of type float is promoted to the positive infinity of type double. The byte value of decimal -1 is ff in hexadecimal. The sign bit is zero for positive numbers and one for negative numbers. The last of the octal digits represents the right most three bits of binary value.ffff. c.No.177. The most positive byte value is represented as a sign bit that is set to zero and all of the other bits set to one. The minimum byte value in hexadecimal format is 80 and in decimal format is -128. can be assigned to a reference of the int array type.

No. Answer Remark not equal to anything including itself. 413 .

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->