java reference library 1.3

5714
As of February 9, 1998, the entire online Java Reference Library reflects version 1.4 of the Java Deluxe CD product, which will be available at the end of February. This version includes the updated files for Exploring Java, Second Edition (published October 1997), plus minor revisions to the other files. Java in a Nutshell Java Language Reference Java AWT Reference Java Fundamental Classes Reference Exploring Java Combined Index Combined Search Web Version Credits The Java Reference Library, version 1.3, is copyright © 1996, 1997, 1998 by O'Reilly & Associates. All Rights Reserved. Questions, comments, and suggestions to [email protected].

Upload: dinhnhu

Post on 08-Dec-2016

344 views

Category:

Documents


3 download

TRANSCRIPT

  • As of February 9, 1998, the entire online Java Reference Library reflects version 1.4 of the Java Deluxe CD product, which will be available at the end of February. This version includes the updated files for Exploring Java, Second Edition (published October 1997), plus minor revisions to the other files.

    Java in a NutshellJava Language ReferenceJava AWT ReferenceJava Fundamental Classes ReferenceExploring Java

    Combined IndexCombined SearchWeb VersionCredits

    The Java Reference Library, version 1.3, is copyright 1996, 1997, 1998 by O'Reilly & Associates. All Rights Reserved. Questions, comments, and suggestions to [email protected].

    file:///C|/download/ftp.selab.org/ebook/javaref/search/allsrch.htmfile:///C|/download/www.ora.com/books/javaref/default.htmmailto:[email protected]

  • Java in a NutshellBy David Flanagan; 1-56592-262-X, 628 pages.2nd Edition, May 1997

    Table of Contents

    Preface

    Part I: Introducing Java Part I is an introduction to Java and Java programming. If you know how to program in C or C++, these chapters teach you everything you need to know to start programming with Java.

    If you are already familiar with Java 1.0 you may want to just skip ahead to Part II, which introduces the new features of Java 1.1. Chapter 1: Getting Started with JavaChapter 2: How Java Differs from CChapter 3: Classes and Objects in Java

    Part II: Introducing Java 1.1 The two chapters in this part introduce the new features of Java 1.1. Chapter 4 is an overview of the new APIs, and Chapter 5 explains the new language syntax. See Part III for some examples of the new features. Chapter 4: What's New in Java 1.1Chapter 5: Inner Classes and Other New Language Features

    Part III: Programming with the Java 1.1 API Part III contains examples of programming with the new features of Java 1.1. You can study and learn from the examples, and you should feel free to adapt them for use in your own programs. The examples shown in these chapters may be downloaded from the Internet. See http://www.ora.com/catalog/books/javanut2/. Some of the chapters in this part also contain tables and other reference material for new features in Java 1.1.

    Part III of this book is "deprecated." Most of the examples from the first edition of this book do

    file:///C|/download/www.ora.com/catalog/javanut2/default.htmfile:///C|/download/www.ora.com/catalog/books/javanut2/default.htm

  • not appear here, and Part III may disappear altogether in the next edition of the book. Unfortunately, as Java continues to grow, there is less and less room for programming examples in this book. However, all of the examples from the first edition are still available on the Web page listed above. Chapter 6: AppletsChapter 7: EventsChapter 8: New AWT FeaturesChapter 9: Object SerializationChapter 10: Java BeansChapter 11: InternationalizationChapter 12: Reflection

    Part IV: Java Language Reference Part IV contains reference material on the Java language and related topics. Chapter 13 contains a number of useful summary tables of Java syntax. Chapter 14 describes the standard Java system properties and how to use them. Chapter 15 covers the syntax of the HTML tags that allow you to include Java applets in Web pages. Chapter 16 documents the command-line syntax for the Java compiler, interpreter, and other tools shipped with the JDK. Chapter 13: Java SyntaxChapter 14: System PropertiesChapter 15: Java-Related HTML TagsChapter 16: JDK Tools

    Part V: API Quick Reference Part V is the real heart of this book: quick-reference material for the Java API. Please read the following section, How to Use This Quick Reference, to learn how to get the most out of this material. How to Use This Quick ReferenceChapter 17: The java.applet PackageChapter 18: The java.awt PackageChapter 19: The java.awt.datatransfer PackageChapter 20: The java.awt.event PackageChapter 21: The java.awt.image PackageChapter 22: The java.awt.peer PackageChapter 23: The java.beans PackageChapter 24: The java.io PackageChapter 25: The java.lang PackageChapter 26: The java.lang.reflect PackageChapter 27: The java.math PackageChapter 28: The java.net Package

  • Chapter 29: The java.text PackageChapter 30: The java.util PackageChapter 31: The java.util.zip PackageChapter 32: Class, Method, and Field Index

    IndexExamples - Warning: this directory includes long filenames which may confuse some older operating systems (notably Windows 3.1).

    Search the text of Java in a Nutshell.

    Copyright 1996, 1997 O'Reilly & Associates. All Rights Reserved.

    file:///C|/download/ftp.selab.org/ebook/javaref/jsrch.htm

  • Preface

    PrefaceContents:Contents of This BookChanges Since the First EditionRelated BooksJava ResourcesJava in a Nutshell Web SitesConventions Used in This BookRequest for CommentsAcknowledgments

    This handbook is a desktop quick reference for Java programmers; it covers version 1.1 of the Java language and API. It also includes introductory and tutorial material for C and C++ programmers who want to learn Java. It was written to sit faithfully by your keyboard for easy reference while you program. The wild success of the first edition has shown that this is exactly what Java programmers want, and I've retained the "no fluff" explanations and the to-the-point reference material in this second edition. I hope that new readers will find this book useful, and that old readers will find it even more useful than the last one!

    Contents of This Book

    This book is divided into five parts:

    Part I: Introducing Java

    This first part of the book introduces Java and Java programming, with a particular emphasis on helping C and C++ programmers make the transition to Java. If you are already familiar with Java 1.0 programming, you can skip the three chapters in this part.

  • Part II: Introducing Java 1.1

    This second part of the book contains two chapters that introduce the new features of the Java 1.1 API and the new language features in Java 1.1.

    Part III: Programming with the Java 1.1 API

    This part contains example programs that demonstrate many of the new features of Java 1.1. You may find that these examples are a good starting point for your own programs, and you should feel free to adapt them for your own use. As explained below, this example section has changed a lot since the first edition of this book.

    Part IV: Java Language Reference

    This part of the book contains reference material that describes the syntax of the Java language and the tools provided with the Java Development Kit (JDK), among other things.

    Part V: API Quick Reference

    This part is a quick reference for the Java API; it forms the bulk of the book. Please be sure to read the How To Use This Quick Reference material, which appears at the beginning of the part. It explains how to get the most out of the reference material.

    Changes Since the First

    Edition

  • Preface

    Changes Since the First Edition

    The many changes in Java 1.1 have resulted in changes to this book. The most significant change since the first edition is a direct result of the large size of Java 1.1: Java has grown too large to fit in a single book, even in quick-reference form. Thus, we need to split Java in a Nutshell into multiple volumes. This volume, the "original" Java in a Nutshell documents the most commonly used features of Java, and it is an indispensable volume for all Java programmers.

    We are planning to publish a separate volume that covers the Java "Enterprise APIs," which include the database connectivity, remote method invocation, and security features of Java 1.1, as well as other forthcoming components, such as CORBA IDL support and the electronic commerce framework. And as new Java APIs are developed and released, we may consider adding new volumes to the Java in a Nutshell series.

    While I was working on this second edition of Java in a Nutshell, it became clear that, even without the enterprise material, the book was becoming too long. (Too long, that is, to remain a useful quick reference, and too long to keep at an affordable price.) Something had to give. The most logical solution was to remove the example programs, which are tutorial in nature, from the book, which is a quick-reference at heart. However, we didn't want to surprise faithful readers by removing the examples altogether, so we decided to pare down the example chapters to the bare minimum. You'll notice that Part III contains examples of using the new Java 1.1 features, such as the JavaBeans API and object serialization, but it does not contain the majority of the old examples from the first edition. For now, Part III contains useful examples for experienced Java programmers who want to learn about the new features of Java 1.1. When Java 1.2 is released, though, we expect that we will have to remove the example section entirely.

    Readers familiar with the first edition of Java in a Nutshell will notice some other changes as well. The table of contents has been rearranged to accommodate all the new material. We've used a new easier-to-read font for code listings. And we've included cross-reference material (that used to be available only in separate index chapters) directly in the quick-reference section, which should make that section substantially more useful. Be sure to read How To Use This Quick Reference at the beginning of the reference section to learn about these and other changes to the quick-reference format.

  • Contents of This Book Related Books

  • Preface

    Related Books

    O'Reilly & Associates is developing an entire series of books on Java. This series consists of introductory books, reference manuals, and advanced programming guides.

    The following books on Java are currently available or due to be released soon from O'Reilly & Associates:

    Exploring Java, by Patrick Niemeyer and Joshua Peck

    A comprehensive tutorial that provides a practical, hands-on approach to learning Java.

    Java Language Reference, by Mark Grand

    A complete reference for the Java programming language itself.

    Java AWT Reference, by John Zukowski

    A complete reference manual for the AWT-related packages in the core Java API.

    Java Fundamental Classes Reference, by Mark Grand and Jonathan Knudsen

    A complete reference manual for the java.lang, java.io, java.net, java.util packages, among others, in the core Java API.

    Java Virtual Machine, by Jon Meyer and Troy Downing

    A programming guide and reference manual for the Java Virtual Machine.

    Java Threads, by Scott Oaks and Henry Wong

  • An advanced programming guide to working with threads in Java.

    Java Network Programming, by Elliote Rusty Harold

    A complete guide to writing sophisticated network applications.

    Database Programming with JDBC and Java, by George Reese

    An advanced tutorial on JDBC that presents a robust model for developing Java database programs.

    Developing Java Beans, by Robert Englander

    A complete guide to writing components that work with the JavaBeans API.

    Look for additional advanced programming guides on such topics as distributed computing and electronic commerce from O'Reilly in the near future.

    Changes Since the First Edition

    Java Resources

  • Preface

    Java Resources

    Sun has online reference documentation for the Java API that you may find useful in conjunction with this quick reference handbook. Visit http://www.javasoft.com/ to view or download this API documentation and other useful documents.

    There are many other sites on the Web that contain useful Java information. One of the most well-known is http://www.gamelan.com/, also known as http://java.developer.com/. For discussion (in English) about Java, try the various comp.lang.java.* newsgroups.

    Related Books Java in a Nutshell Web Sites

    file:///C|/download/www.javasoft.com/default.htmfile:///C|/download/www.gamelan.com/default.htmfile:///C|/download/java.developer.com/default.htm

  • Preface

    Java in a Nutshell Web Sites

    The Web site for this book is http://www.ora.com/catalog/books/javanut2/. There you will find the examples from this book, available for download. As typos are reported, you may also find an errata list at that Web site.

    My personal Web site is http://www.DavidFlanagan.COM/. This is a new site, just getting off the ground as this book goes to press, but it will eventually contain a number of Java programming resources, including commercial and shareware tools and "beans" that I have written.

    Java Resources Conventions Used in This Book

    file:///C|/download/www.ora.com/catalog/books/javanut2/default.htmfile:///C|/download/www.davidflanagan.com/default.htm

  • Preface

    Conventions Used in This Book

    Italic is used for:

    Pathnames, filenames, and program names.

    New terms where they are defined.

    Internet addresses, such as domain names and URLs.

    Boldface is used for:

    Particular keys on a computer keyboard.

    Names of user interface buttons and menus.

    Constant Width is used for:

    Anything that appears literally in a Java program, including keywords, data types, constants, method names, variables, class names, and interface names.

    Command lines and options that should be typed verbatim on the screen.

    All Java code listings.

    HTML documents, tags, and attributes.

    Method parameters, and general placeholders that indicate that an item is replaced by some actual value in your own program.

    Variable expressions in command-line options.

  • Java class synopses in the quick-reference section. This very narrow font allows us to fit a lot of information on the page without a lot of distracting line breaks.

    Highlighting class, method, field, and constructor names in the quick-reference section, which makes it easier to scan the class synopses.

    Method parameter names and comments in the quick-reference section.

    Java in a Nutshell Web Sites Request for Comments

  • Preface

    Request for Comments

    Please help us to improve future editions of this book by reporting any errors, inaccuracies, bugs, misleading or confusing statements, and plain old typos that you find anywhere in this book. Email your bug reports and comments to us at: [email protected]. (Before sending a bug report, however, you may want to check for an errata list at http://www.ora.com/catalog/books/javanut2/ to see if the bug has already been submitted.)

    Please also let us know what we can do to make this book more useful to you. We take your comments seriously and will try to incorporate reasonable suggestions into future editions.

    Conventions Used in This Book

    Acknowledgments

    file:///C|/download/www.ora.com/catalog/books/javanut2/default.htm

  • Preface

    Acknowledgments

    Many people helped in the creation of this book and I am grateful to them all. I am indebted to literally hundreds of readers of the first edition who wrote in with comments, suggestions, bug reports, and praise. Their many small contributions are scattered throughout the book. Also, my apologies to those who made the many good suggestions that could not be incorporated into this edition.

    Paula Ferguson, a friend and colleague, edited both editions of the book. Her careful reading and always-practical suggestions made the book stronger, clearer, and more useful. She is also the one who prodded me when I started to slack off, and got me back on track when I started trying to turn Java in a Nutshell into Java in a Packing Crate.

    Mike Loukides provided high-level direction and guidance for the first edition of the book. Eric Raymond and Troy Downing reviewed that first edition--they helped spot my errors and omissions, and offered good advice on making the book more useful to Java programmers.

    For the second edition, John Zukowski reviewed my Java 1.1 AWT quick-reference material, and George Reese reviewed most of the remaining new material. This edition was also blessed with a "dream team" of technical reviewers from Sun. John Rose, the author of the Java Inner Classes Specification, reviewed the chapter on inner classes. Mark Reinhold, author of the character stream classes in java.io, reviewed my documentation of these classes. Nakul Saraiya, the designer of the new Java Reflection API, reviewed my documentation of the java.lang.reflect package. I am very grateful to these engineers and architects; their efforts have made this a stronger, more accurate book. Any errors that remain are of course my own.

    Nicole Gipson Arigo was the production editor for this edition of the book, taking over the job from John Files, who produced the first edition. Nicole coordinated the entire production process, entered changes from edited copy, and handled the meticulous task of fixing line and page breaks in the manuscript. Madeleine Newell provided production assistance. Clairemarie Fisher O'Leary, Jane Ellin, and Sheryl Avruch performed quality control checks. Seth Maislin wrote the index. Chris Reilley created the figures, including all the detailed class hierarchy diagrams in Part V. [1] Edie Freedman designed the cover. Nancy Priest designed the interior format of the book and Lenny Muellner carefully implemented the

  • format in troff, with help from Ellen Siever.

    [1] The hierarchy diagrams are loosely based on similar diagrams for Java 1.0 by Charles L. Perkins.

    The whole production team has my thanks for once again pulling together all the pieces to create the finished product you now hold in your hands.

    As always, my thanks and love to Christie.

    David Flanagan April 1997

    Request for Comments Getting Started with Java

  • Chapter 1

    1. Getting Started with JavaContents:Why Is Java Interesting?A Simple Example

    When it was introduced in late 1995, Java took the Internet by storm. Java 1.1, released in early 1997, nearly doubles the speed of the Java interpreter and includes many important new features. With the addition of APIs to support database access, remote objects, an object component model, internationalization, printing, encryption, digital signatures, and many other technologies, Java is now poised to take the rest of the programming world by storm.

    Despite all the hype surrounding Java and the new features of Java 1.1, it's important to remember that at its core, Java is just a programming language, like many others, and its APIs are just class libraries, like those of other languages. What is interesting about Java, and thus the source of much of the hype, is that it has a number of important features that make it ideally suited for programming in the heavily networked, heterogenous world of the late 1990s. The rest of this chapter describes those interesting features of Java and demonstrates some simple Java code. Chapter 4, What's New in Java 1.1 explores the new features that have been added to version 1.1 of the Java API.

    1.1 Why Is Java Interesting?

    In one of their early papers about the language, Sun described Java as follows:

    Java: A simple, object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, and dynamic language.

    Sun acknowledges that this is quite a string of buzzwords, but the fact is that, for the most part, they aptly describe the language. In order to understand why Java is so interesting, let's take a look at the language features behind the buzzwords.

  • Object-Oriented

    Java is an object-oriented programming language. As a programmer, this means that you focus on the data in your application and methods that manipulate that data, rather than thinking strictly in terms of procedures. If you're accustomed to procedure-based programming in C, you may find that you need to change how you design your programs when you use Java. Once you see how powerful this new paradigm is, however, you'll quickly adjust to it.

    In an object-oriented system, a class is a collection of data and methods that operate on that data. Taken together, the data and methods describe the state and behavior of an object. Classes are arranged in a hierarchy, so that a subclass can inherit behavior from its superclass. A class hierarchy always has a root class; this is a class with very general behavior.

    Java comes with an extensive set of classes, arranged in packages, that you can use in your programs. For example, Java provides classes that create graphical user interface components (the java.awt package), classes that handle input and output (the java.io package), and classes that support networking functionality (the java.net package). The Object class (in the java.lang package) serves as the root of the Java class hierarchy.

    Unlike C++, Java was designed to be object-oriented from the ground up. Most things in Java are objects; the primitive numeric, character, and boolean types are the only exceptions. Strings are represented by objects in Java, as are other important language constructs like threads. A class is the basic unit of compilation and of execution in Java; all Java programs are classes.

    While Java is designed to look like C++, you'll find that Java removes many of the complexities of that language. If you are a C++ programmer, you'll want to study the object-oriented constructs in Java carefully. Although the syntax is often similar to C++, the behavior is not nearly so analogous. For a complete description of the object-oriented features of Java, see Chapter 3, Classes and Objects in Java.

    Interpreted

    Java is an an interpreted language: the Java compiler generates byte-codes for the Java Virtual Machine (JVM), rather than native machine code. To actually run a Java program, you use the Java interpreter to execute the compiled byte-codes. Because Java byte-codes are platform-independent, Java programs can run on any platform that the JVM (the interpreter and run-time system) has been ported to.

    In an interpreted environment, the standard "link" phase of program development pretty much vanishes. If Java has a link phase at all, it is only the process of loading new classes into the environment, which is an incremental, lightweight process that occurs at run-time. This is in contrast with the slower and more cumbersome compile-link-run cycle of languages like C and C++.

  • Architecture Neutral and Portable

    Because Java programs are compiled to an architecture neutral byte-code format, a Java application can run on any system, as long as that system implements the Java Virtual Machine. This is a particularly important for applications distributed over the Internet or other heterogenous networks. But the architecture neutral approach is useful beyond the scope of network-based applications. As an application developer in today's software market, you probably want to develop versions of your application that can run on PCs, Macs, and UNIX workstations. With multiple flavors of UNIX, Windows 95, and Windows NT on the PC, and the new PowerPC Macintosh, it is becoming increasingly difficult to produce software for all of the possible platforms. If you write your application in Java, however, it can run on all platforms.

    The fact that Java is interpreted and defines a standard, architecture neutral, byte-code format is one big part of being portable. But Java goes even further, by making sure that there are no "implementation-dependent" aspects of the language specification. For example, Java explicitly specifies the size of each of the primitive data types, as well as its arithmetic behavior. This differs from C, for example, in which an int type can be 16, 32, or 64 bits long depending on the platform.

    While it is technically possible to write non-portable programs in Java, it is relatively easy to avoid the few platform-dependencies that are exposed by the Java API and write truly portable or "pure" Java programs. Sun's new "100% Pure Java" program helps developers ensure (and certify) that their code is portable. Programmers need only to make simple efforts to avoid non-portable pitfalls in order to live up to Sun's trademarked motto "Write Once, Run Anywhere."

    Dynamic and Distributed

    Java is a dynamic language. Any Java class can be loaded into a running Java interpreter at any time. These dynamically loaded classes can then be dynamically instantiated. Native code libraries can also be dynamically loaded. Classes in Java are represented by the Class class; you can dynamically obtain information about a class at run-time. This is especially true in Java 1.1, with the addition of the Reflection API, which is introduced in Chapter 12, Reflection.

    Java is also called a distributed language. This means, simply, that it provides a lot of high-level support for networking. For example, the URL class and OArelated classes in the java.net package make it almost as easy to read a remote file or resource as it is to read a local file. Similarly, in Java 1.1, the Remote Method Invocation (RMI) API allows a Java program to invoke methods of remote Java objects, as if they were local objects. (Java also provides traditional lower-level networking support, including datagrams and stream-based connections through sockets.)

    The distributed nature of Java really shines when combined with its dynamic class loading capabilities. Together, these features make it possible for a Java interpreter to download and run code from across the

  • Internet. (As we'll see below, Java implements strong security measures to be sure that this can be done safely.) This is what happens when a Web browser downloads and runs a Java applet, for example. Scenarios can be more complicated than this, however. Imagine a multi-media word processor written in Java. When this program is asked to display some type of data that it has never encountered before, it might dynamically download a class from the network that can parse the data, and then dynamically download another class (probably a Java "bean") that can display the data within a compound document. A program like this uses distributed resources on the network to dynamically grow and adapt to the needs of its user.

    Simple

    Java is a simple language. The Java designers were trying to create a language that a programmer could learn quickly, so the number of language constructs has been kept relatively small. Another design goal was to make the language look familiar to a majority of programmers, for ease of migration. If you are a C or C++ programmer, you'll find that Java uses many of the same language constructs as C and C++.

    In order to keep the language both small and familiar, the Java designers removed a number of features available in C and C++. These features are mostly ones that led to poor programming practices or were rarely used. For example, Java does not support the goto statement; instead, it provides labelled break and continue statements and exception handling. Java does not use header files and it eliminates the C preprocessor. Because Java is object-oriented, C constructs like struct and union have been removed. Java also eliminates the operator overloading and multiple inheritance features of C++.

    Perhaps the most important simplification, however, is that Java does not use pointers. Pointers are one of the most bug-prone aspects of C and C++ programming. Since Java does not have structures, and arrays and strings are objects, there's no need for pointers. Java automatically handles the referencing and dereferencing of objects for you. Java also implements automatic garbage collection, so you don't have to worry about memory management issues. All of this frees you from having to worry about dangling pointers, invalid pointer references, and memory leaks, so you can spend your time developing the functionality of your programs.

    If it sounds like Java has gutted C and C++, leaving only a shell of a programming language, hold off on that judgment for a bit. As we'll see in Chapter 2, How Java Differs from C, Java is actually a full-featured and very elegant language.

    Robust

    Java has been designed for writing highly reliable or robust software. Java certainly doesn't eliminate the need for software quality assurance; it's still quite possible to write buggy software in Java. However, Java does eliminate certain types of programming errors, which makes it considerably easier to write reliable software.

  • Java is a strongly typed language, which allows for extensive compile-time checking for potential type-mismatch problems. Java is more strongly typed than C++, which inherits a number of compile-time laxities from C, especially in the area of function declarations. Java requires explicit method declarations; it does not support C-style implicit declarations. These stringent requirements ensure that the compiler can catch method invocation errors, which leads to more reliable programs.

    One of the things that makes Java simple is its lack of pointers and pointer arithmetic. This feature also increases the robustness of Java programs by abolishing an entire class of pointer-related bugs. Similarly, all accesses to arrays and strings are checked at run-time to ensure that they are in bounds, eliminating the possibility of overwriting memory and corrupting data. Casts of objects from one type to another are also checked at run-time to ensure that they are legal. Finally, and very importantly, Java's automatic garbage collection prevents memory leaks and other pernicious bugs related to memory allocation and deallocation.

    Exception handling is another feature in Java that makes for more robust programs. An exception is a signal that some sort of exceptional condition, such as a "file not found" error, has occurred. Using the try/catch/finally statement, you can group all of your error handling code in one place, which greatly simplifies the task of error handling and recovery.

    Secure

    One of the most highly touted aspects of Java is that it's a secure language. This is especially important because of the distributed nature of Java. Without an assurance of security, you certainly wouldn't want to download code from a random site on the Internet and let it run on your computer. Yet this is exactly what people do with Java applets every day. Java was designed with security in mind, and provides several layers of security controls that protect against malicious code, and allow users to comfortably run untrusted programs such as applets.

    At the lowest level, security goes hand-in-hand with robustness. As we've already seen, Java programs cannot forge pointers to memory, or overflow arrays, or read memory outside of the bounds of an array or string. These features are one of Java's main defenses against malicious code. By totally disallowing any direct access to memory, an entire huge, messy class of security attacks is ruled out.

    The second line of defense against malicious code is the byte-code verification process that the Java interpreter performs on any untrusted code it loads. These verification steps ensure that the code is well-formed--that it doesn't overflow or underflow the stack or contain illegal byte-codes, for example. If the byte-code verification step was skipped, inadvertently corrupted or maliciously crafted byte-codes might be able to take advantage of implementation weaknesses in a Java interpreter.

    Another layer of security protection is commonly referred to as the "sandbox model": untrusted code is placed in a "sandbox," where it can play safely, without doing any damage to the "real world," or full Java environment. When an applet, or other untrusted code, is running in the sandbox, there are a number

  • of restrictions on what it can do. The most obvious of these restrictions is that it has no access whatsoever to the local file system. There are a number of other restrictions in the sandbox as well. These restrictions are enforced by a SecurityManager class. The model works because all of the core Java classes that perform sensitive operations, such as filesystem access, first ask permission of the currently installed SecurityManager. If the call is being made, directly or indirectly, by untrusted code, the security manager throws an exception, and the operation is not permitted. See Chapter 6, Applets for a complete list of the restrictions placed on applets running in the sandbox.

    Finally, in Java 1.1, there is another possible solution to the problem of security. By attaching a digital signature to Java code, the origin of that code can be established in a cryptographically secure and unforgeable way. If you have specified that you trust a person or organization, then code that bears the digital signature of that trusted entity is trusted, even when loaded over the network, and may be run without the restrictions of the sandbox model.

    Of course, security isn't a black-and-white thing. Just as a program can never be guaranteed to be 100% bug-free, no language or environment can be guaranteed 100% secure. With that said, however, Java does seem to offer a practical level of security for most applications. It anticipates and defends against most of the techniques that have historically been used to trick software into misbehaving, and it has been intensely scrutinized by security experts and hackers alike. Some security holes were found in early versions of Java, but these flaws were fixed almost as soon as they were found, and it seems reasonable to expect that any future holes will be fixed just as quickly.

    High-Performance

    Java is an interpreted language, so it is never going to be as fast as a compiled language like C. Java 1.0 was said to be about 20 times slower than C. Java 1.1 is nearly twice as fast as Java 1.0, however, so it might be reasonable to say that compiled C code runs ten times as fast as interpreted Java byte-codes. But before you throw up your arms in disgust, be aware that this speed is more than adequate to run interactive, GUI and network-based applications, where the application is often idle, waiting for the user to do something, or waiting for data from the network. Furthermore, the speed-critical sections of the Java run-time environment, that do things like string concatenation and comparison, are implemented with efficient native code.

    As a further performance boost, many Java interpreters now include "just in time" compilers that can translate Java byte-codes into machine code for a particular CPU at run-time. The Java byte-code format was designed with these "just in time" compilers in mind, so the process of generating machine code is fairly efficient and it produces reasonably good code. In fact, Sun claims that the performance of byte-codes converted to machine code is nearly as good as native C or C++. If you are willing to sacrifice code portability to gain speed, you can also write portions of your program in C or C++ and use Java native methods to interface with this native code.

    When you are considering performance, it's important to remember where Java falls in the spectrum of

  • available programming languages. At one end of the spectrum, there are high-level, fully-interpreted scripting languages such as Tcl and the UNIX shells. These languages are great for prototyping and they are highly portable, but they are also very slow. At the other end of the spectrum, you have low-level compiled languages like C and C++. These languages offer high performance, but they suffer in terms of reliability and portability. Java falls in the middle of the spectrum. The performance of Java's interpreted byte-codes is much better than the high-level scripting languages (even Perl), but it still offers the simplicity and portability of those languages.

    Multithreaded

    In a GUI-based network application such as a Web browser, it's easy to imagine multiple things going on at the same time. A user could be listening to an audio clip while she is scrolling a page, and in the background the browser is downloading an image. Java is a multithreaded language; it provides support for multiple threads of execution (sometimes called lightweight processes) that can handle different tasks. An important benefit of multithreading is that it improves the interactive performance of graphical applications for the user.

    If you have tried working with threads in C or C++, you know that it can be quite difficult. Java makes programming with threads much easier, by providing built-in language support for threads. The java.lang package provides a Thread class that supports methods to start and stop threads and set thread priorities, among other things. The Java language syntax also supports threads directly with the synchronized keyword. This keyword makes it extremely easy to mark sections of code or entire methods that should only be run by a single thread at a time.

    While threads are "wizard-level" stuff in C and C++, their use is commonplace in Java. Because Java makes threads so easy to use, the Java class libraries require their use in a number of places. For example, any applet that performs animation does so with a thread. Similarly, Java does not support asynchronous, non-blocking I/O with notification through signals or interrupts--you must instead create a thread that blocks on every I/O channel you are interested in.

    Acknowledgments A Simple Example

  • Chapter 1Getting Started with Java

    1.2 A Simple Example

    By now you should have a pretty good idea of why Java is such an interesting language. So we'll stop talking about abstract concepts and look at some concrete Java code. Before we look at an interesting applet, however, we are going to pay tribute to that ubiquitous favorite, "Hello World."

    Hello World

    Example 1.1 shows the simplest possible Java program: "Hello World."

    Example 1.1: Hello World

    public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}

    This program, like every Java program, consists of a public class definition. The class contains a method named main(), which is the main entry point for all Java applications--that is, the point at which the interpreter starts executing the program. The body of main() consists of only a single line, which prints out the message:

    Hello World!

    This program must be saved in a file with the same name as the public class plus a .java extension. To compile it, you would use javac: [1]

    [1] Assuming you're using Sun's Java Development Kit (JDK). If you're using a Java development environment from some other vendor, follow your vendor's instructions.

    % javac HelloWorld.java

    This command produces the HelloWorld.class file in the current directory. To run the program, you use the Java interpreter, java:

  • % java HelloWorld

    Note that when you invoke the interpreter, you do not supply the .class extension for the file you want to run.

    A Scribble Applet

    Example 1.2 shows a less trivial Java program. This program is an applet, rather than a standalone Java application like the "Hello World" program above. Because this example is an applet, it has a different structure than a standalone application; notably, it does not have a main() method. Like all applets, this one runs inside an applet viewer or Web browser, and lets the user draw (or scribble) with the mouse, as illustrated in Figure 1.1.

    Figure 1.1: A Java applet running in a Web browser

    [Graphic: Figure 1-1]

    One of the major changes between Java 1.0 and Java 1.1 is in the way that Java programs are notified of "events", such as mouse motion. Example 1.2 uses the Java 1.0 event model rather than the preferred Java 1.1 event model. This is because the current generation of Web browsers (as this is written) still use Java 1.0. In order for this applet to be widely usable, it is coded with the old, "deprecated" event model. [2]

    [2] If you are interested in updating this program to use Java 1.1, see Chapter 7, Events for

  • information on how to use the new 1.1 event model. In addition, you need to change the call to bounds() in the action() method to a call to getBounds(), if you want to avoid a compilation warning about using a deprecated method.

    Example 1.2: A Java Applet

    import java.applet.*;import java.awt.*;public class Scribble extends Applet { private int last_x, last_y; // Store the last mouse position. private Color current_color = Color.black; // Store the current color. private Button clear_button; // The clear button. private Choice color_choices; // The color dropdown list. // This method is called to initialize the applet. // Applets don't have a main() method. public void init() { // Set the background color. this.setBackground(Color.white); // Create a button and add it to the applet. Set the button's colors. clear_button = new Button("Clear"); clear_button.setForeground(Color.black); clear_button.setBackground(Color.lightGray); this.add(clear_button); // Create a menu of colors and add it to the applet. // Also set the menu's colors and add a label. color_choices = new Choice(); color_choices.addItem("black"); color_choices.addItem("red"); color_choices.addItem("yellow"); color_choices.addItem("green"); color_choices.setForeground(Color.black); color_choices.setBackground(Color.lightGray); this.add(new Label("Color: ")); this.add(color_choices); } // This method is called when the user clicks the mouse to start a scribble. public boolean mouseDown(Event e, int x, int y) { last_x = x; last_y = y; return true; } // This method is called when the user drags the mouse. public boolean mouseDrag(Event e, int x, int y) { Graphics g = this.getGraphics(); g.setColor(current_color); g.drawLine(last_x, last_y, x, y); last_x = x;

  • last_y = y; return true; } // This method is called when the user clicks the button or chooses a color. public boolean action(Event event, Object arg) { // If the Clear button was clicked on, handle it. if (event.target == clear_button) { Graphics g = this.getGraphics(); Rectangle r = this.bounds(); g.setColor(this.getBackground()); g.fillRect(r.x, r.y, r.width, r.height); return true; } // Otherwise if a color was chosen, handle that. else if (event.target == color_choices) { if (arg.equals("black")) current_color = Color.black; else if (arg.equals("red")) current_color = Color.red; else if (arg.equals("yellow")) current_color = Color.yellow; else if (arg.equals("green")) current_color = Color.green; return true; } // Otherwise, let the superclass handle it. else return super.action(event, arg); }}

    Don't expect to be able to understand the entire applet at this point. It is here to give you the flavor of the language. In Chapter 2, How Java Differs from C and Chapter 3, Classes and Objects in Java we'll explain the language constructs you need to understand the example. Then, in Chapter 6, Applets and Chapter 7, Events we'll explain the applet and event-handling concepts used in this example.

    The first thing you should notice when browsing through the code is that it looks reassuringly like C and C++. The if and return statements are familiar. Assignment of values to variables uses the expected syntax. Procedures (called "methods" in Java) are recognizable as such.

    The second thing to notice is the object-oriented nature of the code. As you can see at the top of the example, the program consists of the definition of a public class. The name of the class we are defining is Scribble; it is an extension, or subclass, of the Applet class. (The full name of the Applet class is java.applet.Applet. One of the import statements at the top of the example allows us to refer to Applet by this shorter name.)

    Classes are said to "encapsulate" data and methods. As you can see, our Scribble class contains both variable and method declarations. The methods are actually defined inside of the class. The methods of a class are often invoked through an instance of the class. Thus you see lines like:

    color_choices.addItem("black");

    This line of code invokes the addItem() method of the object referred to by the color_choices variable. If

  • you're a C programmer, but not a C++ programmer, this syntax may take a little getting used to. We'll see lots more of it in Chapters 2 and 3. Note that this is a keyword, not a variable name. It refers to the current object; in this example, it refers to the Scribble object.

    The init() method of an applet is called by the Web browser or applet viewer when it is starting the applet up. In our example, this method creates a Clear button and a menu of color choices, and then adds these GUI components to the applet.

    The mouseDown() and mouseDrag() methods are called when the user clicks and drags the mouse. These are the methods that are responsible for drawing lines as the user scribbles. The action() method is invoked when the user clicks on the Clear button or selects a color from the menu of colors. The body of the method determines which of these two "events" has occurred and handles the event appropriately. Recall that these methods are part of the Java 1.0 event model. Chapter 7, Events explains this model and also explains the Java 1.1 event model that replaces it.

    To compile this example, you'd save it in a file named Scribble.java and use javac:

    % javac Scribble.java

    This example is an applet, not a standalone program like our "Hello World" example. It does not have a main() method, and therefore cannot be run directly by the Java interpreter. Instead, we must reference it in an HTML file and run the applet in an applet viewer or Web browser. It is the applet viewer or Web browser that loads the applet class into its running Java interpreter and invokes the various methods of the applet at the appropriate times. To include the applet in a Web page, we'd use an HTML fragment like the following:

    Example 1.3 shows a complete HTML file that we might use to display the applet. Chapter 15, Java-Related HTML Tags explains the HTML syntax for applets in full detail.

    Example 1.3: An HTML File that Contains an Applet

    The Scribble Applet

    Please scribble away in the applet below.

    Your browser does not support Java, or Java is not enabled. Sorry!

  • Suppose we save this example HTML file as Scribble.html. Then to run this applet, you could use Sun's appletviewer command like this:

    % appletviewer Scribble.html

    You could also display the applet by viewing the Scribble.html file in your Web browser, if your browser supports Java applets. Figure 1.1 showed the Scribble applet running in Netscape Navigator.

    Why Is Java Interesting? How Java Differs from C

  • Chapter 2

    2. How Java Differs from CContents:The Name Space: Packages, Classes, and MembersCommentsNo PreprocessorUnicode and Character EscapesPrimitive Data TypesReference Data TypesObjectsArraysStringsOperatorsStatementsExceptions and Exception HandlingMiscellaneous Differences

    Java is a lot like C, which makes it relatively easy for C programmers to learn. But there are a number of important differences between C and Java, such as the lack of a preprocessor, the use of 16-bit Unicode characters, and the exception handling mechanism. This chapter explains those differences, so that programmers who already know C can start programming in Java right away!

    This chapter also points out similarities and differences between Java and C++. C++ programmers should beware, though: While Java borrows a lot of terminology and even syntax from C++, the analogies between Java and C++ are not nearly as strong as those between Java and C. C++ programmers should be careful not to be lulled into a false sense of familiarity with Java just because the languages share a number of keywords.

    One of the main areas in which Java differs from C, of course, is that Java is an object-oriented language and has mechanisms to define classes and create objects that are instances of those classes. Java's object-

  • oriented features are a topic for a chapter of their own, and they'll be explained in detail in Chapter 3, Classes and Objects in Java.

    2.1 Program Structure and Environment

    A program in Java consists of one or more class definitions, each of which has been compiled into its own .class file of Java Virtual Machine object code. One of these classes must define a method main(), which is where the program starts running. [1]

    [1] Method is an object-oriented term for a procedure or function. You'll see it used throughout this book.

    To invoke a Java program, you run the Java interpreter, java, and specify the name of the class that contains the main() method. You should omit the .class extension when doing this. Note that a Java applet is not an application--it is a Java class that is loaded and run by an already running Java application such as a Web browser or applet viewer.

    The main() method that the Java interpreter invokes to start a Java program must have the following prototype:

    public static void main(String args[])

    The Java interpreter runs until the main() method returns, or until the interpreter reaches the end of main(). If no threads have been created by the program, the interpreter exits. Otherwise, the interpreter continues running until the last thread terminates.

    Command-Line Arguments

    The single argument to main() is an array of strings, conventionally named args or argv. The length of this array (which would be passed as the argc argument in C) is available as argv.length, as is the case with any Java array. The elements of the array are the arguments, if any, that appeared on the interpreter command line after the class name. Note that the first element of the array is not the name of the class, as a C programmer might expect it to be. Example 2.1 shows how you could write a UNIX-style echo command (a program that simply prints out its arguments) in Java.

    Example 2.1: An Echo Program in Java

    public class echo { public static void main(String argv[]) { for(int i=0; i < argv.length; i++)

  • System.out.print(argv[i] + " "); System.out.print("\n"); System.exit(0); }}

    Program Exit Value

    Note that main() must be declared to return void. Thus you cannot return a value from your Java program with a return statement in main(). If you need to return a value, call System.exit() with the desired integer value, as we've done in Example 2.1. Note that the handling and interpretation of this exit value are, of course, operating-system dependent. System.exit() causes the Java interpreter to exit immediately, whether or not other threads are running.

    Environment

    The Java API does not allow a Java program to read operating system environment variables because they are platform-dependent. However, Java defines a similar, platform-independent mechanism, known as the system properties list, for associating textual values with names.

    A Java program can look up the value of a named property with the System.getProperty() method:

    String homedir = System.getProperty("user.home");String debug = System.getProperty("myapp.debug");

    The Java interpreter automatically defines a number of standard system properties when it starts up. You can insert additional property definitions into the list by specifying the -D option to the interpreter:

    % java -Dmyapp.debug=true myapp

    See Chapter 14, System Properties for more information on system properties.

    A Simple Example The Name Space: Packages, Classes, and Members

  • Chapter 2How Java Differs from C

    2.2 The Name Space: Packages, Classes, and Members

    As a language that is designed to support dynamic loading of modules over the entire Internet, Java takes special care to avoid name space conflicts. Global variables are simply not part of the language. Neither are "global" functions or procedures, for that matter.

    No Global Variables

    In Java, every field and method is declared within a class and forms part of that class. Also, every class is part of a package (in Java 1.1, classes can also be declared within other classes). The fields and methods (and classes in 1.1) of a class are known as the members of a class. Every Java field or method may be referred to by its fully qualified name, which consists of the package name, the class name, and the member name (i.e., the field or the method name), all separated by periods. Package names are themselves usually composed of multiple period-separated components. Thus, the fully qualified name for a method might be:

    david.games.tetris.SoundEffects.play()

    Java Filenames and Directory Structure

    A file of Java source code has the extension .java. It consists of an optional package statement followed by any number of import statements followed by one or more class or interface definitions. (The package and import statements will be introduced shortly.) If more than one class or interface is defined in a Java source file, only one of them may be declared public (i.e., made available outside of the package), and the source file must have the same name as that public class or interface, plus the .java extension.

    Each class or interface definition in a .java file is compiled into a separate file. These files of compiled Java byte-codes are known as "class files," and must have the same name as the class or interface they

  • define, with the extension .class appended. For example, the class SoundEffects would be stored in the file SoundEffects.class.

    Class files are stored in a directory that has the same components as the package name. If the fully qualified name of a class is david.games.tetris.SoundEffects, for example, the full path of the class file must be david/games/tetris/SoundEffects.class. This filename is interpreted relative to the Java "class path," described below. [2]

    [2] We'll use UNIX-style directory specifications in this book. If you are a Windows programmer, simply change all the forward slashes in filenames to backward slashes. Similarly, in path specifications, change colons to semicolons.

    Packages of the Java API

    The Java 1.1 API consists of the classes and interfaces defined in the twenty-three packages listed in Table 2.1.

    Table 2.1: The Packages of the Java API

    Package name Contents

    java.applet Applet classes

    java.awt Graphics, window, and GUI classes

    java.awt.datatransfer Data transfer (e.g., cut-and-paste) classes

    java.awt.event Event processing classes and interfaces

    java.awt.image Image processing classes

    java.awt.peer GUI interfaces for platform independence

    java.beans JavaBeans component model API

    java.io Various types of input and output classes

    java.lang Core language classes

    java.lang.reflect Reflection API classes

    java.math Arbitrary precision arithmetic

    java.net Networking classes

    java.rmi Remote Method Invocation classes

    java.rmi.dgc RMI-related classes

    java.rmi.registry RMI-related classes

    java.rmi.server RMI-related classes

  • java.security Security classes

    java.security.acl Security-related classes

    java.security.interfaces Security-related classes

    java.sql JDBC SQL API for database access

    java.text Internationalization classes

    java.util Various useful data types

    java.util.zip Compression and decompression classes

    The Java Class Path

    The Java interpreter knows where its standard system classes are installed, and loads them from that location as needed. By default, it looks up user-defined classes in or relative to the current directory. You can set the CLASSPATH environment variable to tell the interpreter where to look for user-defined classes. The interpreter always appends the location of its system classes to the end of the path specified by this environment variable. The entries in a class path specification should be directories or ZIP files that contain the classes. The directories in a class path specification should be colon-separated on a UNIX system, and semicolon-separated on a Windows system. For example, on a UNIX system, you might use:

    setenv CLASSPATH .:/home/david/classes:/usr/local/javatools/classes.zip

    On a Windows system you could use:

    setenv CLASSPATH .;C:\david\classes;D:\local\javatools\classes.zip

    This tells Java to search in and beneath the specified directories for non-system classes. Note that the current directory (.) is included in these paths.

    You can also specify a class path to the Java interpreter with the -classpath command-line argument. Setting this option overides any path specified in the CLASSPATH environment variable. Note that the interpreter does not append the location of the system classes to the end of this path, so you must be sure to specify those system classes yourself. Finally, note that the Java compiler also recognizes and honors class paths specified with the CLASSPATH environment variable and the -classpath command-line argument.

    Globally Unique Package Names

    The Java designers have proposed an Internet-wide unique package naming scheme that is based on the Internet domain name of the organization at which the package is developed.

  • Figure 2.1 shows some fully qualified names, which include package, class, and field components.

    Figure 2.1: Fully qualified names in Java

    [Graphic: Figure 2-1]

    Some organizations are following this naming scheme, and producing classes with names like com.sybase.jdbc.SybDriver. Another trend that is developing, however, is for companies to simply use their company name as the first component of their package names, and produce classes like netscape.javascript.JSObject.

    The top-level package names java and sun are reserved for use by Sun, of course. Developers should not define new classes within these packages.

    The package Statement

    The package statement must appear as the first statement (i.e., the first text other than comments and whitespace) in a file of Java source code, if it appears at all. It specifies which package the code in the file is part of. Java code that is part of a particular package has access to all classes (public and non-public) in the package, and to all non-private methods and fields in all those classes. When Java code is part of a named package, the compiled class file must be placed at the appropriate position in the CLASSPATH directory hierarchy before it can be accessed by the Java interpreter or other utilities.

    If the package statement is omitted from a file, the code in that file is part of an unnamed default package. This is convenient for small test programs, or during development, because it means that the code can be interpreted from the current directory.

    The import Statement

  • The import statement makes Java classes available to the current class under an abbreviated name. Public Java classes are always available by their fully qualified names, assuming that the appropriate class file can be found (and is readable) relative to the CLASSPATH environment variable. import doesn't actually make the class available or "read it in"; it simply saves you typing and makes your code more legible.

    Any number of import statements may appear in a Java program. They must appear, however, after the optional package statement at the top of the file, and before the first class or interface definition in the file.

    There are two forms of the import statement:

    import package.class ;import package.* ;

    The first form allows the specified class in the specified package to be known by its class name alone. Thus, this import statement allows you to type Hashtable instead of java.util.Hashtable:

    import java.util.Hashtable;

    The second form of the import statement makes all classes in a package available by their class name. For example, the following import statement is implicit (you need not specify it yourself) in every Java program:

    import java.lang.*;

    It makes the core classes of the language available by their unqualified class names. If two packages imported with this form of the statement contain classes with the same name, it is an error to use either of those ambiguous classes without using its fully qualified name.

    Access to Packages, Classes, and Class Members

    Java has the following rules about access to packages, classes, and class members. (Class members are the variables, methods, and, in Java 1.1, nested classes defined within a class). Note that the public, private, and protected keywords used in these rules will be explained in more detail in the next chapter.

    A package is accessible if the appropriate files and directories are accessible (e.g., if local files have appropriate read permissions, or if they can be downloaded via the network).

  • All classes and interfaces in a package are accessible to all other classes and interfaces in the same package. It is not possible to define classes in Java that are visible only within a single file of source code.

    A class declared public in one package is accessible within another package, assuming that the package itself is accessible. A non-public class is not accessible outside of its package.

    Members of a class are accessible from a different class within the same package, as long as they are not declared private. private members are accessible only within their own class.

    Af member of a class A is accessible from a class B in a different package if A is public and the member is public, or if A is public, the member is protected, and B is a subclass of A.

    All members of a class are always accessible from within that class.

    Local Variables

    The name space rules we've been describing apply to packages, classes, and the members within classes. Java also supports local variables, declared within method definitions. These local variables behave just like local variables in C--they do not have globally unique hierarchical names, nor do they have access modifiers like public and private. Local variables are quite different from class fields.

    Program Structure and Environment

    Comments

  • Chapter 2How Java Differs from C

    2.3 Comments

    Java supports three types of comments:

    A standard C-style comment that begins with /* and continues until the next */. As in most implementations of C, this style of comment cannot be nested.

    A C++-style comment that begins with // and continues until the end of the line.

    A special "doc comment" that begins with /** and continues until the next */. These comments may not be nested. Doc comments are specially processed by the javadoc program to produce simple online documentation from the Java source code. See Chapter 13, Java Syntax for more information on the doc comment syntax, and Chapter 16, JDK Tools for more information on the javadoc program.

    Since C-style comments do not nest, it is a good idea to use C++-style // comments for most of your short comments within method bodies. This allows you to use /* */ comments to comment out large blocks of code when you need to do that during development. This is especially important because, as you will see, Java does not support a preprocessor that allows you to use #if 0 to comment out a block.

    The Name Space: Packages, Classes, and Members

    No Preprocessor

  • Chapter 2How Java Differs from C

    2.4 No Preprocessor

    Java does not include any kind of preprocessor like the C cpp preprocessor. It may seem hard to imagine programming without #define, #include, and #ifdef, but in fact, Java really does not require these constructs.

    Defining Constants

    Any variable declared final in Java is a constant--its value must be specified with an initializer when it is declared, and that value may never be changed. The Java equivalent of a C #define'ed constant is a static final variable declared within a class definition. If the compiler can compute the value of such a static final variable at compile-time, it uses the computed value to pre-compute other compile-time constants that refer to the value. The variable java.lang.Math.PI is an example of such a constant. It is declared like this:

    public final class Math { ... public static final double PI = 3.14159.....; ...}

    Note two things about this example. First, the C convention of using CAPITAL letters for constants is also a Java convention. Second, note the advantage Java constants have over C preprocessor constants: Java constants have globally unique hierarchic names, while constants defined with the C preprocessor always run the risk of a name collision. Also, Java constants are strongly typed and allow better type-checking by the compiler than C preprocessor constants.

    Defining Macros

    The C preprocessor allows you to define macros--a construct that looks like a function invocation but that is actually replaced directly with C code, saving the overhead of a function call. Java has no

  • equivalent to this sort of macro, but compiler technology has advanced to a point where macros are rarely necessary any more. A good Java compiler should automatically be able to "inline" short Java methods where appropriate.

    Including Files

    Java does not have a #include directive, but it does not need one. Java defines a mapping of fully qualified class names (like java.lang.Math) to a directory and file structure (like java/lang/Math.class). This means that when the Java compiler needs to read in a specified class file, it knows exactly where to find it and does not need a special directive to tell it where to look.

    Furthermore, Java does not make the distinction between declaring a variable or procedure and defining it that C does. This means that there is no need for C-style header files or function prototypes--a single Java object file serves as the interface definition and implementation for a class.

    Java does have an import statement, which is superficially similar to the C preprocessor #include directive. What this statement does, however, is tell the compiler that the current file is using the specified classes, or classes from the specified package, and allows us to refer to those classes with abbreviated names. For example, since the compiler implicitly imports all the classes of the java.lang package, we can refer to the constant java.lang.Math.PI by the shorter name Math.PI.

    Conditional Compilation

    Java does not have any form of the C #ifdef or #if directives to perform conditional compilation. In theory, conditional compilation is not necessary in Java since it is a platform-independent language, and thus there are no platform dependencies that require the technique. In practice, however, conditional compilation is still often useful in Java--to provide slightly different user interfaces on different platforms, for example, or to support optional inclusion of debugging code in programs.

    While Java does not define explicit constructs for conditional compilation, a good Java compiler (such as Sun's javac) performs conditional compilation implicitly--that is, it does not compile code if it can prove that the code will never be executed. Generally, this means that code within an if statement testing an expression that is always false is not included. Thus, placing code within an if (false) block is equivalent to surrounding it with #if 0 and #endif in C.

    Conditional compilation also works with constants, which, as we saw above, are static final variables. A class might define the constant like this:

    private static final boolean DEBUG = false;

  • With such a constant defined, any code within an if (DEBUG) block is not actually compiled into the class file. To activate debugging for the class, it is only necessary to change the value of the constant to true and recompile the class.

    Comments Unicode and Character Escapes

  • Chapter 2How Java Differs from C

    2.5 Unicode and Character Escapes

    Java characters, strings, and identifiers (e.g., variable, method, and class names) are composed of 16-bit Unicode characters. This makes Java programs relatively easy to internationalize for non-English-speaking users. It also makes the language easier to work with for non-English-speaking programmers--a Thai programmer could use the Thai alphabet for class and method names in her Java code.

    If two-byte characters seem confusing or intimidating to you, fear not. The Unicode character set is compatible with ASCII and the first 256 characters (0x0000 to 0x00FF) are identical to the ISO8859-1 (Latin-1) characters 0x00 to 0xFF. Furthermore, the Java language design and the Java String API make the character representation entirely transparent to you. If you are using only Latin-1 characters, there is no way that you can even distinguish a Java 16-bit character from the 8-bit characters you are familiar with. For more information on Unicode, see Chapter 11, Internationalization.

    Most platforms cannot display all 38,885 currently defined Unicode characters, so Java programs may be written (and Java output may appear) with special Unicode escape sequences. Anywhere within a Java program (not only within character and string literals), a Unicode character may be represented with the Unicode escape sequence \uxxxx, where xxxx is a sequence of four hexadecimal digits.

    Java also supports all of the standard C character escape sequences, such as \n, \t, and \xxx (where \xxxis three octal digits). Note, however, that Java does not support line continuation with \ at the end of a line. Long strings must either be specified on a single long line, or they must be created from shorter strings using the string concatenation (+) operator. (Note that the concatenation of two constant strings is done at compile-time rather than at run-time, so using the + operator in this way is not inefficient.)

    There are two important differences between Unicode escapes and C-style escape characters. First, as we've noted, Unicode escapes can appear anywhere within a Java program, while the other escape characters can appear only in character and string constants.

    The second, and more subtle, difference is that Unicode \u escape sequences are processed before the other escape characters, and thus the two types of escape sequences can have very different semantics. A

  • Unicode escape is simply an alternative way to represent a character that may not be displayable on certain (non-Unicode) systems. Some of the character escapes, however, represent special characters in a way that prevents the usual interpretation of those characters by the compiler. The following examples make this difference clear. Note that \u0022 and \u005c are the Unicode escapes for the double-quote character and the backslash character.

    // \" represents a " character, and prevents the normal// interpretation of that character by the compiler.// This is a string consisting of a double-quote character.String quote = "\"";// We can't represent the same string with a single Unicode escape.// \u0022 has exactly the same meaning to the compiler as ".// The string below turns into """: an empty string followed// by an unterminated string, which yields a compilation error.String quote = "\u0022";// Here we represent both characters of an \" escape as// Unicode escapes. This turns into "\"", and is the same// string as in our first example.String quote = "\u005c\u0022";

    No Preprocessor Primitive Data Types

  • Chapter 2How Java Differs from C

    2.6 Primitive Data Types

    Java adds byte and boolean primitive types to the standard set of C types. In addition, it strictly defines the size and signedness of its types. In C, an int may be 16, 32, or 64 bits, and a char may act signed or unsigned depending on the platform. Not so in Java. In C, an uninitialized local variable usually has garbage as its value. In Java, all variables have guaranteed default values, though the compiler may warn you in places where you rely, accidentally or not, on these default values. Table 2.2 lists Java's primitive data types. The subsections below provide details about these types.

    Table 2.2: Java Primitive Data Types

    Min Value

    Type Contains Default Size Max Value

    boolean true or false false 1 bit N.A.

    N.A.

    char Unicode character \u0000 16 bits \u0000

    \uFFFF

    byte signed integer 0 8 bits -128

    127

    short signed integer 0 16 bits -32768

    32767

    int signed integer 0 32 bits -2147483648

    2147483647

    long signed integer 0 64 bits -9223372036854775808

    9223372036854775807

    float IEEE 754 0.0 32 bits +/-3.40282347E+38

    floating-point +/-1.40239846E-45

  • double IEEE 754 0.0 64 bits +/-1.79769313486231570E+308

    floating-point +/-4.94065645841246544E-324

    The boolean Type

    boolean values are not integers, may not be treated as integers, and may never be cast to or from any other type. To perform C-style conversions between a boolean value b and an int i, use the following code:

    b = (i != 0); // integer-to-boolean: non-0 -> true; 0 -> false; i = (b)?1:0; // boolean-to-integer: true -> 1; false -> 0;

    The char Type

    char values represent characters. Character literals may appear in a Java program between single quotes. For example:

    char c = 'A';

    All of the standard C character escapes, as well as Unicode escapes, are also supported in character literals. For example:

    char newline = '\n', apostrophe = '\", delete = '\377', aleph='\u05D0';

    Values of type char do not have a sign. If a char is cast to a byte or a short, a negative value may result.

    The char type in Java holds a two-byte Unicode character. While this may seem intimidating to those not familiar with Unicode and the techniques of program internationalization, it is in fact totally transparent. Java does not provide a way to compute the size of a variable, nor does it allow any sort of pointer arithmetic. What this means is that if you are only using ASCII or Latin-1 characters, there is no way to distinguish a Java char from a C char.

    Integral Types

    The integral types in Java are byte, short, char, int, and long. Literals for these types are written just as they are in C. All integral types, other than char, are signed. There is no unsigned keyword as there is in C. It is not legal to write long int or short int as it is in C. A long constant may be distinguished from other integral constants by appending the character l or L to it.

  • Integer division by zero or modulo zero causes an ArithmeticException to be thrown. [3]

    [3] Exceptions signal errors in Java. Exception handling is described later in this chapter.

    Floating-Point Types

    The floating-point types in Java are float and double. Literals for these types are written just as they are in C. Literals may be specified to be of type float by appending an f or F to the value; they may be specified to be of type double by appending a d or D.

    float and double types have special values that may be the result of certain floating-point operations: positive infinity, negative infinity, negative zero and not-a-number. The java.lang.Float and java.lang.Double classes define some of these values as constants: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN.

    NaN is unordered--comparing it to any other number, including itself, yields false. Use Float.isNaN() or Double.isNaN() to test for NaN. Negative zero compares equal to regular zero (positive zero), but the two zeros may be distinguished by division: one divided by negative zero yields negative infinity; one divided by positive zero yields positive infinity.

    Floating-point arithmetic never causes exceptions, even in the case of division by zero.

    String Literals

    Strings in Java are not a primitive type, but are instances of the String class. However, because they are so commonly used, string literals may appear between quotes in Java programs, just as they do in C. When the compiler encounters such a string literal, it automatically creates the necessary String object.

    Unicode and Character Escapes

    Reference Data Types

  • Chapter 2How Java Differs from C

    2.7 Reference Data Types

    The non-primitive data types in Java are objects and arrays. These non-primitive types are often called "reference types" because they are handled "by reference"--in other words, the address of the object or array is stored in a variable, passed to methods, and so on. By comparison, primitive types are handled "by value"--the actual primitive values are stored in variables and passed to methods.

    In C, you can manipulate a value by reference by taking its address with the & operator, and you can "dereference" an address with the * and -> operators. These operators do not exist in Java: primitive types are always passed by value; arrays and objects are always passed by reference.

    Because objects are passed by reference, two different variables may refer to the same object:

    Button p, q;p = new Button(); // p refers to a Button object.q = p; // q refers to the same Button.p.setLabel("Ok"); // A change to the object through p...String s = q.getLabel(); // ...is also visible through q. // s now contains "Ok."

    This is not true of primitive types, however:

    int i = 3; // i contains the value 3.int j = i; // j contains a copy of the value in i.i = 2; // Changing i doesn't change j. // Now, i == 2 and j == 3.

    Terminology: Pass by Reference

    The statement that Java manipulates objects "by reference" causes confusion for some programmers, because there are several different meanings of "by reference" in common use. Regardless of what we

  • call it, it is important to understand what Java does. Java works with references to objects. A Java variable holds only a reference to an object, not the object itself. When an object is passed to a method, only a reference to the object is actually passed, not the entire object. It is in this sense that Java manipulates objects "by reference."

    Some people use the term "pass by reference" to mean that a reference to a variable is passed to a method. Java does not do this. For example, it is not possible to write a working swap() function like the following in Java:

    public void swap(Object a, Object b) { Object temp = a; a = b; b = temp;}

    The method parameters a and b contain references to objects, not addresses of variables. Thus, while this swap() function does compile and run, it has no effect except on its own local variables and arguments.

    To solve this terminology problem, perhaps we should say that Java manipulates objects "by reference," but it passes object references to methods "by value."

    Copying Objects

    Because reference types are not passed by value, assigning one object to another in Java does not copy the value of the object. It merely assigns a reference to the object. Consider the following code:

    Button a = new Button("Okay");Button b = new Button("Cancel");a = b;

    After these lines are executed, the variable a contains a reference to the object that b refers to. The object that a used to refer to is lost.

    To copy the data of one object into another object, use the clone() method:

    Vector b = new Vector;c = b.clone();

    After these lines run, the variable c refers to an object that is a duplicate of the object referred to by b. Note that not all types support the clone() method. Only classes that implement the Cloneable interface may be cloned. For more information on cloning objects, look up java.lang.Cloneable

  • and java.lang.Object.clone() in Chapter 25, The java.lang Package.

    Arrays are also reference types, and assigning an array simply copies a reference to the array. To actually copy the values stored in an array, you must assign each of the values individually or use the System.arraycopy() method.

    Checking Objects for Equality

    Another implication of passing objects by reference is that the == operator tests whether two variables refer to the same object, not whether two objects contain the same values. To actually test whether two separate objects are the same, you must use a specially written method for that object type (just as you might use strcmp() to compare C strings for equality). In Java, a number of classes define an equals() method that you can use to perform this test.

    Java Has No Pointers

    The referencing and dereferencing of objects is handled for you automatically by Java. Java does not allow you to manipulate pointers or memory addresses of any kind:

    It does not allow you to cast object or array references into integers or vice-versa.

    It does not allow you to do pointer arithmetic.

    It does not allow you to compute the size in bytes of any primitive type or object.

    There are two reasons for these restrictions:

    Pointers are a notorious source of bugs. Eliminating them simplifies the language and eliminates many potential bugs.

    Pointers and pointer arithmetic could be used to sidestep Java's run-time checks and security mechanisms. Removing pointers allows Java to provide the security guarantees that it does.

    To a C programmer, the lack of pointers and pointer arithmetic may seem an odious restriction in Java. But once you get used to the Java object-oriented programming model, it no longer seems like a serious restriction at all. The lack of pointers does mean that you probably can't do things like write UNIX device drivers in Java (at least not without using native methods written in C). But big deal--most of us never have to do this kind of low-level programming anyway.

    null

  • The default value for variables of all reference types is null. null is a reserved value that indicates "an absence of reference"--i.e., that a variable does not refer to any object or array.

    In Java, null is a reserved keyword, unlike NULL in C, where it is just a constant defined to be 0. null is an exception to the strong typing rules of Java--it may be assigned to any variable of reference type (i.e., any variable which has a class, interface, or array as its type).

    null can't be cast to any primitive type, including integral types and boolean. It shouldn't be considered equal to zero (although it may be implemented this way).

    Reference Type Summary

    The distinction between primitive types passed by value, and objects and arrays passed by reference is a crucial one in Java. Be sure you understand the following:

    All objects and arrays are handled by reference in Java. (Those object references are passed-by-value to methods, however.)

    The = and == operators assign and test references to objects. Use clone() and equals() to actually copy or test the objects themselves.

    The necessary referencing and dereferencing of objects and arrays is handled automatically by Java.

    A reference type can never be cast to a primitive type.

    A primitive type can never be cast to a reference type.

    There is no pointer arithmetic in Java.

    There is no sizeof operator in Java.

    null is a special value that means "no object" or indicates an absence of reference.

    Primitive Data Types Objects

  • Chapter 2How Java Differs from C

    2.8 Objects

    Now that you know objects are passed by reference, we should discuss how they are created, used, and destroyed. The following subsections provide a very brief overview of objects. Chapter 3, Classes and Objects in Java explains classes and objects in much greater detail.

    Creating Objects

    Declaring a variable to hold an object does not create the object itself; the variable only holds the reference to the object. To actually create an object, you must use the new keyword. This is followed by the object's class (i.e., its type) and an optional argument list in parentheses. These arguments are passed to the constructor method for the class, which serves to initialize internal fields in the new object. For example:

    java.awt.Button b = new java.awt.Button();ComplexNumber c = new ComplexNumber(1.0, 1.414);

    There are actually two other ways to create an object. First, you can create a String object simply by enclosing characters in double quotes:

    String s = "This is a test";

    Because strings are used so frequently, the Java compiler provides this technique as a shortcut. Another way to create objects is by calling the newInstance() method of a Class object. This technique is generally used only when dynamically loading classes, so we won't discuss it here. In Java 1.1, objects can also be created by "de-serializing" them--i.e., recreating an object that had its state saved through "serialization."

    The memory for newly created objects is dynamically allocated. Creating an object with new in Java is like calling malloc() in C to allocate memory for an instance of a struct. It is also, of course, a lot like using the new operator in C++. (Below, we'll see where this analogy to malloc() in C and new in

  • C++ breaks down.)

    Accessing Objects

    As you've probably noticed in various example code fragments by now, the way you access the fields of an object is with a dot:

    ComplexNumber c = new ComplexNumber();c.x = 1.0;c.y = -1.414;

    This syntax is reminiscent of accessing the fields of a struct in C. Recall, though, that Java objects are always accessed by reference, and that Java performs any necessary dereferencing for you. Thus, the dot in Java is more like -> in C. Java hides the fact that there is a reference here in an attempt to make your programming easier. The other difference between C and Java when accessing objects is that in Java you refer to an object's methods with the same syntax used for fields:

    ComplexNumber c = new ComplexNumber(1.0, -1.414);double magnitude = c.magnitude();

    Garbage Collection

    Objects in Java are created with the new keyword, but there is no corresponding old or delete keyword or free() method to get rid of them when they are no longer needed. If creating an object with new is like calling malloc() in C or using new in C++, then it would seem that Java is full of memory leaks, because we never call free() or use the delete operator.

    In fact, this isn't the case. Java uses a technique called garbage collection to automatically detect objects that are no longer being used (an object is no longer in use when there are no more references to it) and to free them. This means that in our programs, we never need to worry about freeing memory or destroying objects--the garbage collector takes care of that.

    If you are a C or C++ programmer, it may take some getting used to to just let allocated objects go without worrying about reclaiming their memory. Once you get used to it, however, you'll begin to appreciate what a nice feature this is. We'll discuss garbage collection in more detail in the next chapter.

    Reference Data Types Arrays

  • Chapter 2How Java Differs from C

    2.9 Arrays

    Most of what we learned in the previous sections about reference types and objects applies equally well to arrays in Java:

    Arrays are manipulated by reference.

    T