Java Quick Reference
Java Quick Reference
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package
Usage
q q
References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
use the menu on the left to navigate the various Certification Objective pages use the menu on the bottom of the Objective and note pages to navigate notes related to the selected Objective save and compile the Code Examples to see Java concepts in action Tips are things to be keep in mind when taking the exam Traps are things to watch out for when taking the exam Testing concepts
If you're having a problem with a concept, WRITE SOME CODE to test it! DO NOT use an IDE! Compile all your test code from the command line; this ensures you'll see all the errors the compiler may create.
Mike Meyer's Java 2 Certification Passport by Cindy Glass, Jane Griscti, Margarita Isayeva, Ajith Kallambella, and Kathy Sierra A concise, affordable and portable guide to Sun's Java 2 Exam 310-025 Errata Page Best of luck in your studies!
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
Identify correctly constructed source files, package declarations, import statements, class declarations (of all forms including inner classes), interface declarations and implementations (for java.lang.Runnable or other interfaces described in the test), method declarations (including the main method that is used to start execution of a class), variable declarations and identifiers. State the correspondence between index values in the argument array passed to a main method and command line arguments. Identify all Java programming language keywords and correctly constructed identifiers. State the effect of using a variable or array element of any kind when no explicit assignment has been made to it. State the range of all primitive data types and declare literal values for String and all primitive types using all permitted formats, bases, and representations.
Identify classes that correctly implement an interface where that interface is either java.lang.Runnable or a fully specifiec interface in the question.
The second 1.2 objective has been split with an additional note on 'keywords' q State the correspondence between index values in the argument array passed to a main method and command line arguments.
q
Identify all Java programming language keywords. Note: There will not be any questions regarding esoteric distinction between keywords and manifest constants.
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Determine the result of applying the boolean equals(Object) method to objects of any combination of the classes java.lang.String, java.lang.Boolean, and java.lang.Object. In an expression involving the operators &, |, &&, ||, and variables of known values state which operands are evaluated and the value of the expression. Determine the effect upon objects and primitive values of passing variables into methods and performing assignments or other modifying operations in that method.
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Write code using if and switch statements and identify legal argument types for these statements. Write code using all forms of loops including labeled and unlabeled use of break and continue, and state the values taken by loop control variables during and after loop execution. Write code that makes proper use of exceptions and exception handling clauses (try, catch, finally) and declares methods and overriding methods that throw exceptions.
Recognize the effect of an exception arising at a sepcified point in a code fragment. Note: The exception may be a runtime exception, a checked exception, or an error (the code may include try, catch, or finally clauses in any legitimate combination). Write code that makes proper use of assertions, and distinguish appropriate from inapporopriate uses of assertions. Identify correct statements about the assertion mechanism.
For additional study materials try: Sun: Programming with Assertions Developerworks: Working with Assertions JavaWorld: Understand the mechanics of ... new assertion facility
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package
Declare classes, inner classes, methods, instance variables, static variables, and automatic (method local) variables making appropriate use of all permitted modifiers (such as public, final, static, abstract, and so forth). State the significance of each of these modifiers both singly and in combination, and state the effect of package relationships on declared items qualified by these modifiers. For a given class, determine if a default constructor will be created, and if so, state the prototype of that constructor. (Covered under Language Fundamentals - Constructors) State the legal return types for any method given the declarations of all related methods in this or parent class. (Covered under Language Fundamentals - Method Declarations)
The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
Additional References
q
Chapter 6 Objects and Classes from The Complete Java 2 Certification Stuyd Guide by Simon Roberts, Philip Heller, Michael Ernest Sun Tech Tip: Using Class Methods and Variables Sun Tech Tip: Global Variables
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
State the behaviour that is guaranteed by the garbage collection system, and write code that explicitly makes objects eligible for collection.
1.4 Exam
The above objective has been expanded as: q State the behavior that is guaranteed by the garbage collection system.
q
Write code that explicitly makes objects eligible for garbage collection. Recognize the point in a piece of source code at which an object becomes eligible for garbage collection.
Behaviour
Eligibility
finalize()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Write code to invoke overridden or overloaded methods and parental or overloaded constructors; and describe the effect of invoking these methods. Write code to construct instances of any concrete class including normal top level classes, inner classes, static inner classes, and anonymous inner classes.
isA/hasA
Overloading
Field Variables
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Write code to define, instantiate, and start new threads using both java.lang.Thread and java.lang.Runnable. Recognize conditions that might prevent a thread from executing. Write code using synchronized, wait, notify, or notifyAll, to protect against concurrent access problems and to communicate between threads. Define the interaction between threads and between threads and object locks when executing synchronized, wait, notify, or notifyAll
1.4 Exam
The third 1.2 objective has been re-worded as: q Write code using synchronized wait, notify and notifyAll to protect against concurrent access problems and to communicate between threads.
q
Define the interaction among threads and object locks when executing synchronized wait, notify or notifyAll
Scheduling wait()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Write code using the following methods of the java.lang.Math class: abs, ceil, floor, max, min, random, round, sin, cos, tan, sqrt. Describe the significance of the immutability of String objects.
Describe the significance of wrapper classes, including making appropriate selections in the wrapper classes to suit specified behavior requirements, stating the result of excecuting a fragment of code that includes an instance of one of the wrapper classes, and writing code using the following methods of the wrappers classees 9e.g, Integer, Double, etc): r doubleValue r floatValue r intValue r longValue r parseXxx r getXxx r toString r toHexString
Main Classes
Wrapper Classes
Math Class
String Immutability
String Class
StringBuffer Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
1.4 Exam
This objective has been renamed The Collection Framework and the following has been added: q Distinguish between correct and incorrect implementations of hashcode methods.
Also see
q q q
Collections - a tutorial by Joshua Bloch The Collection Framework The Java Collections Framework
Collections Framework
Collection
Abstract Classes
Iterator
List
Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q q q q
NOT REQUIRED FOR 1.4 EXAM Write code using component, container, and LayoutManager classes of the java.awt package to present a GUI with a specified appearance and resize behaviour, and distinguish the responsibilities of layout managers from those of containers. Write code to implement listener classes and methods, and in listener methods, extract information from the event to determine the affected component, mouse position, nature and time of the event. State the classname for any specified event listener interface in the java.awt.event package. Pay Attention to which Layout Managers implement LayoutManager2 one thing I discovered (after I wrote the exam!) that is of prime importance in the way containers handle components when they are resized is knowing which Layout Interface the active LayoutManager implements. Any Layout Manager that extends the LayoutManager2 Interface keeps track of their own components. What this means in practice is that if the layout manager is set after components have been added to the container and the layout manager implements the LayoutManager2 interface, no components will be visible. LayoutManager2 type managers do not query the container for a list of components, they maintain their own list. FlowLayout and GridLayout, both implement LayoutManager. When the container is resized they will query the container for a list of the components and then layout them out according to their contract. CardLayout, BorderLayout, GridBagLayout, BoxLayout, and OverlayLayout implement the LayoutManager2 interface. If the container is resized they rely on their own, internal list of components. Components added to a container before the LayoutManager was added will not be known and hence not included in the layout when the container is resized. Note
I haven't gotten around to re-writing my original notes. They are located at http://members.rogers.com/jgriscti/awt.html
Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
NOT REQUIRED FOR 1.4 EXAM Write code that uses objects of the file class to navigate a file system. Write code that uses objects of the classes InputStreamReader and OutputStreamWriter to translate between Unicode and either platform default or ISO 8859-1 character encoding and distinguish between conditions under which platform default encoding conversion should be used and conditions under which a specific conversion should be used. Select valid constructor arguments for FilterInputStream and FilterOutputStream subclasses from a list of classes in the java.io package. Write appropriate code to read, write, and update files using FileInputStream, FileOutputStream and RandomAccessFile objects. Describe the permanent effects of the file system of constructing and using FileInputStream, FileOutputStream, and RandomAccessFile objects.
Tip
q
Also see
q
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes
Sun Sites
q q q
Sun Certified Programmer for the Java 2 Platform certification objectives. (JSK) Java 2 Platform Standard Edition v 1.3 (JLS) Java Language Specification
Books
On-line
q q q q
Thinking In Java by Bruce Eckel Essentials of the Java Programming Language: A Hands on Guide, Part 1 Essentials of the Java Programming Language: A Hands on Guide, Part 2 Writing Advanced Applications for the Java Platform
Hardcover
q
SCJA Notes
q
(JPL) The Java Programming Language Second Edition by Ken Arnold and James Gosling, The Java Series, Addison Wesley, 1998 (CPJ) Concurrent Programming in Java Second Edition: Design Principles and Patterns by Doug Lea, The Java Series, Addison Wesley, 2000 (JCL1) The Java Class Libraries Second Edition, Volume 1 by Patrick Chan and Rosanna Lee, The Java Series, Addison Wesley, 1998 (JCL2) The Java Class Libraries Second Edition, Volume 2 by Patrick Chan and Rosanna Lee, The Java Series, Addison Wesley, 1998 (JCLS) The Java Class Libraries Second Edition, Volume 1: Supplemental for the Java 2 Platform, Standard Edition, v1.2 by Patrick Chan, Rosanna Lee, and Douglas Kramer, The Java Series, Addison Wesley, 1999 (GJ) Graphic Java: Mastering the AWT by David M. Geary and Alan L. McClellan, SunSoft Press, 1997 (JJ) Java 2 Certification by Jamie Jaworski, New Riders, 1999 (BB) Java Certification Exam Guide for Programmers and Developers by Barry Boone, McGraw Hill, 1997 (VA) Programming with VisualAge for Java by Marc Carrel-Billiard and John Akerley, Prentice-Hall, 1998
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
Tips
q q
an empty source file will compile without error if a .java file does not contain a public class or interface it can have any name a single-type import will take precedence over an import-on-demand import-on-demand types do not increase the size of the compiled code ie only the types actually used are added to the code while import-on-demand adds no overhead to the compiled code, they can slow down the speed of the compile a constructor body can include a return statement providing no value is returned any method can throw a Runtime or Error exception without declaring it in the throws clause methods having the same name and parameter types do not have the same signature unless the parameter types are listed in the same order main() can be declared final main() is inherited and can be overridden if not declared as final args[0] references first command line argument after the application name ( arrays in Java are zero-based) main() can be declared public static void ... or static public void ... the variable name does not have to be args; can be anything as long as the type is String[] variables can have the same name as a method or a class only field variables are automatically initialized to their types default value; local variables must be explicitly initialized arrays are initialized to the default value of their type when they are created, not declared, even if they are local variables array index operator [] has highest level of precedence integer variables can be used as array dimension values postfix/prefix operators have the highest level of precedence remember that when the postfix operator is used in an expression, the current value of the variable is used a class may be assigned to an Interface type if the class implements the interface or one of it's sub-interfaces you cannot cast a primitive type to an object reference, or vice versa you cannot cast a boolean type to another primitive type String operations whose result does not alter the original string (ie calling toUpperCase() on a String that is already in uppercase) return the original string reference; otherwise they return a reference to a new String Strings are immutable; the original String value can never be changed all the primitive type wrapper classes override the Object.equals() method to compare the
q q
q q
q q q
q q
Feedback
q q
q q
value of the objects; the default Object.equals() method checks if the variables reference the same object
q q
you do not have to have a default statement in a switch() block the default statement in a switch() blcok can appear anywhere in the construct, does not have to be last all sections of the for() loop are optional finalize() can only be executed once on any object
Traps
q q q q
code with package or import declarations given in wrong order more than one package declaration file with more than one public class or interface declaration filename.java does not match name of public class declared in the file single-type imports for two classes in different packages but with the same simple name single-type import with the same simple name as a class defined in the source file attempting to import a package vs a type ie import java.util vs import java.util.* class attempting to extend more than one other class class declared both final and abstract an interface method declared as native or synchronized an interface method declared as static subclass with default constructor when the superclass does not have a no-args constructor or it's no-arg constructor has a throws clause constructor declared with a return type an abstract method also declared private, native, final, synchronized, or strictfp an abstract method declared in a non-abstract class a native or abstract method with a method body method returning a type which is not convertible to the declared return type a void method returning a value a static method referencing this or super main() declared other than according to the standard convention local (automatic) variables declared with a modifier other than final identifiers names beginning with a number or # sign main listed as a possible keyword capitalized words listed as possible keywords; particularly wrapper classes Integer, Boolean, etc C/C++ keywords listed as possible Java keywords an empty string vs null as the default value for a String object incorrect array declaration statements, particularly:
q q q
q q
q q
q q q q q q
q q
q q
q q q
arrayType [#] varName; incorrect array initialization statements, particularly: arrayType[] varName = new arrayType[2]; varName = { value, value, value }; negative values for array index long value for array index array declaration used as an array creation statement variables of primitive type handled as Objects using the char literals \u000A or \u000D in comments or Strings String literal "c" assigned to char type using == operator to compare values of two different string reference variables variables requiring narrowing conversion being passed to methods without using a cast assigning a typed byte or short variable to a char variable floating point operation throwing an ArithmeticException Bitwise operator precdence is: & ^ | assigning subclasses with the same parent to each other assigning a parent class to a subclass without a cast result of an integer operation on byte or short types being assigned to a byte or short without an explicit cast a non-boolean value used for operand1 in a ternary expression using == to compare the contents of two different String objects using a new value based on a short-circuit operation that was never evaluated code that results in a primitive value being changed in a method (can't happen) code that results in an unchanged object value when it was changed in a method failing to cast a value to match a method parameter type ie assuming narrowing conversion on a method call a non-boolean value used in a loop or if( ) statement using the assignment operator '=' vs '==' in an loop or if() statement using an expression vs a value promotable to int in a switch() block switch() blocks with duplicate case values switch() blocks with incorrectly 'typed' case statements switch() blocks with missing break statements (unintentionally causing code to fall through to next case) attempting to access a variable declared in the initialization outside of the for-loop for()loop with incorrect initialization expression for()loop with a non-boolean expression a question that targets a specific object for garbage collection (can't be done) a question that presumes to force the gc to run (can only suggest it run)
q q q
q q
q q
q q
q q q
q q
q q q q
q q q
q q
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Mock Exams
A complete list of Mock Exams can be found on Maha Anna's JavaRanch site Another list of Mock Exams by Levteck Getting Certified in Java A Java SCJP Mock Exam by Ashok Gupta rated, by Levteck, as one of the more difficult mock exams. The site also contains study notes.
Home SCJP2 Study Notes Case Studies Tech Articles SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Case Studies
Learning how to put an OOP application together is not an easy task. While there is lots of information available on the Java language and numerous books and articles on using various OO methods and notations there are very few resources that marry the two in a format that's helpful to beginners. One tried and true method of learning how to program is to study the code created by other programmers. Posted here are the results of my own look at code written and designed by others. What's the basis for my choosing a case study? Right now it's pretty simple. The code must be 1. available, preferably on the web 2. it must utilize multiple user defined types The pages in this section will also be laid out slightly different than the rest of the site. MailMerge An example of a classic batch processing application implemented in Java. The design incorporates a Singleton pattern. JCalculator An example of a calculator component that can be used in any application. The design incorporates a Command pattern.
Home SCJP2 Study Notes Case Studies Tech Articles SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Basics
q q q q q q q q q q q q q q
Accessing the environment from Java applications Constructor and Initialization Ordering Class and Object initialization Default Constructors Destroying Objects How arguments are passed to Java methods Interfaces and Constants Narrowing and Widening Conversions Overload Resolution Shadowing Understanding Expression Evaluation Order Using Assertions Using Import Declarations Using Variable length argument lists
Class Design
q q q q q q q q q q q q q q
Abstract Classes Abstract Classes vs Interfaces Anonymous Classes Cloning Objects Java Design Patterns 101 (Developerworks tutorial) Joshua Bloch: A conversation about design Local Classes Making defensive copies of objects Making deep copies of objects Returning multiple values from a method Using Adapters Using Class methods and variables Use stack variables whenever possible When not to Overload Methods
Collections
q q
Choosing a Collections Framework Implementation Using Iterators Maintaining Insertion order in Collections Maintaining a Priority Queue Manipulating Arrays Sorting Arrays Sorting Lists Sorting with Comparators(Using Method Pointers) The Enumeration interface The RandomAccess Interface Using ArrayList and LinkedList Using Enumerations in Java Programming Using HashSet, LinkedHashSet and TreeSet Using Hashtable Using List Collections efficiently Using the LinkedHashMap Class Using Sets Using Vector in the Collections Framework Using Zero-Length Arrays
Exceptions
q q q q q q q q q q
Using Exceptions Finally clauses Guidelines and tips on when and how to use exceptions Handling InterruptedExceptions Handling Uncaught Exceptions Reusing Exceptions Stack Trace Elements Use the finally keyword to avoid resource leaks Using finally vs finalize for resource cleanup Why finalizers should (and can) be avoided
Graphics
q q q q
Blending Images Drawing and rendering simple graphic images without suffering a serious performance hit Providing a Scalable Image Icon Using the BitSet Class
I/O
q q q q
Capturing standard output in a log file Converting Pathnames to URLs File Channles Filter Streams
I/O Redirection Improving Java I/O Performance Improving I/O Performance with buffering Improving Serialization performance with Externalizable Piped Streams Programming with Buffers Programming with File Attributes Random Access for Files Reading and writing Unicode using I/O Stream Encodings Reading from Output Streams Serialization in the real world Serialization and Transient values Temporary Files Using Charsets and Encodings Using Checksums Using ReadResolve Using the PushbackReader Class Using the Serialiazable Fields API
HTML
q
Java Tools/Extras
q q q q q q q q q
A custom utility class for JavaHelp software Adding Help to your applications with JavaHelp software Capturing Audio with the Sound API Creating a HelpSet with JavaHelp software Fundamentals of JavaMail API Generating custom taglets (JavaDoc) Getting started with Java Management Extensions (JMX) Reading files from Java Archives (Jars) (An addendum to this article) Sending mail with the JavaMail API
Math
q q q q q q q q q
BigDecimal Character (using the Character class) Formatting BigDecimal Numbers Format currencies Format Dates Formatting Decimal Numbers Generating integer random numbers Performing exact calculations with floating-point numbers Representing currencies
Some things you should know about Floating Point Arithmetic Using Random Numbers for Testing and Simulation Working with Number Bases (binary, decimal, octal, hex)
Miscellaneous
q q q q q q q q q
Compiling source directly from a program Converting C programs to Java Discovering the calling methods name Goto statements and Java programming Invoking programs from Java applications Unpacking Zip files Producing MIDI Sound Using Method Pointers Using runtime.exec to invoke child processes
Optimization
q
Patterns
q q q
Employ Factory Methods to best advantage Singleton: Limit class instances with a modified singleton Singleton: Creating thread-safe singletons
Reflection
q q q q
Reflection Using java.lang.Class Using Reflection to Create Class Instances Using Reflection to test methods and classes
RMI
q q q q
Dynamic Class Loading in RMI The LifeCycle of an RMI Server Using RMI to access legacy databases A Java RMI server framework
Strings
q q q q q
String vs StringBuffer Collators Interning Strings Optimizing String Performance String Concatenation and Performance
Optimizing StringBuffer Usage StringBuffer editing String tokenization using StreamTokenizer String tokenization using StringTokenizer Using BreakIterator to parse text Using the CharSequence Interface Using the java.lang.Character class Writing toString Methods
Swing
q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q
Automating GUI programs with java.awt.Robot Borders Build a better GUI Creating a File Chooser Create a Splash Screen Creating Image Thumbnails Creating Modal Internal Frames (with a JOptionPane) Creating Round buttons Creating Tree Tables, Part 1, Part 2, Custom Carets (cursors) Cut, Copy and Paste Displaying element level tool tips for Swing components Drag and Drop Fundamentals Drag and Drop, Part 1 , Part 2 Dragging Text and Images with Swing Effective Layout Management Fonts (working with) Handling Keyboard Focus JColorChooser JFileChooser JFileChooser(Implementing type-ahead feature) JFormattedTextField (and regular expresssions) JList (advanced programming) JList (Making sure your JList index is visible) JMenu (displaying large menus) JScrollableDesktopPane (create a virtual, scrollable desktop) JSpinner(selecting from an ordered list) JTabbedPane JTable (cell rendering) JTable (displaying multi-column lists) Set your table options JTextField (validating numerical input) JTextPane JToolTips (customizing)
JTree (manipulating hierarchical data) JTree (understanding TreeModel) Keymaps Loading text files in Swing efficiently Look and Feel Make a Splash Screen in Swing Performance secrets in Swing Press Esc to close Dialog windows Printing in Swing Saving and reconstituting Swing components Tracking locations in a Document Undoing Text edits Using Swing Timers Using the GraphicsEnvironment class Swing model filtering (Using filter objects to reinterpret data and state models) The Java Foundation Classes(The new standard for Java GUI development) Using Progress bars and Monitors in Java GUI Applications Using Timers in Swing Applications
Text in Swing
q q q q q q q q q q q q
Converting Numeric Entities Displaying Multiline text Displaying text in multiple styles Text Overview Text attributes Modeling Text in Documents Pattern Matching (java.util.regex) The Element Interface Tabbing Sizing text with FontMetrics Customizing a Text Editor Concurrency in Swing Text
Threads
q q q q q q q q q
Acquire multiple locks in a fixed, global order Do not reassign the object reference of a locked object Ease your multithreaded application programming (Producer-Consumer) Exploiting ThreadLocal to enhance scalability Can ThreadLocal solve the double-checked locking problem? Minimizing the overhead of synchronized blocks Multi-threading in Java programs Piped Streams (to communicate between threads) Programmatically choose threads for notification
Protecting shared resources with synchronized blocks Understand that for methods, synchronized locks objects, not methods or code Using synchronized or volatile when accessing shared variables Using Synchronized Statements Using Timers to run tasks on a background thread Writing efficient thread safe classes
This spot will eventually host study notes for the Sun Certified Java Architect Certification Exam. Useful SCJA sites you may want to check out: q SCJA 2 Study Notes by Aaron Robinson
q
Martin Fowler's where you'll find a wealth of information on UML, Extreme Programming, Patterns and other design topics. ArgoUML a free CASE Tool.
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
I haven't completed the assignment or passed the SCJD ... these notes are being built as I go.
!!! ALWAYS CHECK SUN'S SITE FOR THE LATEST OBJECTIVES !!!
Overview
The exam consists of two parts: 1. A programming assignment 2. An examination to be taken at a test center. This exam contains multiple-choice and essay questions relating to the programming assignment. There is no time limit on completing the assignment. Quote from Sun Basically, the SCJD is testing your ability to apply the Java core API set to code the solution to a problem. Because it is a programming assignment, you do not have a set time frame in which to complete the assignment. So, you can get the assignment and determine the studying you need to do. Questions and Answers about Java Platform Certification It is recommended that you track your design decisions as the exam portion will ask you to explain why you opted for one design feature over another. Also, register for the exam immeadiately upon uploading your assignment, while your assignment is still fresh in your mind. The majority consensus (from what I've seen in the forums) is that the assignment takes roughly 120 hours of work to complete.
Assignment features
The assignment requires the following features: q a GUI for viewing information. Must demonstrate good principles of design. The specific design requirements will be provided in the assignment instructions. q database extensions to support a flexible search and record locking q network server functionality for the database systems. q communications functionality to connect the user interface with the database. The server must be multi-threaded and thread safe. q the application must be able to run in either stand-alone or network mode q the GUI interface must be flexible enough to allow the easy implementation of future enhancements
source and object code Javadoc documentation Database server documentation User interface (client) documentation a README file
Marking
The programming assignment is worth 155 points, you need 124 points to pass Marks are based on the following criteria: q General Considerations (58) r ease of use (23) r coding standards and readability (23) r clarity and maintainablity of the design and implementation (12) q Documentation (20) r user documentation (10) r javadoc source documentation (5) r comments (5) q User Interface (24) r layout uses accepted GUI principles q Server Design (53) r locking (30) r error handling (8) r search algorithm: clarity and efficiency (15)
Application Design: Use cases, CRC, UML, Patterns GUI Design using Swing components and event handling Database processing Networking: Client-Server design, TCP/IP, Sockets, RMI, I/O Streams, Object Serialization Threads: implementing multi-threading Error and Exception handling Security profiles Documentation: JavaDoc, User Guide, Install instructions
The Dallas SCJD Study Group Brian Thorn received full marks for his Documentation (Note: These links have not been working lately. It's possible Mr. Thorn has removed his pages.) r Programming Notes example
r
There doesn't appear to be all that much out there. If you come across a good resource site, please let me know!
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
OOD
OOP
Resources
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
Resources
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
Searching
q
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing
Custom Networking tutorial on Sun's site. Chapter 17 Writing the Network Protocol from Java 2 The Complete Certification Study Guide by Simon Robers, Philip Heller, and Michael Ernest
Sun's RMI White Paper Sun's Guide to RMI Fundamentals of RMI: Short Course By jGuru on Sun's site. Tutorial may be downloaded Building a Java Chat Server tutorial by Greg Travis on the IBM Developerworks site. The tutorial covers the problems inherent in building a server and techniques for over-coming them. The tutorial is free and can be downloaded but you need to register first. Distributed Computation with Java Remote Method Invocation a basic RMI tutorial by Kevin Henry. LifeCycle of an RMI Server (Sun Tech Tip) Dynamic Class loading in RMI (Sun Tech Tip) JavaWorld RMI Article Index An index of all the RMI articles published at JavaWorld.
Networking Threads
q
Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
q q
RMI Tools
q q q
rmic - The Java RMI Stub Compiler rmiregistry - The Java Remote Object Registry rmid - The Java RMI Activation System Daemon
Sockets
q
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads
Learn how to implement a read/write lock Singletons, critical sections and read/write locks Acquire multiple locks in a fixed, global order Do not reassign the object reference of a locked object Exploiting ThreadLocal to enhance scalability Ease your multithreaded application programming (Producer-Consumer) Can ThreadLocal solve the double-checked locking problem? Minimizing the overhead of synchronized blocks Multi-threading in Java programs Piped Streams (to communicate between threads) Programmatically choose threads for notification Protecting shared resources with synchronized blocks Understand that for methods, synchronized locks objects, not methods or code Using synchronized or volatile when accessing shared variables Using Synchronized Statements Using Timers to run tasks on a background thread Writing efficient thread safe classes Double-checked locking: Clever, but broken. Do you know what synchronized really means? (JavaWorld) Warning! Threading in a multiprocessor world Find out why many tricks to avoid synchronization overhead just don't work. (JavaWorld)
Security
q
Java Quick Reference - SCJD Study Notes - Error and Exception Handling
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing
Sun Tutorial on Exceptions Using Exceptions Exception Handling: The good, the bad and the ugly (Article by Michael C. Daconta) The Proper Way to do Exception Handling (Article by Brian Maso) Exceptions in Java: Nothing Exceptional about them (Article by Gaurav Pal and Sonal Bansal) Using your own exception classes in Java (Article by Keld H. Hansen)
Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes
Security in Java 2 SDK 1.2 (Sun tutorial) Java's Security Architecture (Article by Bill Venners) Java security: How to install the security manager and customize your security policy (Article by Bill Venners) Java Security API - Example
Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
JavaDoc Tool Home Page How to put comments in your code with JavaDoc Java theory and practice: I have to document THAT? Integrated documentation a la Javadoc is both a benefit and a burden
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Projects is a rather glorified name for this section. Right now it's just small examples. q PropertiesViewer - display the system properties returned by System.getProperties() in a JTree.
q
ClassBrowser - A simple Java class browser. FieldValidation - The example uses InputVerifier's to validate user input. Calculator - a simple calculator that uses method reflection to invoke commands. CalendarComboBox - a custom 'date' input component that mimics a combo-box, displaying a perpetual calendar as it's drop-down.
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
JavaRanch JavaRanch hosts numerous discussion groups related to all areas of Java Development: SCJP, SCJA and SCJD Certification, EJB, XML, JSP and much, much more including CattleDrive (Java College) where you can write practice assignments and have someone nitpick your code for free! JCHQ Java Programmer Certification Exam and Training. Popular site created by Marcus Green. Discussions, tutorials, FAQ's and more. JavaChina A SCJP Certification site created by Roseanne Zhang. Contains a large Certification FAQ, code examples and much more!
Sun Sites
Tutorials
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Site Design
The site is built and maintained by myself using HomeSite from Allaire I swiped the folder and page icons from Jeff Rouyer, author of Dynamic HTML: Web Magic.
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Sun site geared to Java newbies. Contains an overview of the language, how to get started learning and using Java, and links to other resources. Certification Objectives and exam details. Download site for latest Java 2 Software Development Kit View or download the Java Language Specification. View or download the Java Virtual Machine Specification.
Glossary Glossary of Java Technology related terms. Code Conventions On-line document outlining coding conventions for the Java Programming Language Technical Articles Numerous articles on various aspects of the Java platform: Collections, JDBC, Programming, JavaBeans, Graphics, etc. Tech Tips Tips, Techniques and sample code. Bugs Database containing reported Bugs. You need to register with the site before you can access the database. Applets Sample applets contributed by Java enthusiasts or created at Sun. Code Samples Code snippets (examplets) showing how to handle various common tasks. Forte Resources Developer resource for Sun's Java Development IDE, Forte for Java. Includes links to the FAQ, Technical Articles, Newsgroups, Documentation and Downloads. Sun Sites Tutorials On-line Books Resource Sites
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
The Java Tutorial viewable on-line or may be downloaded. Thinking in Java Popular tutorial by Bruce Eckel. Download the html version. Introduction to Computer Science using Java Interactive tutorial created by Bradley Kjell of Cental Connecticut State University. Assumes no prior programming experience. Introduction to Programming Using Java Tutorial written by David Eck of Hobart and William Smith Colleges. May be taken on-line or downloaded. Java Tutorials A series of Java tutorials available in the Objective Viewpoint column written by George Crawford III for ACM Crossroads, an student online magazine. Pure Java Education Center Collection of Java "how-to" articles, tips, techniques and source code. Brewing Java A basic Java tutorial by Elliot Rusty Harold. Java Tutorials Java 2 Certification Java Jems JSP Tutorial JDBC Tutorial A collection of introductory Java Tutorials from Free Java Help. A popular tutorial created by Marcus Green geared to the Java 2 Certification Objectives Tutorials for beginners and SCJP certification. Tutorial on Java Servlets Tutorial on Java Database Connectivity from the Web Developers Virtual Library. On-line Books Resource Sites
Sun Sites
Tutorials
This book is about the fundamentals of data structures and algorithms--the basic elements from which large and complex software artifacts are built. A list of Java online books made available by InformIt. Complete tutorial on the Java Language. Covers a wide variety of topics: RMI, JDBC, Applets, etc. This is a free, online textbook on introductory Java programming. Lots of excercises and example code.
Java by Example SCJD Notes Java Expert Solutions Projects Favourite Links About Feedback Focus on Java Programming
Sun Sites
Tutorials
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Java FAQ from the computer-lang/java/programmers/faq newsgroup. Updated weekly. Collection of free Java applets. Java resource site. Contains articles, links to other resources.
Gamelan One of the oldest and most popular Java resource sites. JavaWorld Java How-To's and Tutorials from JavaWorld magazine. Other resources A number of people have written study notes and built Java related sites. Browse the Java Certification web-ring (see bottom of page) to find others.
Sun Sites
Tutorials
PropertiesViewer.java
package ca.janeg.properties; import import import import import import import import import import import import import import import java.awt.Dimension; java.util.Iterator; java.util.Properties; java.util.Set; java.util.StringTokenizer; java.util.TreeMap; javax.swing.JPanel; javax.swing.JOptionPane; javax.swing.JScrollPane; javax.swing.SwingUtilities; javax.swing.JTree; javax.swing.event.TreeSelectionListener; javax.swing.event.TreeSelectionEvent; javax.swing.tree.TreeSelectionModel; javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.JFrame; /** Displays system properties in a sorted, categorized tree heirarchy. * Select a property node to display its corresponding value. * * @author Jane Griscti [email protected] * @version 1.0 Dec-21-2001 */ public class PropertiesViewer extends JPanel{ private Properties props = System.getProperties(); private JTree tree; private JPanel owner; /** Creates a JPanel containing a JTree. Nodes are categorized * according to the first element of the property name. For example, * all properties beginning with 'java' are categorized under * the node 'java'. */ public PropertiesViewer(){ super(); owner = this; createSortedTree(); JScrollPane jsp = new JScrollPane( tree ); jsp.setPreferredSize( new Dimension( 400, 300 ) ); jsp.setMinimumSize( getPreferredSize() ); add( jsp ); } /** Builds the JTree. The properties are given to a TreeMap, which automatically * sorts them. The keys from the TreeMap are used to create the JTree nodes. * A StringTokenizer is used to extract the first portion of the property name * to build category nodes. */ private void createSortedTree(){ DefaultMutableTreeNode top = new DefaultMutableTreeNode("System Properties"); Set keySet = new TreeMap(props).keySet(); Iterator iter = keySet.iterator();
http://www.janeg.ca/projects/properties/PropertiesViewer.java.html (1 of 3) [15/03/2004 8:46:33 AM]
PropertiesViewer.java
DefaultMutableTreeNode key = null; DefaultMutableTreeNode category = null; String currentCategory = ""; String newCategory = ""; while( iter.hasNext() ){ key = new DefaultMutableTreeNode( iter.next() ); StringTokenizer stok = new StringTokenizer( (String)key.getUserObject(), "." ); newCategory = stok.nextToken(); if( !currentCategory.equals(newCategory) ){ currentCategory = newCategory; category = new DefaultMutableTreeNode( newCategory ); top.add( category ); } category.add( key ); } tree = new JTree( top ); tree.putClientProperty("JTree.lineStyle", "Angled" ); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener( new TreeListener() ); } /** The JTree listener. When a property node is selected a JOptionPane * is created to display the value associated with the property. */ private class TreeListener implements TreeSelectionListener{ public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if (node == null) return; Object nodeInfo = node.getUserObject(); if (node.isLeaf()) { String property = (String)nodeInfo; String value = props.getProperty( property ); if( value.equals("") ){ value = "No associated value."; } JOptionPane.showMessageDialog( owner, value, property, JOptionPane.INFORMATION_MESSAGE); } } } /** Demos the PropertiesViewer. */
http://www.janeg.ca/projects/properties/PropertiesViewer.java.html (2 of 3) [15/03/2004 8:46:33 AM]
PropertiesViewer.java
public static void main(String[] args){ JFrame frame = new JFrame("Properties Viewer Demo"); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); PropertiesViewer pv = new PropertiesViewer(); frame.getContentPane().add( pv ); frame.pack(); frame.setVisible( true ); } }
The UML
The UML diagram. The ClassBrowser class diagram. The CBClassGroup class diagram. The CBClassInfo class diagram. The CBDocument class diagram. The CBTreePanel class diagram. The CBTextPane class diagram. The FieldGroup class diagram. The ConstructorGroup class diagram. The MethodGroup class diagram. The ParsedClassName class diagram. The NameComparator class diagram. The AccessSeparator class diagram.
Refactoring Notes
Probably could be refactored to use a Group interface or abstract class as the ConstructorGroup, FieldGroup and MethodGroup have identical functionality; the only difference being the type of their attributes. The text display could also using some cleaning up. It would be nice to display the access groups using different colours: red for 'private', 'green' for public, etc.
Home | Projects
http://www.janeg.ca/projects/cb/images/cbScreenShot.jpg
http://www.janeg.ca/projects/cb/images/cb_uml_1.gif
http://www.janeg.ca/projects/cb/images/classBrowser_uml.gif
http://www.janeg.ca/projects/cb/images/cbClassGroup_uml.gif
http://www.janeg.ca/projects/cb/images/cbClassInfo_uml.gif
http://www.janeg.ca/projects/cb/images/cbDoc_uml.gif
http://www.janeg.ca/projects/cb/images/cbTreePanel_uml.gif
http://www.janeg.ca/projects/cb/images/cbTextPane_uml.gif
http://www.janeg.ca/projects/cb/images/fldGroup_uml.gif
http://www.janeg.ca/projects/cb/images/ctorGroup_uml.gif
http://www.janeg.ca/projects/cb/images/methodGroup_uml.gif
http://www.janeg.ca/projects/cb/images/parsedClassName_uml.gif
http://www.janeg.ca/projects/cb/images/nameComparator_uml.gif
http://www.janeg.ca/projects/cb/images/accessSep_uml.gif
ClassBrowser.java
package ca.janeg.cb; import import import import import import import import import import import import import java.awt.Dimension; java.awt.event.ActionEvent; java.awt.event.ActionListener; java.io.File; java.io.IOException; java.util.zip.ZipException; java.util.zip.ZipFile; javax.swing.JFrame; javax.swing.JMenu; javax.swing.JMenuBar; javax.swing.JMenuItem; javax.swing.JScrollPane; javax.swing.JSplitPane;
/** * A simple Java class browser.<p> * Takes a .jar or .zip archive, extracts the class names and * displays them in a JTree by package or alphabetically.<p> * Selecting a class displays it's superclasses, fields, * constructors and methods in an adjacent JTextPane. * *@author Jane Griscti [email protected] *@created January 26, 2002 */ public class ClassBrowser extends JFrame { private JSplitPane mainPanel; private CBTreePanel treePanel; private CBTextPane textPane = new CBTextPane();
/** * Constructs a new ClassBrowser object * * @param cbcg a CBClassGroup object */ public ClassBrowser( final CBClassGroup cbcg ) { super( "ClassBrowser" ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); treePanel = new CBTreePanel( this, cbcg ); JScrollPane tsp = new JScrollPane( textPane ); tsp.setPreferredSize( new Dimension( 500, 300 ) ); tsp.setMinimumSize( tsp.getPreferredSize() ); mainPanel = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, treePanel, tsp ); getContentPane().add( mainPanel ); createMenuBar(); pack();
http://www.janeg.ca/projects/cb/ClassBrowser.html (1 of 3) [15/03/2004 8:46:37 AM]
ClassBrowser.java
setVisible( true ); }
/** Builds the menu bar. */ private void createMenuBar() { JMenu menu = new JMenu( "View" ); menu.setMnemonic( 'v' ); JMenuItem pkgItem JMenuItem classItem = new JMenuItem( "by Packages" ); = new JMenuItem( "by Class" );
pkgItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent evt ) { treePanel.switchToPkgTree(); } } ); classItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent evt ) { treePanel.switchToClassTree(); } } ); pkgItem.setMnemonic( 'p' ); classItem.setMnemonic( 'c' ); menu.add( pkgItem ); menu.add( classItem ); JMenuItem exitItem = new JMenuItem( "Exit" ); exitItem.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent evt ) { dispose(); System.exit(0); } } ); exitItem.setMnemonic( 'x' ); JMenuBar menuBar = new JMenuBar(); menuBar.add( menu ); menuBar.add( exitItem ); setJMenuBar( menuBar ); }
ClassBrowser.java
void displayClassInfo( final String className ) { textPane.displayClassInfo( className ); } private static void exit(){ System.exit(1); }
/** * The main program for the ClassBrowser class * *@param args The command line arguments */ public static void main( String[] args ) { if( args.length == 0 ) { System.out.println( "Usage: java ClassBrowser filepath" ); System.out.println( " where, filepath is the full path to the archive file" ); System.out.println( " containing the class or source files." ); System.out.println( " e.g. c:/j2sdk1.4.0_01/src.zip" ); exit(); } CBClassGroup cbcg = null;
try { cbcg = new CBClassGroup( new ZipFile( new File( args[0] ) ) ); } catch( ZipException e ) { System.out.println( args[0] + " is not a valid .jar or .zip file." ); exit(); } catch( IOException e ) { System.out.println( args[0] + " is not a valid file path." ); exit(); } ClassBrowser cb } } = new ClassBrowser( cbcg );
AccessSeparator.java
package ca.janeg.cb; import java.util.ArrayList; /* * Takes an array of objects and uses their string names to separate * the elements by their access levels. * * @author Jane Griscti [email protected] * @created January 13, 2002 */ class AccessSeparator { /* * Checks the name of an object for one of the four access levels: * public, protected, private or default and returns four ArrayLists * with the objects separated accordingly. */ static Object[] separate( final Object[] obj ) { ArrayList pub = new ArrayList(); ArrayList pro = new ArrayList(); ArrayList pri = new ArrayList(); ArrayList pkg = new ArrayList(); String name = null; int index = 0; for( int i = 0; i < obj.length; i++ ) { name = obj[i].toString(); if( name.indexOf( "public" ) >= 0 ) { pub.add( obj[i] ); } else if( name.indexOf( "protected" ) >= 0 ) { pro.add( obj[i] ); } else if( name.indexOf( "private" ) >= 0 ) { pri.add( obj[i] ); } else { pkg.add( obj[i] ); } } return new Object[]{pub, pro, pri, pkg}; } }
CBClassGroup.java
package ca.janeg.cb; import import import import import import import import import import java.io.File; java.io.IOException; java.util.ArrayList; java.util.Collection; java.util.Collections; java.util.Comparator; java.util.Enumeration; java.util.StringTokenizer; java.util.zip.ZipEntry; java.util.zip.ZipFile;
/** * Constructs a new CBClassGroup object by extracting * class names from a .jar or .zip archive file. * Extracted class names are stored for retreival by package or * alphabetically by name. * *@author Jane Griscti [email protected] *@created January 5, 2002 */ class CBClassGroup { private ArrayList entries = new ArrayList(); private String[] sortedByPkg; private String[] sortedByClass; private String groupName;
CBClassGroup( final ZipFile zip ) throws IOException { groupName = zip.getName(); Enumeration allEntries ZipEntry zipEntry String name; = zip.entries(); = null;
while( allEntries.hasMoreElements() ) { zipEntry = (ZipEntry)allEntries.nextElement(); name = zipEntry.getName(); // only want full paths, not partials if( name.endsWith( ".java" ) || name.endsWith( ".class" ) ) { // drop the .java or .class ending StringTokenizer stok = new StringTokenizer( name, "." ); String token = stok.nextToken(); entries.add( token ); } } Collections.sort( (ArrayList)entries );
http://www.janeg.ca/projects/cb/CBClassGroup.html (1 of 2) [15/03/2004 8:46:38 AM]
CBClassGroup.java
sortedByPkg = (String[])entries.toArray( new String[0] ); Collections.sort( (ArrayList)entries, CBNameComparator.getInstance() ); sortedByClass = (String[])entries.toArray( new String[0] ); entries = null; }
/** * Gets the class name entries sorted by package. * *@return An array of class names sorted by package. */ String[] getByPackageName() { return sortedByPkg; }
/** * Gets the class name entries sorted by class. * *@return An array of class names sorted by the class simple name. */ String[] getByClassName() { return sortedByClass; }
/** * Gets the name of the group of entries. * *@return The fullpath name of the file containing this group of entries. */ String getGroupName() { return groupName; } }
CBClassInfo.java
package ca.janeg.cb; import import import import import import import java.lang.reflect.Array; java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.util.ArrayList; java.util.Arrays; java.util.Collections;
/** * A CBClassInfo object used to load a class and store pertinent class * information: superclasses, fields, methods, constructor names. * * @author Jane Griscti [email protected] * @created January 8, 2002 */ public class CBClassInfo { private final static String NAME_DELIMITER = "."; private final String fullyQualifiedName; private final ParsedClassName pcn; private private private private private private private Class thisClass; String[] superClasses; FieldGroup flds; MethodGroup methods; ConstructorGroup ctors; Class[] memberClasses; Class[] memberInterfaces; = true;
/** * Constructs a new CBClassInfo object. Checks for a fully qualified class * name; however, this does not guarantee that the class is available to be * loaded. <p> * * A 'fully qualified name' consists of the classes package name and simple * name given in dot-notation format. For example, java.lang.Object<p> * * A class may only be loaded, and its information retreived, if it is * available to the JVM via the bootstrap loader or the system classpath. * * @param name a fully qualified class name * @exception ClassNotFoundException if name is not a fully qualified class * name */ public CBClassInfo( final String name ) throws ClassNotFoundException { if( !isFullyQualifiedName( name ) ) { throw new ClassNotFoundException( " '" + name + "' is not a fully qualified class name." ); }
CBClassInfo.java
private boolean isFullyQualifiedName( final String name ) { return name.indexOf( NAME_DELIMITER ) > 0; }
private void loadSuperClasses() { Class subclass Class superclass ArrayList tmp = thisClass; = subclass.getSuperclass(); = new ArrayList();
while( superclass != null ) { String className = superclass.getName(); tmp.add( className ); subclass = superclass; superclass = subclass.getSuperclass(); } Collections.sort( tmp ); superClasses = (String[])tmp.toArray( new String[0] ); tmp = null; }
private void loadMemberClasses() throws SecurityException { Class[] members = thisClass.getDeclaredClasses(); if( members.length > 0 ) { ArrayList mInter = new ArrayList(); ArrayList mClass = new ArrayList(); for( int i = 0; i < members.length; i++ ) { if( members[i].isInterface() ) { mInter.add( members[i] ); } else { mClass.add( members[i] ); } } if( !mClass.isEmpty() ) { memberClasses = (Class[])mClass.toArray( new Class[0] ); } if( !mInter.isEmpty() ) {
CBClassInfo.java
memberInterfaces = (Class[])mInter.toArray( new Class[0] ); } } } private void loadClassData() throws ClassNotFoundException { thisClass = Class.forName( fullyQualifiedName ); loadSuperClasses(); flds = new FieldGroup( thisClass ); methods = new MethodGroup( thisClass ); ctors = new ConstructorGroup( thisClass ); try { loadMemberClasses(); } catch( SecurityException e ) { memberPermission = false; } }
/** * Returns the simpleName attribute of the CBClassInfo object * *@return The simpleName value */ public String getSimpleName() { return pcn.getSimpleName(); }
/** * Returns the fullyQualifiedName attribute of the CBClassInfo object * *@return The fullyQualifiedName value */ public String getFullyQualifiedName() { return fullyQualifiedName; }
/** * Returns the packageName attribute of the CBClassInfo object * *@return The packageName value */ public String getPackageName() { return pcn.getPackageName(); }
/** * Returns the package names associated with the class represented by
CBClassInfo.java
* this object. * *@return The packages value */ public String[] getPackages() { return pcn.getPackages(); }
/** * Returns all the fields declared in the class represented by this object. * *@return an object array containing Field objects */ public Field[] getAllFields() { return flds.getAllFields(); }
/** * Returns all the public fields declared in the class represented by this * object. * *@return an object array containing Field objects */ public Field[] getPublicFields() { return flds.getPublicFields(); }
/** * Returns all the private fields declared in the class represented by this * object. * *@return an object array containing Field objects */ public Field[] getPrivateFields() { return flds.getPrivateFields(); }
/** * Returns all the package fields declared in the class represented by this * object. * * *@return an object array containing Field objects */ public Field[] getPackageFields() { return flds.getPackageFields(); }
CBClassInfo.java
/** * Returns all the protected fields declared in the class represented by * this object. * *@return an object array containing Field objects */ public Field[] getProtectedFields() { return flds.getProtectedFields(); }
/** * Returns all the super classes the class represented by this object * inherits from. * *@return an object array containing Class objects */ public String[] getSuperClasses() { return superClasses; }
/** * Returns all the methods declared in the class represented by this * object. * *@return an object array containing Method objects */ public Method[] getAllMethods() { return methods.getAllMethods(); }
/** * Returns all the public methods declared in the class represented by this * object. * *@return an object array containing Method objects */ public Method[] getPublicMethods() { return methods.getPublicMethods(); }
/** * Returns all the private methods declared in the class represented by * this object. * *@return an object array containing Method objects */ public Method[] getPrivateMethods() { return methods.getPrivateMethods();
CBClassInfo.java
/** * Returns all the package methods declared in the class represented by * this object. * * *@return an object array containing Method objects */ public Method[] getPackageMethods() { return methods.getPackageMethods(); }
/** * Returns all the protected methods declared in the class represented by * this object. * *@return an object array containing Method objects */ public Method[] getProtectedMethods() { return methods.getProtectedMethods(); }
/** * Returns all the constructors declared in the class represented by this * object. * *@return an object array containing Constructor objects */ public Constructor[] getAllConstructors() { return ctors.getAllConstructors(); }
/** * Returns all the public constructors declared in the class represented by * this object. * *@return an object array containing Constructor objects */ public Constructor[] getPublicConstructors() { return ctors.getPublicConstructors(); }
/** * Returns all the private constructors declared in the class represented * by this object. * *@return an object array containing Constructor objects
CBClassInfo.java
/** * Returns all the package constructors declared in the class represented * by this object. * * *@return an object array containing Constructor objects */ public Constructor[] getPackageConstructors() { return ctors.getPackageConstructors(); }
/** * Returns all the protected constructors declared in the class represented * by this object. * *@return an object array containing Constructor objects */ public Constructor[] getProtectedConstructors() { return ctors.getProtectedConstructors(); }
/** * Returns all the classes declared as members of the class represented by * this object if the package security allows access to the information. * *@return an object array of Class objects *@see isMemberAccessAllowed() */ public Class[] getMemberClasses() { return memberClasses; }
/** * Returns all the interfaces declared as members of the class represented * by this object if the package security allows access to the information. * * @return an object array of Class objects * @see isMemberAccessAllowed() */ public Class[] getMemberInterfaces() { return memberInterfaces; } /**
CBClassInfo.java
* Returns true if the class has declared fields. */ public boolean hasFields(){ return flds.hasFields ? true : false; } /** * Returns true if the class has declared methods. */ public boolean hasMethods() { return methods.hasMethods ? true : false; } /** * Returns true if the class has declared constructors. */ public boolean hasCtors() { return ctors.hasCtors ? true : false; } /** * Returns true if the class has super classes. */ public boolean hasSuperClasses() { return Array.getLength( superClasses ) > 0; } /** * Gets the interface attribute of the CBClassInfo object * *@return The interface value */ public boolean isInterface() { return thisClass.isInterface(); }
/** * Gets the memberAccessAllowed attribute of the CBClassInfo object * *@return The memberAccessAllowed value */ public boolean isMemberAccessAllowed() { return memberPermission; }
/** * Returns a textual description of the object. * *@return the name of the class represented by this object */ public String toString() {
CBClassInfo.java
return "A ClassInfo object for the '" + fullyQualifiedName + "' class."; } }
CBDocument.java
package ca.janeg.cb; import import import import import java.awt.Color; javax.swing.text.BadLocationException; javax.swing.text.DefaultStyledDocument; javax.swing.text.Style; javax.swing.text.StyleConstants;
/** * A customized DefaultStyledDocument used by the CBTextPane * component to display class details as formatted text. * *@author Jane Griscti [email protected] *@created January 5, 2002 */ class CBDocument extends DefaultStyledDocument { private static Style basicStyle; final static String BASIC final static String HEADING final static String BOLD = "Basic"; = "Heading"; = "Bold";
/** Adds three styles to the document: Heading, Basic and Bold */ private void createStyles() { // Create the top-level style, with the required font basicStyle = addStyle( BASIC, null ); StyleConstants.setFontFamily( basicStyle, "Courier New" ); StyleConstants.setFontSize( basicStyle, 14 ); StyleConstants.setForeground( basicStyle, Color.black ); StyleConstants.setFirstLineIndent( basicStyle, 50.0f ); StyleConstants.setSpaceAbove( basicStyle, 6 ); StyleConstants.setSpaceBelow( basicStyle, 0 ); // Heading: centered, bold, larger font Style s = addStyle( HEADING, basicStyle ); StyleConstants.setBold( s, true ); StyleConstants.setFontSize( s, 16 );
http://www.janeg.ca/projects/cb/CBDocument.html (1 of 2) [15/03/2004 8:46:39 AM]
CBDocument.java
StyleConstants.setForeground( s, new Color( 0x006699 ) ); StyleConstants.setAlignment( s, StyleConstants.ALIGN_CENTER ); StyleConstants.setSpaceBelow( s, 12 ); // BoldText s = addStyle( BOLD, basicStyle ); StyleConstants.setBold( s, true ); } }
CBTextPane.java
package ca.janeg.cb; import import import import import import import import import java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.util.StringTokenizer; javax.swing.JOptionPane; javax.swing.JTextPane; javax.swing.text.AttributeSet; javax.swing.text.BadLocationException; javax.swing.text.Style;
/** * A component to display formatted text detailing the superclasses, * interfaces, fields, constructor, and methods of a selected class. * * @author Jane Griscti [email protected] * @created January 5, 2002 */ class CBTextPane extends JTextPane { CBClassInfo currentClass; CBDocument doc;
/** * Formats the class name and assigns it to the first line of the display * document. */ private void showHeading() { String head = null; if( currentClass.isInterface() ) { head = "Details for Interface " + currentClass.getFullyQualifiedName(); } else { head = "Details for Class " + currentClass.getFullyQualifiedName(); } try { AttributeSet s = doc.getStyle( doc.HEADING ); doc.insertString( doc.getLength(), head + "\n", s ); doc.setLogicalStyle( doc.getLength() - 1, (Style)s ); } catch( BadLocationException e ) { JOptionPane.showMessageDialog( this, "Error displaying details. /n" + e, "Display Error", JOptionPane.ERROR_MESSAGE );
http://www.janeg.ca/projects/cb/CBTextPane.html (1 of 5) [15/03/2004 8:46:39 AM]
CBTextPane.java
return; } }
/** * Retreives the class superclasses, formats their names and adds them to * the display document */ private void showSuperClasses() { String[] supers = currentClass.getSuperClasses(); if( supers == null ) { return; } AttributeSet s = doc.getStyle( doc.HEADING ); try { doc.insertString( doc.getLength(), "SuperClasses \n", s ); } catch( BadLocationException e ) { JOptionPane.showMessageDialog( this, "Error displaying details. /n" + e, "Display Error", JOptionPane.ERROR_MESSAGE ); return; } doc.setLogicalStyle( doc.getLength() - 1, (Style)s ); for( int i = 0; i < supers.length; i++ ) { try { doc.insertString( doc.getLength(), supers[i] + "\n", doc.getStyle( doc.BASIC ) ); } catch( BadLocationException e ) { JOptionPane.showMessageDialog( this, "Error displaying details. /n" + e, "Display Error", JOptionPane.ERROR_MESSAGE ); return; } } }
/** * Formats the class details and adds them to the display document. * *@param data An array of Interface, Field, Constructor, or Method objects *@param type Description of Parameter */
http://www.janeg.ca/projects/cb/CBTextPane.html (2 of 5) [15/03/2004 8:46:39 AM]
CBTextPane.java
private void showData( final Object[] data, final String type ) { if( data == null ) { return; } try { if( type != "" ) { AttributeSet s = doc.getStyle( doc.HEADING ); doc.insertString( doc.getLength(), type + "\n", s ); doc.setLogicalStyle( doc.getLength() - 1, (Style)s ); }else{ doc.insertString( doc.getLength(), "\n", doc.getStyle( doc.BASIC ) ); } for( int i = 0; i < data.length; i++ ) { displayLine( data[i].toString() ); doc.insertString( doc.getLength(), "\n", doc.getStyle( doc.BASIC ) ); } } catch( BadLocationException e ) { JOptionPane.showMessageDialog( this, "Error displaying details. /n" + e, "Display Error", JOptionPane.ERROR_MESSAGE ); return; } }
/** * Write a new line in the document * * @param line the text to be displayed */ private void displayLine( final String line ) { String className = currentClass.getSimpleName(); StringTokenizer stok = new StringTokenizer( line, " (", true ); String token = new String( "" ); while( stok.hasMoreTokens() ) { token = stok.nextToken(); try { if( token.indexOf( className ) == -1 ) { if( token.lastIndexOf( '.' ) > 0 && !token.endsWith( ")" ) ) { int pos = token.lastIndexOf( '.' ); token = token.substring( pos + 1 );
http://www.janeg.ca/projects/cb/CBTextPane.html (3 of 5) [15/03/2004 8:46:39 AM]
CBTextPane.java
} doc.insertString( doc.getLength(), token, doc.getStyle( doc.BASIC ) ); } else { // show field, method, ctor name in bold int pos = token.lastIndexOf( '.' ); doc.insertString( doc.getLength(), token.substring( pos + 1 ), doc.getStyle( doc.BOLD ) ); } } catch( BadLocationException e ) { JOptionPane.showMessageDialog( this, "Error displaying details. /n" + e, "Display Error", JOptionPane.ERROR_MESSAGE ); return; } } }
/** * Replaces the current content with the details of the supplied class. All * content is displayed using a StyledDocument. * *@param str the name of the class for which details will be displayed */ void displayClassInfo( final String str ) { try { currentClass = new CBClassInfo( str ); } catch( ClassNotFoundException e ) { JOptionPane.showMessageDialog( this, "Unable to load class " + str + "\nPlease check your classpath.", "Error Loading Class", JOptionPane.ERROR_MESSAGE ); return; } doc = new CBDocument(); setStyledDocument( doc ); showHeading(); if( currentClass.hasSuperClasses() ) { showSuperClasses(); Class[] inter = currentClass.getMemberInterfaces(); showData( inter, "Interfaces" ); }
CBTextPane.java
Class[] members = currentClass.getMemberClasses(); showData( members, "Member Classes"); if( currentClass.hasFields() ) { Field[] flds = currentClass.getPublicFields(); showData( flds, "Fields" ); flds = currentClass.getPackageFields(); showData( flds, "" ); flds = currentClass.getProtectedFields(); showData( flds, "" ); flds = currentClass.getPrivateFields(); showData( flds, "" ); } if( currentClass.hasCtors() ) { Constructor[] ctors = currentClass.getPublicConstructors(); showData( ctors, "Constructors" ); ctors = currentClass.getProtectedConstructors(); showData( ctors, "" ); ctors = currentClass.getPackageConstructors(); showData( ctors, "" ); ctors = currentClass.getPrivateConstructors(); showData( ctors, "" ); } if( currentClass.hasMethods() ) { Method[] methods = currentClass.getPublicMethods(); showData( methods, "Methods" ); methods = currentClass.getProtectedMethods(); showData( methods, "" ); methods = currentClass.getPackageMethods(); showData( methods, "" ); methods = currentClass.getPrivateMethods(); showData( methods, "" ); } setCaretPosition( 0 ); } }
CBTreePanel.java
package ca.janeg.cb; import import import import import import import import import import import import import import import import import java.awt.Dimension; java.util.ArrayList; java.util.Collection; java.util.Collections; java.util.ListIterator; java.util.StringTokenizer; java.util.TreeMap; javax.swing.JPanel; javax.swing.JScrollPane; javax.swing.JTree; javax.swing.event.TreeSelectionEvent; javax.swing.event.TreeSelectionListener; javax.swing.tree.DefaultMutableTreeNode; javax.swing.tree.DefaultTreeModel; javax.swing.tree.TreeNode; javax.swing.tree.TreePath; javax.swing.tree.TreeSelectionModel;
/** * Builds and contains the JTree used to display the class heirarchy. * * @author Jane Griscti [email protected] * @created January 26, 2002 */ class CBTreePanel extends JPanel { private private private private private private ClassBrowser parent; JTree tree = new JTree(); DefaultMutableTreeNode classTree; DefaultMutableTreeNode pkgTree; CBClassGroup classGroup; Collection sortedClasses = new ArrayList();
/** * Constructs a CBTreePanel object. * * @param frame the ClassBrowser object to contain the panel * @param cbcg the CBClassGroup to be displayed */ CBTreePanel( final ClassBrowser frame, final CBClassGroup cbcg ) { super(); parent = frame; classGroup = cbcg; buildPkgTree(); buildClassTree();
CBTreePanel.java
switchToPkgTree(); tree.putClientProperty( "JTree.lineStyle", "Angled" ); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); tree.addTreeSelectionListener( new CBTreeListener() ); JScrollPane jsp = new JScrollPane( tree ); jsp.setPreferredSize( new Dimension( 300, 500 ) ); jsp.setMinimumSize( jsp.getPreferredSize() ); add( jsp ); }
/** Builds a tree model based on the class package names. */ private void buildPkgTree() { DefaultMutableTreeNode top = new DefaultMutableTreeNode( classGroup.getGroupName() ); DefaultMutableTreeNode prevNode; DefaultMutableTreeNode node; String element; String key StringBuffer keyBuf String keyBufStr; TreeMap map prevNode = top; String[] pkgs
// build tree nodes for( int i = 0; i < pkgs.length; i++ ) { element = pkgs[i]; keyBuf = new StringBuffer( element.length() ); keyBufStr = ""; StringTokenizer stok ClassInfo data int tokenCount = new StringTokenizer( element, "/" ); = null; = 0;
while( stok.hasMoreTokens() ) { key = stok.nextToken(); tokenCount++; keyBuf.append( key + '.' ); keyBufStr = keyBuf.toString(); if( map.containsKey( keyBufStr ) ) { prevNode = (DefaultMutableTreeNode)map.get( keyBufStr ); } else {
CBTreePanel.java
data = new ClassInfo( keyBufStr, key ); node = new DefaultMutableTreeNode( data ); // check for top level package names if( tokenCount == 1 ) { top.add( node ); } else { prevNode.add( node ); } prevNode = node; map.put( keyBufStr, node ); sortedClasses.add( data ); } } } pkgTree = top; }
/* * Builds a tree model based on the class names.<p> * * Note: This is not built by using the CBClassGroup sorted classes. It * uses the same ClassInfo objects created for the package tree. */ private void buildClassTree() { Collections.sort( (ArrayList)sortedClasses, CBNameComparator.getInstance() ); ListIterator liter = ( (ArrayList)sortedClasses ).listIterator(); DefaultMutableTreeNode classTop = new DefaultMutableTreeNode( classGroup.getGroupName() ); DefaultMutableTreeNode node; ClassInfo element; while( liter.hasNext() ) { element = (ClassInfo)liter.next(); node = new DefaultMutableTreeNode( element ); classTop.add( node ); } sortedClasses = null; classTree = classTop; } // finished with sorted classes
CBTreePanel.java
/** * Switches the JTree model to the sorted class tree model. * The display is automatically updated. */ void switchToClassTree() { DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); model.setRoot( classTree ); model.reload(); }
/** * Switches the JTree model to the package name tree model. * The display is automatically updated. */ void switchToPkgTree() { DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); model.setRoot( pkgTree ); model.reload(); }
/** * The listener for the JTree contained in CBTreePanel. * * @author Jane Griscti [email protected] * @created January 26, 2002 */ private class CBTreeListener implements TreeSelectionListener { public void valueChanged( TreeSelectionEvent e ) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if( node == null ) { return; } if( node.isLeaf() ) { ClassInfo classInfo = (ClassInfo)node.getUserObject(); parent.displayClassInfo( classInfo.qualifiedName ); } } }
/** * Separates the class name from the package name and stores them * separately. A ClassInfo object acts as a leaf node in the JTree.
CBTreePanel.java
* * @author Jane Griscti [email protected] * @created January 5, 2002 */ class ClassInfo { String qualifiedName; String className;
/** * Constructs a new ClassInfo object * * @param fullpath the fully qualifed class name * @param name the simple class name */ ClassInfo( String fullpath, String name ) { fullpath = fullpath.substring( 0, fullpath.length() - 1 ); qualifiedName = fullpath; className = name; } public String getQualifiedName() { return qualifiedName; }
/** * Overrides Object.toString() to provide each node with a display * name; that of the class it represents. * *@return Description of the Returned Value */ public String toString() { return className; } } }
ConstructorGroup.java
package ca.janeg.cb; import import import import import java.lang.reflect.Array; java.lang.reflect.Constructor; java.util.ArrayList; java.util.Arrays; java.util.Comparator;
/** * A constructor group object contains class constructor information separated * into groups based on their access privileges. Each grouping is sorted on the * constructors simple name. * *@author Jane Griscti [email protected] *@created January 13, 2002 */ class ConstructorGroup { private private private private private private final Class owner; Constructor[] ctors; Constructor[] publicConstructors; Constructor[] protectedConstructors; Constructor[] packageConstructors; Constructor[] privateConstructors;
boolean hasCtors;
/** * Creates a ConstructorGroup object. * *@param owner the class object the methods are derived from */ ConstructorGroup( final Class owner ) { this.owner = owner; ctors = owner.getDeclaredConstructors(); Arrays.sort( ctors, NameComparator.getInstance() ); hasCtors = Array.getLength( ctors ) > 0; if( hasCtors ) separateByAccess(); }
private void separateByAccess() { Object[] obj = AccessSeparator.separate( ctors ); ArrayList al = (ArrayList)obj[0]; publicConstructors = (Constructor[])al.toArray( new Constructor[0] ); al = (ArrayList)obj[1]; protectedConstructors = (Constructor[])al.toArray( new Constructor[0] );
ConstructorGroup.java
al = (ArrayList)obj[2]; privateConstructors = (Constructor[])al.toArray( new Constructor[0] ); al = (ArrayList)obj[3]; packageConstructors = (Constructor[])al.toArray( new Constructor[0] ); }
FieldGroup.java
package ca.janeg.cb; import import import import import java.lang.reflect.Array; java.lang.reflect.Field; java.util.ArrayList; java.util.Arrays; java.util.Comparator;
/** * A field group object contains class field information separated into groups * based on their access privileges. Each grouping is sorted on the fields * simple name. * *@author Jane Griscti [email protected] *@created January 13, 2002 */ class FieldGroup { private private private private private private final Class owner; Field[] flds; Field[] publicFields; Field[] protectedFields; Field[] packageFields; Field[] privateFields;
boolean hasFields;
/** * Creates a new FieldGroup object. * *@param owner the class object the fields are derived from */ FieldGroup( final Class owner ) { this.owner = owner; flds = owner.getDeclaredFields(); Arrays.sort( flds, NameComparator.getInstance() ); hasFields = Array.getLength( flds ) > 0; if( hasFields ) } // separate fields based on their access level private void separateByAccess() { Object[] obj = AccessSeparator.separate( flds ); ArrayList al = (ArrayList)obj[0]; publicFields = (Field[])al.toArray( new Field[0] ); separateByAccess();
FieldGroup.java
al = (ArrayList)obj[1]; protectedFields = (Field[])al.toArray( new Field[0] ); al = (ArrayList)obj[2]; privateFields = (Field[])al.toArray( new Field[0] ); al = (ArrayList)obj[3]; packageFields = (Field[])al.toArray( new Field[0] ); }
MethodGroup.java
package ca.janeg.cb; import import import import import import java.lang.reflect.Array; java.lang.reflect.Method; java.util.ArrayList; java.util.Arrays; java.util.Comparator; java.util.StringTokenizer;
/** * A method group object contains class method information separated into * groups based on their access privileges. Each grouping is sorted on the * methods simple name. * * @author Jane Griscti [email protected] * @created January 13, 2002 */ class MethodGroup { private private private private private private final Class owner; Method[] methods; Method[] publicMethods; Method[] protectedMethods; Method[] packageMethods; Method[] privateMethods;
boolean hasMethods;
/** * Creates a MethodGroup object. * *@param owner the class object the methods are derived from */ MethodGroup( final Class owner ) { this.owner = owner; methods = owner.getDeclaredMethods(); Arrays.sort( methods, NameComparator.getInstance() ); hasMethods = Array.getLength( methods ) > 0; if( hasMethods ) separateByAccess(); }
// separate methods based on their access level private void separateByAccess() { Object[] obj = AccessSeparator.separate( methods );
MethodGroup.java
ArrayList al = (ArrayList)obj[0]; publicMethods = (Method[])al.toArray( new Method[0] ); al = (ArrayList)obj[1]; protectedMethods = (Method[])al.toArray( new Method[0] ); al = (ArrayList)obj[2]; privateMethods = (Method[])al.toArray( new Method[0] ); al = (ArrayList)obj[3]; packageMethods = (Method[])al.toArray( new Method[0] ); }
NameComparator.java
Compares fully qualified class, constructor, field and method names based on their simple name; ignores character case. @author @created Jane Griscti [email protected] January 13, 2002
class NameComparator implements Comparator { private final static NameComparator INSTANCE = new NameComparator();
private String getDelimiter( final String str ) { String delimiter = ""; if( str.indexOf( "/" ) > 0 ) { delimiter = "/"; } else if( str.indexOf( "." ) > 0 ) { delimiter = "."; } return delimiter; }
private String extract( final String str, final String delimiter ) { String result = str; // drop any parameters if it's a method or constructor name if( str.indexOf( "(" ) > 0 ) { result = str.substring( 0, str.indexOf( "(" ) ); } if( delimiter != "" ) { int index = result.lastIndexOf( delimiter ); result = result.substring( index + 1 ); } return result; }
NameComparator.java
/** * Returns a singleton instance of NameComparator * *@return a NameComparator object */ public static NameComparator getInstance() { return INSTANCE; }
/** * Compares two objects * *@param o1 the first object being compared *@param o2 the second object being compared *@return a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. */ public int compare( final Object o1, final Object o2 ) { String s1 = o1.toString(); String s2 = o2.toString(); String s1Delimiter String s2Delimiter = getDelimiter( s1 ); = getDelimiter( s2 );
ParsedClassName.java
package ca.janeg.cb; import java.util.StringTokenizer; /** * A ParsedClassName takes a fully qualified class name and breaks into it's * component parts using the given delimiter. * *@author Jane Grisct [email protected] *@created January 26, 2002 */ class ParsedClassName { private String simple; private String[] pkgs; private String pkgName;
ParsedClassName( final String name, final String delimiter ) { StringTokenizer stok int tokens = new StringTokenizer( name, delimiter ); = stok.countTokens();
if( tokens > 1 ) { StringBuffer buf = new StringBuffer( name.length() ); pkgs = new String[tokens - 1]; String tok = ""; for( int i = 0; i < tokens - 1; i++ ) { tok = stok.nextToken(); pkgs[i] = tok; buf.append( tok + '.' ); } pkgName = buf.substring( 0, buf.length() - 1 ); } simple = stok.nextToken(); }
String getPackageName() {
http://www.janeg.ca/projects/cb/ParsedClassName.html (1 of 2) [15/03/2004 8:46:41 AM]
ParsedClassName.java
return pkgName; }
/** * The main program for the ParsedClassName class; used for testing. * *@param args The command line arguments */ public static void main( String[] args ) { // good example ParsedClassName pcn = new ParsedClassName( "java.awt.text.resources.DateFormatZoneData_en", "." ); System.out.println( pcn.getSimpleName() ); System.out.println( pcn.getPackageName() ); for( int i = 0; i < pcn.pkgs.length; i++ ) { System.out.println( pcn.pkgs[i] ); } System.out.println(); // works ok with empty tokens pcn = new ParsedClassName( "java..awt.Button", "." ); System.out.println( pcn.getSimpleName() ); System.out.println( pcn.getPackageName() ); for( int i = 0; i < pcn.pkgs.length; i++ ) { System.out.println( pcn.pkgs[i] ); } // works ok with ending delimiter System.out.println(); pcn = new ParsedClassName( "java..awt.Frame.", "." ); System.out.println( pcn.getSimpleName() ); System.out.println( pcn.getPackageName() ); for( int i = 0; i < pcn.pkgs.length; i++ ) { System.out.println( pcn.pkgs[i] ); } } }
FieldValidation.java Utils.java Each field is assigned an InputVerifier which checks the contents of a field when it is exited. If the input does not fall within the verifiers parameters, focus is automatically returned to the field. A corresponding message is displayed in the 'status' area. The static method center() from the Utils class is used to center the window on the desktop.
Home | Projects
ca.janeg.project.FieldValidation (Java2HTML)
FieldValidation
1 package ca.janeg.project; 2 3 import java.awt.BorderLayout; 4 import java.awt.Color; 5 import java.awt.Dimension; 6 import java.awt.Font; 7 import java.awt.event.WindowAdapter; 8 import java.awt.event.WindowEvent; 9 import java.text.DateFormat; 10 import java.text.ParseException; 11 import java.text.SimpleDateFormat; 12 13 import javax.swing.BorderFactory; 14 import javax.swing.Box; 15 import javax.swing.BoxLayout; 16 import javax.swing.InputVerifier; 17 import javax.swing.JComponent; 18 import javax.swing.JFrame; 19 import javax.swing.JLabel; 20 import javax.swing.JPanel; 21 import javax.swing.JTextField; 22 import javax.swing.border.Border; 23 import javax.swing.border.TitledBorder; 24 25 import ca.janeg.swing.Utils; 26 27 /** 28 * An example of validating user input fields using 29 * <code>javax.swing.InputVerifier</code>. 30 * 31 * The verifiers are defined as inner classes. 32 * 33 * References: 34 * <ul> 35 * <li><a href="http://www.javaworld.com/javaworld/jw-06-2001/jw-0622-traps.html?"> 36 * JavaWorld article by Michael Daconta</a></li> 37 * <li><a href="http://developer.java.sun.com/developer/JDCTechTips/2001/tt1120.html"> 38 * JDC Tech Tip - VALIDATING NUMERICAL INPUT IN A JTEXTFIELD</a></li> 39 * 40 * </ul> 41 * @author Jane Griscti, [email protected] 42 */ 43 public class FieldValidation { 44 45 private final static DateFormat dateFormat = 46 new SimpleDateFormat( "MM/dd/yyyy" ); 47 private final Font font = new Font( null, 48 Font.BOLD | Font.ITALIC, 49 12 ); 50
ca.janeg.project.FieldValidation (Java2HTML)
JFrame frame JTextField name JTextField age JTextField birthday JTextField status
= = = = =
25 ); 3 ); 10 ); 30 );
public FieldValidation(){ frame.setTitle( "Field Validation Example" ); // assign a verifier to each input field age.setInputVerifier( new AgeVerifier() ); birthday.setInputVerifier( new BirthdayVerifier() ); name.setInputVerifier( new BlankFieldVerifier() ); buildGUI(); } /* * Build the example GUI. */ private void buildGUI(){ JPanel mainPanel = new JPanel(); mainPanel.setLayout( new BoxLayout( mainPanel, BoxLayout.Y_AXIS ) ); mainPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 5,5,5,5 ), mainPanel.getBorder() ) ); mainPanel.add( buildInputPanel() ); mainPanel.add( buildStatusPanel() ); frame.getContentPane().add( mainPanel, BorderLayout.CENTER ); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent wevt) { System.exit(0); } }); frame.setResizable( false ); frame.pack(); Utils.center( frame ); frame.setVisible( true ); } /* * Build the GUI input panel. */ private JPanel buildInputPanel(){ JPanel panel = new JPanel(); Border border = BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "Input", TitledBorder.LEADING,
ca.janeg.project.FieldValidation (Java2HTML)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
TitledBorder.TOP, font, Color.GRAY ); panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); panel.setBorder( border ); panel.add( buildField( name, "Name:" ) ); panel.add( buildField( age, "Age:" ) ); panel.add( buildField( birthday, "Birthday:" ) ); return panel; } /* * Build an input field to be displayed in the input panel. */ private JPanel buildField( JComponent comp, String label ){ comp.setMinimumSize( comp.getPreferredSize() ); comp.setMaximumSize( comp.getPreferredSize() ); JPanel panel = new JPanel(); panel.setBorder( BorderFactory.createEmptyBorder( 2,2,2,2 ) ); panel.setLayout( new BoxLayout( panel, BoxLayout.X_AXIS ) ); Box leftBox = new Box( BoxLayout.X_AXIS ); leftBox.setPreferredSize( new Dimension( 60, 20 ) ); leftBox.add( new JLabel( label ) ); Box rightBox = new Box( BoxLayout.X_AXIS ); rightBox.add( comp ); panel.add( leftBox ); panel.add( rightBox ); panel.add( Box.createHorizontalGlue() ); return panel; } /* * Build the GUI status panel. */ private JPanel buildStatusPanel(){ JPanel panel = new JPanel(); Border border = BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "Status", TitledBorder.LEADING, TitledBorder.TOP, font,
ca.janeg.project.FieldValidation (Java2HTML)
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
Color.GRAY ); panel.setBorder( border ); status.setEditable( false ); status.setForeground( Color.BLUE ); status.setText( "Ready" ); panel.add( status ); return panel; } /* * Checks to ensure a field is not blank. * * The 'shouldYieldFocus()' method produces * a 'beep' if the validation fails. It is inherited * by the other field verifiers. */ private class BlankFieldVerifier extends InputVerifier { public boolean verify(JComponent comp) { JTextField fld = (JTextField) comp; String content = fld.getText(); boolean isValid = true; if (content.length() == 0) { status.setText("Field cannot be blank."); isValid = false; } return isValid; } public boolean shouldYieldFocus(JComponent input) { boolean valid = super.shouldYieldFocus(input); if (!valid) { frame.getToolkit().beep(); } return valid; } } /* * Checks the age field to ensure it is not * empty and that it contains an integer value. */ private class AgeVerifier extends BlankFieldVerifier { public boolean verify(JComponent comp) { JTextField fld = (JTextField) comp; String content = fld.getText(); boolean isValid = true;
ca.janeg.project.FieldValidation (Java2HTML)
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
try { Integer.parseInt(content); } catch (NumberFormatException nfe) { fld.setText(""); status.setText("Age must be a number."); isValid = false; } if (isValid) { status.setText("Age is valid."); } return isValid; } } /* * Checks the birthday field to ensure it is not blank * and it contains a valid date string. There is no * range checking on the date. */ private class BirthdayVerifier extends BlankFieldVerifier { public boolean verify(JComponent comp) { JTextField fld = (JTextField) comp; String content = fld.getText(); boolean isValid = true; try { dateFormat.parse(content); } catch (ParseException e) { fld.setText(""); status.setText("Birthday must be mm/dd/yyyy."); isValid = false; } if (isValid) { status.setText("Birthday is valid."); } return isValid; } } /** * Main entry point for the class. */ public static void main(String[] args){ new FieldValidation(); } }
ca.janeg.project.FieldValidation (Java2HTML)
FieldValidation
ca.janeg.swing.Utils (Java2HTML)
Utils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package ca.janeg.swing; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.Window; /** * Utility methods for Swing components. * * * @author Jane Griscti, [email protected] */ public class Utils { /** * Center a component on the screen. * * Source: * <a href="http://javaalmanac.com/egs/java.awt/screen_CenterScreen.html"> * The Java Almanac</a> * @param window the component to be centered. */ public static void center( Window window ) { // Get the size of the screen Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // Determine the new location of the window int w = window.getSize().width; int h = window.getSize().height; int x = (dim.width - w) / 2; int y = (dim.height - h) / 2; // Move the window window.setLocation(x, y); } }
Utils
Calculator.java CalculatorEngine.java This is a simple implementation of a Calculator. I started with some code I found in Object-Oriented Programming and Java by Danny C.C. Poo and Derek B.K. Kiong which implemented the four binary operations: + - / * and = in the class CalculatorEngine. I added the unary functions and built a Swing GUI.
Design Decisions
q
CalculatorEngine The original code returned Double.toString( value ). This worked fine from the command line but gave me problems when I was designing the GUI; exponential numbers were being returned. I then tried using a JFormattedTextField in the GUI with a DecimalFormat. This also presented difficulties. The default pattern for DecimalFormat is "#,##0.0#". The display always showed 0.0. I only wanted to show decimal digits if the user had selected the decimal key. I changed the pattern to #,###.#" and invoked setDecimalSeperatorAlwaysShown( false ) but then the decimal did not show up until the user selected another digit key and if that happened to be a zero, in any decimal position, it was not shown until a number between 1 and 9 was selected. In the end I gave up and decided to modify CalculatorEngine, adding the display field, a NumberFormatter and modifying the code to keep the value and display attributes in sync.
Calculator The key to the GUI is displaying the various buttons in a pleasing manner and finding an easy way to invoke their actions. By default, each JButton's action command is set to the value of the button label. This got me thinking about how nice it would be if, when a user selected the cos button, the button action listener could invoke engine.cos(). The reflection mechanism in Java allows for just such a scenario. I also wanted the buttons appearance to vary according to their functions: digit, unary, binary, control. To accomplish this I created an inner class CalcButton which implements ActionListener and then created a number of subclasses to handle the different colour settings for each function.
All in all the whole thing came out fairly clean<g>. There is one small flaw that I'm aware of, if the result of a unary operation such as mod is zero, the display shows nothing when really it should show a '0'. Haven't figured out how to get
http://www.janeg.ca/projects/calc/calc.html (1 of 2) [15/03/2004 8:46:45 AM]
around this yet. If you have a solution, please let me know <g>
Home | Projects
ca.janeg.calc.Calculator (Java2HTML)
Calculator
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *************************************************************************** File: Package: Contains: Calculator.java ca.janeg.calc Inner classes CalcButton DigitButton FunctionButton UnaryButton ControlButton Visual Components: Sum It Up with JCalculator by Claude Duguay, Article at http://archive.devx.com (Layout) The Java Programming Language: 2nd Edition by Ken Arnold and James Gosling Addison-Wesley, 1998, 7th Printing 2000 (p311) The Java Developers Almanac 1.4 (online) http://javaalmanac.com/egs/java.awt/screen_CenterScreen.html http://www.javaalmanac.com/egs/javax.swing/LookFeelNative.html Date -----------Oct 17, 2002 Oct 22, 2002 Oct 23, 2002 Changes ---------------------------------------------Created Cleaned up comments, layouts and action listener changed CalcButton to use a white foreground as the default button color and removed redundant calls from the subclasses re-arranged the code in the class body to place inner classes after all methods except main() *************************************************************************** */ Author ------------Jane Griscti Jane Griscti Jane Griscti
References:
package ca.janeg.calc; import import import import import import import import import import import import import java.awt.Color; java.awt.Component; java.awt.Container; java.awt.Dimension; java.awt.Font; java.awt.GridLayout; java.awt.Insets; java.awt.Toolkit; java.awt.Window; java.awt.event.ActionEvent; java.awt.event.ActionListener; java.lang.reflect.InvocationTargetException; java.lang.reflect.Method;
ca.janeg.calc.Calculator (Java2HTML)
/** * A GUI interface for <code>CalculatorEngine</code>. * * @author Jane Griscti [email protected] * @version 1.0 Oct 17, 2002 */ public class Calculator extends JFrame { private final Class ENGINE; private final CalculatorEngine engine = new CalculatorEngine(); private final JTextField display = new JTextField(); /** * Create a new calculator instance. */ public Calculator(){ setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); setTitle( "Calculator" ); display.setEditable( false ); display.setBackground( Color.WHITE ); // set up a Class object used in actionPerformed() // to invoke methods on the CalculatorEngine ENGINE = engine.getClass(); buildGUI(); pack(); setResizable( false ); setLAF(); center( this ); setVisible( true ); } private void buildGUI(){ Container cp = getContentPane(); cp.setLayout( new BoxLayout( cp, BoxLayout.Y_AXIS ) ); cp.add( display ); cp.add( buildControlPanel() ); cp.add( buildButtonPanels() ); } private JPanel buildControlPanel(){ JPanel panel = new JPanel();
http://www.janeg.ca/projects/calc/Calculator.java.html (2 of 7) [15/03/2004 8:46:45 AM]
ca.janeg.calc.Calculator (Java2HTML)
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.add( Box.createHorizontalGlue() ); panel.add( new ControlButton( "Backspace", "backspace" ) ); panel.add( Box.createRigidArea( new Dimension( 2, 0 ) ) ); JPanel panel2 = new JPanel( new GridLayout( 1, 1, 2, 2 ) ); panel2.add( new ControlButton( "CE", "clearEntry" ) ); panel2.add( new ControlButton( "C", "clear" ) ); panel.add( panel2 ); return panel; } private JPanel buildButtonPanels() { JPanel buttons = new JPanel(); buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS)); buttons.setFont(new Font("Courier", 10, Font.BOLD)); buttons.add( buildUnaryPanel() ); buttons.add( buildDigitPanel() ); buttons.add( buildFunctionPanel() ); return buttons; } private JPanel buildDigitPanel(){ JPanel panel = new JPanel(); panel.setLayout( new GridLayout( 4, 3, 2, 2 ) ); panel.add( new DigitButton( "7" ) ); panel.add( new DigitButton( "8" ) ); panel.add( new DigitButton( "9" ) ); panel.add( new DigitButton( "4" ) ); panel.add( new DigitButton( "5" ) ); panel.add( new DigitButton( "6" ) ); panel.add( new DigitButton( "1" ) ); panel.add( new DigitButton( "2" ) ); panel.add( new DigitButton( "3" ) ); panel.add( new DigitButton( "0" ) ); panel.add( new DigitButton( "." ) ); // not a digit but added here to balance out the panel panel.add( new UnaryButton( " +/- ", "sign" ) ); return panel; }
ca.janeg.calc.Calculator (Java2HTML)
buttons.add( new FunctionButton( "/", "divide" ) ); buttons.add( new FunctionButton( "&", "and" ) ); buttons.add( new FunctionButton( "<<", "leftShift" ) ); buttons.add( new FunctionButton( "*", "multiply" ) ); buttons.add( new FunctionButton( "|", "divide" ) ); buttons.add( new FunctionButton( ">>", "rightShift" ) ); buttons.add( new FunctionButton( "-", "subtract" ) ); buttons.add( new FunctionButton( "^" , "xor" ) ); buttons.add( new FunctionButton( "pow" ) ); buttons.add( new FunctionButton( "+", "add" ) ); buttons.add( new FunctionButton( "=", "equals" ) ); buttons.add( new FunctionButton( "mod" ) ); return buttons; } private JPanel buildUnaryPanel(){ JPanel buttons = new JPanel( new GridLayout( 4, 3, 2, 2 ) ); buttons.add( buttons.add( buttons.add( buttons.add( buttons.add( buttons.add( buttons.add( buttons.add( new new new new new new new new UnaryButton( UnaryButton( UnaryButton( UnaryButton( UnaryButton( UnaryButton( UnaryButton( UnaryButton( "sin" ) ); "cos" ) ); "tan" ) ); "asin" ) ); "acos" ) ); "atan" ) ); "log" ) ); "deg", "degrees" ) );
buttons.add( new UnaryButton( "rad", "radians" ) ); buttons.add( new UnaryButton( "sqrt" ) ); buttons.add( new UnaryButton( "%", "percent" ) ); buttons.add( new UnaryButton( "1/x", "reciprocal" ) ); return buttons; } /* * Center a component on the screen. * * @param window the component to be centered. */ private void center( Window window ) { // Get the size of the screen Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // Determine the new location of the window int w = window.getSize().width;
http://www.janeg.ca/projects/calc/Calculator.java.html (4 of 7) [15/03/2004 8:46:45 AM]
ca.janeg.calc.Calculator (Java2HTML)
int h = window.getSize().height; int x = (dim.width - w) / 2; int y = (dim.height - h) / 2; // Move the window window.setLocation(x, y); } /* * Set the Look and Feel to the system look and feel. */ private void setLAF() { // Get the native look and feel class name String nativeLF = UIManager.getSystemLookAndFeelClassName(); // Install the look and feel try { UIManager.setLookAndFeel(nativeLF); } catch (InstantiationException e) { System.out.println( e.getMessage() ); } catch (ClassNotFoundException e) { System.out.println( e.getMessage() ); } catch (UnsupportedLookAndFeelException e) { System.out.println( e.getMessage() ); } catch (IllegalAccessException e) { System.out.println( e.getMessage() ); } }
/* * Helper class to handle button formatting. * Each button acts as its own listener. */ private class CalcButton extends JButton implements ActionListener{ CalcButton( String s, String action ){ super( s ); setActionCommand( action ); setMargin( new Insets( 2, 2, 2, 2 ) ); setForeground( Color.WHITE ); addActionListener( this ); } /* * * * * * * * * * *
Captures the button events and then uses 'reflection' to invoke the right method in the calculator engine Digit buttons are handled slightly different as they all use the digit( int ) method and their values must be passed as arguments. The digit button for the decimal has special handling; new Integer( "." ) throws a NumberFormatException, have to use new Integer( '.' ) which converts the ASCII
ca.janeg.calc.Calculator (Java2HTML)
* value of '.' to an integer. * */ public void actionPerformed(ActionEvent e) { String methodName = e.getActionCommand(); Method method = null; try { if ( e.getSource() instanceof DigitButton ) { method = ENGINE.getMethod("digit", new Class[] { int.class }); if (methodName.equals(".")) { method.invoke(engine, new Object[] { new Integer( '.' )}); } else { method.invoke(engine, new Object[] { new Integer( methodName )}); } } else { method = ENGINE.getMethod(methodName, null); method.invoke(engine, null); } } catch (NoSuchMethodException ex) { System.out.println("No such method: " + methodName); } catch (IllegalAccessException ea) { System.out.println("Illegal access" + methodName); } catch (InvocationTargetException et) { System.out.println("Target exception: " + methodName); } display.setText(engine.display()); } } private class DigitButton extends CalcButton { DigitButton( String s ){ super( s, s ); setForeground( Color.BLUE ); } } private class FunctionButton extends CalcButton { FunctionButton( String s ){ this( s, s ); } FunctionButton( String s, String action ){ super( s, action ); setBackground( Color.GRAY ); } }
ca.janeg.calc.Calculator (Java2HTML)
private class ControlButton extends CalcButton{ ControlButton( String s ){ this( s, s ); } ControlButton( String s, String action ){ super( s, action ); setBackground( Color.RED ); } } private class UnaryButton extends CalcButton { UnaryButton( String s ){ this( s, s ); } UnaryButton( String s, String action ){ super( s, action ); setBackground( Color.BLUE ); } } /** * Main entry point for the program */ public static void main(String[] args) { new Calculator(); } }
Calculator
ca.janeg.calc.CalculatorEngine (Java2HTML)
CalculatorEngine
/* * * * * * * * * * * * * * * * * * * * *************************************************************************** File: Package: References: CalculatorEngine.java ca.janeg.calc Object Oriented Programming and Java, by Danny C.C. Poo and Derek B.K. Kiong, Springer, 1999 (p48-49)
Date -----------Oct 17, 2002 Oct 18, 2002 Oct 20, 2002
Changes ---------------------------------------------Created Added unary functions %, sqrt, reciprocal, etc Added var display, number formatter and related methods Added integer binary operations: xor, or, and leftShift, rightShift Oct 21, 2002 Jane Griscti Cleaned up comments Oct 22, 2002 Jane Griscti Added trig and log unary functions *************************************************************************** */
package ca.janeg.calc; import java.text.DecimalFormat; import java.text.NumberFormat; /** * A class to perform standard calculator operations. * For example, * * <pre> * CalculatorEngine c = new CalculatorEngine(); * c.digit( 1 ); * c.digit( 2 ); * c.add(); * c.digit( 1 ); * c.digit( 3 ); * c.equals(); * System.out.println( c.display() ); * </pre> * * Accuracy is limited to fifteen decimal places. * * @author Jane Griscti [email protected] * @version 1.2 Oct 20, 2002 */ public class CalculatorEngine { private private private private StringBuffer display DecimalFormat df boolean newOp boolean inDecimals = = = = new StringBuffer( 64 ); (DecimalFormat)NumberFormat.getInstance(); false; false;
ca.janeg.calc.CalculatorEngine (Java2HTML)
// // // // //
current digits previous value or operation result binary operation waiting for 2nd value number of decimal positions in current value
/** * Creates a new <code>CalculatorEngine</code> object. */ public CalculatorEngine(){ super(); df.setMaximumFractionDigits( 15 ); } /* -- Digits and the decimal point handler -- */ /** * Accept a digit or decimal as input. */ public void digit(final int n ){ /* * Strategy: * 1. Start a new value if at the beginning of a new operation. * * 2. Append the input character, setting the decimal flag if it's * a decimal point or increasing the decimal count if we're * already into decimals. * * 3. Convert the revised input string to a double for use in * calculations; forcing input errors to return a 0.0 value. */ if( newOp ){ display.delete( 0, display.length() ); newOp = false; } char c = (char)n; if( c == '.' ){ display.append( '.' ); inDecimals = true; }else if( !inDecimals ){ display.append( n ); }else{ if( decimalCount < 16 ){ display.append( n ); decimalCount++; } } try{ value = Double.parseDouble( display.toString() );
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (2 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
}catch( NumberFormatException e ){ value = Double.parseDouble( "0.0" ); } } /* -- Binary operations -* * A binary operation signals the engine to: * 1. store the current value * 2. set the 'toDo' flag with the requested operation * 3. accept input for a second value * 4. perform the 'toDo' op when '=' or another binary operation * is requested */ /** * Add the next input value to the previous value */ public void add(){ binaryOperation( "+" ); } /** * Subtract the next input value from the previous value */ public void subtract(){ binaryOperation( "-" ); } /** * Multiply the next input value by the previous value */ public void multiply(){ binaryOperation( "*" ); } /** * Divide the previous value by the next input value */ public void divide(){ binaryOperation( "/" ); } /** * Bitwise And ( & ) */ public void and(){ binaryOperation( "&" ); } /** * Bitwise Or ( | ) */ public void or(){ binaryOperation( "|" );
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (3 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
} /** * Bitwise ( ^ ) */ public void xor(){ binaryOperation( "^" ); } /** * Bitwise left shift ( < ) */ public void leftShift(){ binaryOperation( "<" ); } /** * Bitwise right shift ( > ) */ public void rightShift(){ binaryOperation( ">" ); } /** * Modulous ( % ) */ public void mod(){ binaryOperation( "m" ); } /** * Raise the previous value to the 'power; of the next input value */ public void pow(){ binaryOperation( "p" ); } /** * Perform any waiting binary operation and clear previous value */ public void equals(){ compute(); toDo = 0; newOp = true; } /* * Setup registers for next input value */ private void binaryOperation( final String op ){ if( toDo == 0 ){ keep = value; }else{ compute();
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (4 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
} value = 0; toDo = op.hashCode(); resetDecimals(); setDisplay(); } /* * Perform a binary operation */ private void compute(){ switch( toDo ){ case '+': value = keep + value; break; case '-': value = keep - value; break; case '*': value = keep * value; break; case '/': if( value != 0 ){ // ignore divide by zero value = keep / value; } case '&': value = (int)keep & (int)value; break; case '|': value = (int)keep | (int)value; break; case '^': value = (int)keep ^ (int)value; break; case '<': value = (int)keep << (int)value; break; case '>': value = (int)keep >> (int)value; break; case 'm': value = keep % value; break; case 'p': value = Math.pow( keep, value ); break; } keep = value; setDisplay(); } /* -- Unary Operations -- */ /** * Compute the square of the current value */ public void sqrt(){ value = Math.sqrt( value ); unaryOperation(); } /** * Reverse the sign on the current value */ public void sign(){ value = value * -1; unaryOperation(); } /** * Convert the current value to a percent */
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (5 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
public void percent(){ value = value / 100; unaryOperation(); } /** * Convert the current value to it's reciprocal value */ public void reciprocal(){ if( value > 0 ){ value = 1 / value; }else{ value = 0; } unaryOperation(); } /** * Compute the sine of the current value. */ public void sin(){ value = Math.sin( value ); unaryOperation(); } /** * Compute the cosine of the current value */ public void cos(){ value = Math.cos( value ); unaryOperation(); } /** * Compute the tan of the current value */ public void tan(){ value = Math.tan( value ); unaryOperation(); } /** * Compute the asine of the current value */ public void asin(){ value = Math.asin( value ); unaryOperation(); } /** * Compute the acosine of the current value */ public void acos(){ value = Math.acos( value ); unaryOperation();
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (6 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
} /** * Compute the atan of the current value */ public void atan(){ value = Math.atan( value ); unaryOperation(); } /** * Compute the log of the current value */ public void log(){ value = Math.log( value ); unaryOperation(); } /** * Convert the current value to degrees */ public void degrees(){ value = Math.toDegrees( value ); unaryOperation(); } /** * Convert the current value to radians */ public void radians(){ value = Math.toRadians( value ); unaryOperation(); }
/* * Setup flag to signal start of a new operation and * set the display to match the value generated by a * unary operation */ private void unaryOperation(){ newOp = true; setDisplay(); } /* -- Control operations -- */ /** * Delete the last entered digit */ public void backspace(){ display.deleteCharAt( display.length() - 1 ); value = Double.parseDouble( display.toString() ); setDisplay(); }
http://www.janeg.ca/projects/calc/CalculatorEngine.java.html (7 of 8) [15/03/2004 8:46:47 AM]
ca.janeg.calc.CalculatorEngine (Java2HTML)
/** * Clear all values */ public void clear(){ display.delete( 0, display.length() ); value = 0; keep = 0; toDo = 0; resetDecimals(); } /** * Clear the current value */ public void clearEntry(){ display.delete( 0, display.length() ); value = 0; resetDecimals(); } /* * Reset the decimal flag and counter */ private void resetDecimals(){ inDecimals = false; decimalCount = 0; } /** * Convert the current value to a formatted string for * display */ private void setDisplay(){ if( value == 0 ){ display.delete( 0, display.length() ); }else{ display.replace( 0, display.length(), df.format( value ) ); } } /** * Returns the current value as a decimal formatted string */ public String display(){ return display.toString(); } }
CalculatorEngine
CalendarComboBox.java
As a Notes developer, I've gotten used to having a date input box with a perpetual calendar. I thought it would be nice to have one for my Java projects. It turned out to be less difficult to create than I'd originally imagined. The one truly nice thing about Java is the richness of it's API. I was able to create the CalendarComboBox by simply arranging a number of existing components: JFormattedTextField, BasicArrowButton, JTable, and Popup. Of course, code always looks simple once it's finished. Originally I didn't know the BasicArrowButton and Popup classes even existed. It took some poking around in the API and Java source code related to JComboBox before I tracked them down. I also needed to figure out how to build an array to hold the days in a month and leverage the various date related classes: Calendar, GregorianCalendar, DateFormat, and DateFormatSymbols. Mr. Dunn's book, Java Rules was particularly useful in helping me understand how these classes worked. And last, but not least, were the layout experiments. I got stuck for a few hours on the calendar display; the buttons in the navigation panel kept changing size, it was very distracting. Finally realized that part of the problem was the JLabel component I was using to display the month and year name and the fact that I was using a BoxLayout. Once I changed the label to a JTextField and the calendar panel layout to BorderLayout, with the navigation portion placed in BorderLayout.NORTH and the table in BorderLayout.CENTER the display started to behave itself. I ran across a few other snags, they are hightlighted in the code comments. Below are my reasons for designing the class as I did.
Design Decisions
q
Class fields The values represented by these fields are common to the system the class is running on. The data is based on the system Locale which is not likely to change; at least, not during the active life of a running application. Field access modifiers All fields (except popup ) are declared private and final. This is good coding practice. The private keyword helps to enforce encapsulation and forces you to think about your classes public interface. In this case, only one field, current needed to be publicly exposed; a gettor method, public Calendar getDate() was provided to return current as it's reasonable to assume an external class would need access to the currently selected date.
The keyword final emphasizes that the fields are required and that references cannot be accidently modifed during the life of an object. It also notifies the compiler that the code relating to these values can be safely optimized. Another advantage is that it helps ensure that everything the object requires to work correctly will be available once it is created; if you fail to initialize a final variable during object creation the compiler complains. Why popup isn't final The API recommends using PopupFactory to create Popup objects. PopupFactory caches popup objects, managing their reuse and disposal. As the programmer's at Sun have been kind enough to supply me with a class that can manage popup's it seemed sensible to use it rather than create a final popup reference and attempt to manage it myself. Listeners as inner classes There are three basic ways to implement listeners: as external classes, as inner classes or as anonymous classes. The only reason to implement one as an external class is if it could possibly be used by another class; yet listeners are generally very specific in nature and certainly are specific in this case so there was nothing to be gained by implementing them as external classes. Anonymous listener classes are generally used if they are required by only one element in the class and if they can be written in nine or ten lines of code. When I started writing the class I had no idea how long a particular listeners code would be and I did know that one listener, ButtonListener, would be required by three elements, not one. So again, there was little to be gained by implementing the listeners as anonymous classes. Add to that the difficulty of maintaining code that is peppered with anonymous classes and the choice of using inner classes became even more attractive. The registerListeners() method For the most part, this is simply a personal preference. I find it easier to keep track of listeners when they are all located in one spot. Having a separate method to handle them just makes life easier for me.
Summary
If you've avoided creating custom components, thinking they're to much trouble or that you need to be an expert programmer to create them, here's the proof that it just ain't so! They can be alot easier to create than you realize. If you end up using the class in one of your applications please let me know how it fares<g> Home | Projects
ca.janeg.calendar.CalendarComboBox (Java2HTML)
CalendarComboBox
/* *************************************************************************** * * File: CalendarWidget.java * Package: ca.janeg.calendar * * Contains: ButtonActionListener * CalendarModel * CalendarSelectionListener * InputListener * * References: 'Java Rules' by Douglas Dunn * Addison-Wesley, 2002 (Chapter 5, section 13 - 19) * * 'Professional Java Custom UI Components' * by Kenneth F. Krutsch, David S. Cargo, Virginia Howlett * WROX Press, 2001 (Chapter 1-3) * * Date Author Changes * ------------ ---------------------------------------------------------* Oct 24, 2002 Jane Griscti Created * Oct 27, 2002 jg Cleaned up calendar display * Oct 30, 2002 jg added ctor CalendarComboBox( Calendar ) * Oct 31, 2002 jg Added listeners and Popup * Nov 1, 2002 jg Cleaned up InputListener code to only accept * valid dates * Nov 2, 2002 jg modified getPopup() to handle display when * component is positioned at the bottom of the screen * Nov 3, 2002 jg changed some instance variables to class variables * Mar 29, 2003 jg added setDate() contributed by James Waldrop * *************************************************************************** */ package ca.janeg.calendar; import import import import import import import import import import import import import import import import java.awt.BorderLayout; java.awt.Color; java.awt.Dimension; java.awt.Font; java.awt.Point; java.awt.Toolkit; java.awt.event.ActionEvent; java.awt.event.ActionListener; java.awt.event.KeyAdapter; java.awt.event.KeyEvent; java.text.DateFormat; java.text.DateFormatSymbols; java.text.ParseException; java.util.Calendar; java.util.Date; java.util.GregorianCalendar;
ca.janeg.calendar.CalendarComboBox (Java2HTML)
import import import import import import import import import import import import import import
javax.swing.JPanel; javax.swing.JTable; javax.swing.JTextField; javax.swing.ListSelectionModel; javax.swing.Popup; javax.swing.PopupFactory; javax.swing.SwingConstants; javax.swing.border.LineBorder; javax.swing.event.ListSelectionEvent; javax.swing.event.ListSelectionListener; javax.swing.plaf.basic.BasicArrowButton; javax.swing.table.DefaultTableModel; javax.swing.table.JTableHeader; javax.swing.table.TableColumn;
/** * A custom component that mimics a combo box, displaying * a perpetual calendar rather than a 'list'. * * @author Jane Griscti [email protected] * @version 1.0 Oct 24, 2002 */ public class CalendarComboBox extends JPanel { // -- class fields private static final DateFormatSymbols private static final String[] private static final String[] private static final Toolkit Toolkit.getDefaultToolkit(); private static final Dimension private static final PopupFactory
// -- instance fields used with 'combo-box' panel private final JPanel inputPanel = new JPanel(); private final JFormattedTextField input = new JFormattedTextField( new Date() ); private final BasicArrowButton comboBtn = new BasicArrowButton( SwingConstants.SOUTH ); // -- instance fields used with calendar panel private final JPanel calPanel private final JTextField calLabel private final Calendar current private final CalendarModel display private final JTable table
= = = = =
private final BasicArrowButton nextBtn = new BasicArrowButton( SwingConstants.EAST ); private final BasicArrowButton prevBtn = new BasicArrowButton( SwingConstants.WEST ); private final BasicArrowButton closeCalendarBtn = new BasicArrowButton( SwingConstants.NORTH );
http://www.janeg.ca/projects/calendar/CalendarComboBox.java.html (2 of 9) [15/03/2004 8:46:49 AM]
ca.janeg.calendar.CalendarComboBox (Java2HTML)
private Popup popup; /** * Create a new calendar combo-box object set with today's date. */ public CalendarComboBox(){ this( new GregorianCalendar() ); } /** * Create a new calendar combo-box object set with the given date. * * @param cal a calendar object * @see java.util.GregorianCalendar */ public CalendarComboBox( final Calendar cal ){ super(); // set the calendar and input box date Date date = cal.getTime(); current.setTime( date ); input.setValue( date ); // create the GUI elements and assign listeners buildInputPanel(); buildCalendarDisplay(); registerListeners(); // intially, only display the input panel add( inputPanel ); } /* * Creates a field and 'combo box' button above the calendar * to allow user input. */ private void buildInputPanel(){ inputPanel.setLayout( new BoxLayout( inputPanel, BoxLayout.X_AXIS ) ); input.setColumns( 12 ); inputPanel.add( input ); comboBtn.setActionCommand( "combo" ); inputPanel.add( comboBtn ); } /* * Builds the calendar panel to be displayed in the popup */ private void buildCalendarDisplay(){ // Allow for individual cell selection and turn off // grid lines. table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
http://www.janeg.ca/projects/calendar/CalendarComboBox.java.html (3 of 9) [15/03/2004 8:46:49 AM]
ca.janeg.calendar.CalendarComboBox (Java2HTML)
table.setShowGrid( false ); // Calendar (table) column headers // Set column headers to weekday names as given by // the default Locale. // // Need to re-map the retreived names. If used as is, // the table model ends up with an extra empty column as // the returned names begin at index 1, not zero. String[] names = dfs.getShortWeekdays(); for( int i=1; i<names.length; i++ ){ dayNames[ i - 1 ] = "" + names[ i ].charAt( 0 ); } display.setColumnIdentifiers( dayNames ); table.setModel( display ); // Set the column widths. Need to turn // auto resizing off to make this work. table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); int count = table.getColumnCount(); for( int i = 0; i < count; i ++ ){ TableColumn col = table.getColumnModel().getColumn( i ); col.setPreferredWidth( 20 ); } // Column headers are only displayed automatically // if the table is put in a JScrollPane. Don't want // to use one here, so need to add the headers // manually. JTableHeader header = table.getTableHeader(); header.setFont( header.getFont().deriveFont( Font.BOLD ) ); JPanel panel = new JPanel(); panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); panel.add( header ); panel.add( table ); calPanel.setBorder( new LineBorder( Color.BLACK ) ); calPanel.setLayout( new BorderLayout() ); calPanel.add( buildCalendarNavigationPanel(), BorderLayout.NORTH ); calPanel.add( panel ); } /* * Creates a small panel above the month table to display the month and * year along with the 'prevBtn', 'nextBtn' month selection buttons * and a 'closeCalendarBtn'. */ private JPanel buildCalendarNavigationPanel(){ JPanel panel = new JPanel(); panel.setLayout( new BoxLayout( panel, BoxLayout.X_AXIS ) );
ca.janeg.calendar.CalendarComboBox (Java2HTML)
// Add a text display of the selected month and year. // A JTextField is used for the label instead of a JLabel // as it is easier to ensure a consistent size; JLabel // expands and contracts with the text size calLabel.setEditable( false ); int fontSize = calLabel.getFont().getSize(); calLabel.setFont( calLabel.getFont().deriveFont( Font.PLAIN, fontSize - 2 ) ); panel.add( calLabel ); // set button commands and add to panel prevBtn.setActionCommand( "prevBtn" ); nextBtn.setActionCommand( "nextBtn" ); closeCalendarBtn.setActionCommand( "close" ); panel.add( prevBtn ); panel.add( nextBtn ); panel.add( closeCalendarBtn ); return panel; } /* * Register all required listeners with appropriate * components */ private void registerListeners(){ ButtonActionListener btnListener = new ButtonActionListener(); // 'Combo-box' listeners input.addKeyListener( new InputListener() ); comboBtn.addActionListener( btnListener ); // Calendar (table) selection listener // Must be added to both the table selection model // and the column selection model; otherwise, new // column selections on the same row are not recognized CalendarSelectionListener listener = new CalendarSelectionListener(); table.getSelectionModel().addListSelectionListener( listener ); table.getColumnModel().getSelectionModel() .addListSelectionListener( listener ); // Calendar navigation listeners prevBtn.addActionListener( btnListener ); nextBtn.addActionListener( btnListener ); closeCalendarBtn.addActionListener( btnListener ); } /* * * * *
Fill the table model with the days in the selected month. Rows in the table correspond to 'weeks', columns to 'days'. Strategy:
ca.janeg.calendar.CalendarComboBox (Java2HTML)
* * * * * * */ private
1. get the first calendar day in the new month 2. find it's position in the first week of the month to determine the starting column for the day numbers 3. find the actual number of days in the month 4. fill the calendar with the day values, erasing any days left over from the old month void updateTable( Calendar cal ){
Calendar dayOne = new GregorianCalendar( cal.get( Calendar.YEAR ), cal.get( Calendar.MONTH ), 1 ); // compute the number of days in the month and // the start column for the first day in the first week int actualDays = cal.getActualMaximum( Calendar.DATE ); int startIndex = dayOne.get( Calendar.DAY_OF_WEEK ) - 1; // fill the calendar for the new month int day = 1; for( int row = 0; row < 6 ; row++ ){ for( int col = 0; col < 7; col++ ){ if( ( col < startIndex && row == 0 ) || day > actualDays ){ // overwrite any left over values from old month display.setValueAt( "", row, col ); }else{ display.setValueAt( new Integer( day ), row, col ); day++; } } } // set the month, year label calLabel.setText( months[ cal.get( Calendar.MONTH ) ] + ", " + cal.get( Calendar.YEAR ) ); // set the calendar selection table.changeSelection( cal.get( Calendar.WEEK_OF_MONTH ) - 1, cal.get( Calendar.DAY_OF_WEEK ) - 1, false, false ); } /* * Gets a Popup to hold the calendar display and determines * it's position on the screen. */ private Popup getPopup(){ Point p = input.getLocationOnScreen(); Dimension inputSize = input.getPreferredSize(); Dimension calendarSize = calPanel.getPreferredSize(); if( ( p.y + calendarSize.height ) < screenSize.height) { // will fit below input panel popup = factory.getPopup( input, calPanel,
http://www.janeg.ca/projects/calendar/CalendarComboBox.java.html (6 of 9) [15/03/2004 8:46:49 AM]
ca.janeg.calendar.CalendarComboBox (Java2HTML)
p.x, p.y + (int)inputSize.height ); } else { // need to fit it above input panel popup = factory.getPopup( input, calPanel, p.x, p.y - (int)calendarSize.height ); } return popup; } /* * Returns the currently selected date as a <code>Calendar</code> object. * * @return Calendar the currently selected calendar date */ public Calendar getDate(){ return current; } /** * Sets the current date and updates the UI to reflect the new date. * @param newDate the new date as a <code>Date</code> object. * @see Date * @author James Waldrop */ public void setDate(Date newDate) { current.setTime(newDate); input.setValue(current.getTime()); } /* * Creates a custom model to back the table. */ private class CalendarModel extends DefaultTableModel { public CalendarModel( int row, int col ){ super( row, col ); } /** * Overrides the method to return an Integer class * type for all columns. The numbers are automatically * right-aligned by a default renderer that's supplied * as part of JTable. */ public Class getColumnClass( int column ){ return Integer.class; } /** * Overrides the method to disable cell editing. * The default is editable. */ public boolean isCellEditable( int row, int col ){ return false; }
http://www.janeg.ca/projects/calendar/CalendarComboBox.java.html (7 of 9) [15/03/2004 8:46:49 AM]
ca.janeg.calendar.CalendarComboBox (Java2HTML)
} /* * Captures the 'prevBtn', 'nextBtn', 'comboBtn' and * 'closeCalendarBtn' actions. * * The combo button is disabled when the popup is shown * and enabled when the popup is hidden. Failure to do * so results in the popup screen area not being cleared * correctly if the user clicks the button while the popup * is being displayed. */ private class ButtonActionListener implements ActionListener { public void actionPerformed( ActionEvent e ){ String cmd = e.getActionCommand(); if( cmd.equals( "prevBtn" ) ){ current.add( Calendar.MONTH, -1 ); input.setValue( current.getTime() ); }else if( cmd.equals( "nextBtn" ) ){ current.add( Calendar.MONTH, 1 ); input.setValue( current.getTime() ); }else if( cmd.equals( "close" ) ){ popup.hide(); comboBtn.setEnabled( true ); }else{ comboBtn.setEnabled( false ); popup = getPopup(); popup.show(); } updateTable( current ); } } /* * Captures a user selection in the calendar display and * changes the value in the 'combo box' to match the selected date. * */ private class CalendarSelectionListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent e){ if ( !e.getValueIsAdjusting() ) { int row = table.getSelectedRow(); int col = table.getSelectedColumn(); Object value = null; try{ value = display.getValueAt(row, col); }catch( ArrayIndexOutOfBoundsException ex ){ // ignore, happens when the calendar is // displayed for the first time }
ca.janeg.calendar.CalendarComboBox (Java2HTML)
if( value instanceof Integer ){ int day = ( (Integer)value ).intValue(); current.set( Calendar.DATE, day ); input.setValue( current.getTime() ); } } } } /* * Captures user input in the 'combo box' * If the input is a valid date and the user pressed * ENTER or TAB, the calendar selection is updated */ private class InputListener extends KeyAdapter { public void keyTyped(KeyEvent e) { DateFormat df = DateFormat.getDateInstance(); Date date = null; try{ date = df.parse( input.getText() ); }catch( ParseException ex ){ // ignore invalid dates } // change the calendar selection if the date is valid // and the user hit ENTER or TAB char c = e.getKeyChar(); if( date != null && ( c == KeyEvent.VK_ENTER || c == KeyEvent.VK_TAB ) ) { current.setTime( date ); updateTable( current ); } } } }
CalendarComboBox
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes
changing the Look and Feel JRadioButtons, ButtonGroup, and mnemonics setting up an ActionListener as an inner class creating an anonymous WindowAdapter, implementing WindowClosing
UML
Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
Mnemonics
A mnemonic allows the user to activate a button by holding ALT + the assigned mnemonic character. Setting the mnemonic for a button is relatively simple, just call the the setMnemonic(char c) method. Button b = new Button("Hello"); b.setMnemonic('h'); That's it, no other coding required. One thing that's nice, if you're in Metal Look and Feel and you a tool tip, any assigned mnemonic is appended to the tip as 'ALT+x' where 'x' = whatever characters been assigned.
ToolTip
The demo doesn't include tool tips (the text you see when the mouse is over the component) but assigning one is easy; just invoke the setToolTextTip(String) method.
http://www.janeg.ca/scjd/gui/simple.html (1 of 2) [15/03/2004 8:46:50 AM]
b.setToolTextTip("The Hello button"); This will work for every component as the method is defined in JComponent (the superclass of all Swing components). Resources
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects
Principles of good GUI Design by James Hobart The Design of Graphic User Interfaces on-line course. The Three Models Used in Designing for Ease of Use IBM Design site. Building user interfaces for object-oriented systems, Part 1 thru 6 JavaWorld articles by Allen Holub Java Look and Feel Design Guidelines from Sun
Swing
q
q q q q q
Swing by Matthew Robinson and Pavel Vorobiev. Book which can be viewed on-line or downloaded as a Word'97 document. Write high-performance RMI servers and Swing clients by Andy Krumel Rendering cells in Swing's JTable component by Brett Spell Add an undo/redo function to your Java apps with Swing by Tomer Meshorer Using the Swing Action Architecture by Mark Davidson (Sun article) Using Timers in Swing Applications by Hans Muller and Kathy Walrath (Sun article) Threads and Swing by Hans Muller and Kathy Walrath (Sun article) Using Dynamic Proxies to Generate Event Listeners Dynamically by Mark Davidson (Sun article) Card Panel - an Alternative to Card Layout by Hans Muller (Sun article) Testing Java Swing-Based Applications by J. D. Newmarch, University of Canberra
q q
Creating a GUI with JFC/Swing tutorial Index of Swing Articles Java TM Look and Feel Graphics Repository, a collection of Toolbar Icons from Sun Resource
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
These notes are derived from the book Object-Oriented Design in Java by Stephen Gilbert and Bill McCarty
A class is a programming construct; a template used to create objects. Try to think in terms of the object vs the class when you start a design. The design process involves building a model of an object using abstraction. An interface describes the services the client wants accomplished ie the object's capabilities or functionality. A public interface describes the objects contract with users. "Always start by designing a minimal public interface." The implementation is how the object goes about providing the services In Procedural programming design is based on the implementation; it is task oriented. Object-Oriented programming design is based on the interface; it is service oriented. You need to be concerned, initially, with what an object can do, not how it does it. Encapsulation hides the non-essentials ie it hides the implementation details. This is not about setting every field to private and writing public gettors and settors. You need to make sure your public interface does not rely on how the objects behaviour is implemented. Think what would happen if every time you upgraded your PC you had to learn a new keyboard layout! Sales would plummet and programmers would become extinct. When you begin to design an object, you need to act like an investigative reporter and discover the: q WHO q WHERE, and q WHAT of an object's existance. q Who is going to use the object? What clients(actors) are going to use the object you're designing q Where is your object going to exist? What hardware and software is involved? Will it exist in a framework ie inside other objects? What operating system will it run on? q What functions should it have from the user's point of view? What services can it be reasonably expected to provide? As a first step, describe, in a single paragraph, exactly what the object you're building should do (requirements). This paragraph is informal and written from a user's perspective ie "I want an object that can display the current date and the time in an analog or digital format." not "This object uses the Java Date class and JPanel to display the date and time. The analog display blah, blah, blah ...."
2. Class fields. A state that holds true for every object in the class. For example, an Employee class may include an id attribute that holds the last id number and is incremented every time a new Employee is created. The value in the id field would be common to all Employee objects. 3. Class constants. Pre-defined conditions that can be applied to all objects in the class. For example, a class that defines buffer objects may have a MAX_BUFFER value.
Behaviour
Design Traps
It might be easier to describe well-designed code in terms of what it is not vs what it is. The following is a summary of such information gleaned from various sources:
Source: Object-Oriented Design in Java by Stephen Gilbert and Bill McCarty Data Warehouse Trap
An object is not a repository for data that the rest of your program will use! An object should manipulate it's own data; not pass it to other parts of the program which then manipulate it.
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects Favourite Links About Feedback
If you read only one book before you start your SCJD assignment make it Effective Java by Joshua Bloch. This is an excellent book that will give you new insights into how the Java language is best utilized. It contains 57 items grouped into categories: Creating and Destroying Objects, Classes and Interfaces, General Programming, Threads, etc. that describe the programming idioms that work best along with the how and why of implementing them.
The Essence of Object-Oriented Programming with Java and UML The Pragmatic Programmer Design Techniques Articles about Java program design by Bill Venners
OOD
OOP
Resources
Home SCJP2 Study Notes Case Studies SCJA Notes SCJD Notes Application Design GUI Design Database Processing Networking Threads Errors and Exceptions Security Documentation Projects
Use and Abuse Cases(PDF) by Martin Fowler Modeling Essential Use Cases by Scott W. Ambler Roles before Objects by Doug Lea Dealing with Roles(PDF) by Martin Fowler
CRC
Class-Responsibility-Collaboration cards. Martin Fowler calls it "One of the most valuable techniques for learning OO" (UML Distilled p9) q A Laboratory For Teaching Object-Oriented Thinking by Ward Cunningham and Kent Beck, the developers of CRC. Two flavours: sequence and collaboration. Useful when trying to capture the behaviour of several objects within a single use case. Martin Fowler recommends using State diagrams to model the behaviour of one object across multiple use cases. (UML Distilled p78) q Introduction to UML sequence diagrams by Scott W. Ambler Classes describe objects in the domain and the static relationships that exist between them. Detail the class data (attributes) and operations (behaviour). q A general discussion of Class Diagrams by Martin Fowler. Includes tips on when and how they are best utilized. q UML Tutorial - Class Diagrams(PDF) by Robert C. Martin
q
Interaction Diagrams
Class Diagrams in Analysis an exercise in developing Class Diagrams from a Use Case accompanied by lecture notes (PDF) which explain the analysis process.
Design Patterns
Patterns are example models of processes that crop up repeatedly in software development. For example, developers are often faced with problems that require moving through a list or collection. The Iterator pattern describes a standard technique for handling iterations. q The Design Patterns Java Companion by James Cooper
q q
Implementing Basic Design Patterns in Java by Doug Lea Speaking on the Observer pattern How can you use the Observer pattern in your Java design? (JavaWorld)
q q
The Essence of Object-Oriented Programming with Java and UML by Bruce E. Wampler (draft of book) Techniques for Object Oriented Analysis and Design by Martin Fowler Systems Analysis and Design A series of lectures and practical exercises based on the book Object-Oriented Systems Analysis and Design using UML by Simon Bennet, Steve McRobb, Ray Farmer Object-Oriented Analysis and Design lecture series by J.W. Schmidt, Claudia Niedere, and Michael Skusa A Commercially Robust Process for the Development of OO Software Systems(PDF)
DOME free modeling software from Honeywell. mUml from MountField Computers free for non-commercial use. Written entirely in Java using Swing GUI. Capabilities allow you to draw all 9 UML diagrams in colour. Diagrams can be saved as JPEGs or saved as HTML pages. If you have Visio v4, v5 or Visio 2000 you can download a free Visio Stencil and Template for UML courtesy of Navision and Paul Hruby. ArgoUML free case tool; part of the Tigris.org open-source platform. If you're using Linux or Sun Solaris, you can download a free copy of JVision for non-commercial use. (Sorry, if you're using Windows it will cost you.)
q q
Miscellaneous
q q
UML Reference Card Allen Holub has put together a great page with annotated UML diagrams. UML Dictionary put together by Kendall Scott, author of The Unified Modeling Language User Guide and four UML/OOP related books. OOP Resources
OOD
Overview User Defined Types Quasi Pseudo Code Notes on Design Using an Abstract class Extending a RuntimeException The GUI implementation Solves a problem or problem domain?
Source
The code for this study is from Developing Java Software, 2nd Edition by Russel Winder and Graham Roberts and may be downloaded from the authors support site. Home | Case Studies
LaTex
LaTex
LaTex is a typesetting system used in the production of technical and scientific documentation. For more information see The LaTex Home Page
Java Quick Reference - Case Study - Mail Merge - User Defined Types
CommandServer
r r
UNIXCommandServer MSWindowsCommandServer
q q q
FilesSelector$BrowseButtonActionListener
q q q
http://www.janeg.ca/case/mail/uml.jpg
http://www.janeg.ca/case/mail/MailMerge.jpg
http://www.janeg.ca/case/mail/CommandServer.jpg
http://www.janeg.ca/case/mail/UNIXCommandServer.jpg
http://www.janeg.ca/case/mail/MSWindowsCommandServer.jpg
http://www.janeg.ca/case/mail/FailedCommandException.jpg
http://www.janeg.ca/case/mail/MessageBox.jpg
http://www.janeg.ca/case/mail/FileSelector.jpg
http://www.janeg.ca/case/mail/BrowseButton.jpg
http://www.janeg.ca/case/mail/Report.jpg
http://www.janeg.ca/case/mail/ExitActionListener.jpg
http://www.janeg.ca/case/mail/ExitWindowAdapter.jpg
Java Quick Reference - Case Study - Mail Merge - Quasi Pseudo Code
Java Libraries
Standard Java library classes were used for file handling: java.io.BufferedReader java.io.File java.io.FileNotFoundException java.io.BufferedWriter java.io.FileReader java.io.IOException
java.io.FileWriter
All of these are listed using import-by-type versus import-on-demand statements. (See the import statements in the MailMerge source code). The standard classes String and StringBuffer were used for string manipulation. Standard Swing classes were extended to create all the GUI elements. javax.swing.JFrame javax.swing.JButton javax.swing.JTextField javax.swing.JDialog javax.swing.JFileChooser javax.swing.JLabel javax.swing.JOptionPane javax.swing.JPanel
Event Listeners
When a listener is required for an event specific to the class it is implemented as an anonymous class. For example, the listener attached to the okButton in FileSelector is declared as an anonymous class implementing the ActionListener interface (see the source code for FileSelector) When a listener is required for an event specific to the class but can be used by more than one component belonging to the class, it is implemented as an inner class. For example, a FileSelector dialog has two browse buttons both of which, when clicked, result in a JFileChooser dialog being displayed. The BrowseButtonActionListener class is declared within the FileSelector class. It implements the ActionListener interface and provides a constructor that takes a JTextField. The value of the parameter is saved so that each new instance of the listener knows which field it must set. When a listener is required for a class but its functionality is not specific to the class (it has a behaviour that could apply in other situations) it is implemented as a separate class. For example, the ExitWindowAdapter, which simply calls System.exit(0), is implemented as a separate class; allowing it to be re-used by other classes.
http://www.janeg.ca/case/mail/mail_5.html (1 of 2) [15/03/2004 8:46:59 AM]
Event listeners are named according to the interface they implement or the adapter they extend and the component they will be registered with. For example, rather than name the listener responsible for closing a window as ExitWindow it is named ExitWindowAdapter. From the name it is evident that the class will cause a window componet to be exited and that the class extends the WindowAdapter class versus implementing WindowListener interface.
Passing parameters
All method parameters (except those in MailMerge.editMarkers() ) are passed as final. It is considered good practice to pass parameters as final if the method will not modify the value in any way. The use of final signals this intent. Also, it allows the compiler to optimize the code for better performance.
Java Quick Reference - Case Study - Mail Merge - Using an Abstract class
Java Quick Reference - Case Study - Mail Merge - The GUI implementation
r r
removed the inheritance to JFrame replaced the indivual fields letterFileName, addressFileName and printerName with a MailMergeInputFields object removed the MailMerge instance and added a JFrame reference. changed all references in the MailMerge class to use the new MailMergeInputFields object and JFrame reference where necesssary.
Made a few other minor changes: split the code in main() into two separate methods, setup() and processFiles() and modified the terminate() method so it could be used as a single exit point from the application. The revised class files are: q MailMergeInputFields
q q q q
MailMerge Note: the commands directed to LaTex have been commented out as it is not installed on my system. FilesSelector Report Revised UML Diagram
http://www.janeg.ca/case/mail/MailMergeInputFields.jpg
http://www.janeg.ca/case/mail/FileSelector_1.jpg
http://www.janeg.ca/case/mail/Report_1.jpg
http://www.janeg.ca/case/mail/MailMerge_1.jpg
http://www.janeg.ca/case/mail/uml_1.jpg
Java Quick Reference - Case Study - Mail Merge - Solves a problem or problem domain?
Overview User Defined Types Where the action is Command Behaviour Unary Function Behaviour Binary Function Behaviour Summary
Source
The code for this study is from Sum it up with JCalculator an article by Claude Duguay in JavaPro, August 2001, Vol.5 No. 8,and may be downloaded from Devx Home | Case Studies
CalculatorButton - defines a button used by the calculator object CalculatorCommands - defines the commands associated with calculator buttons CalculatorField - defines objects used to display information in the calculator CalculatorStack - defines an object to hold the intermediary results of calculator button operations Home | Case Studies | Previous | TOC | Next
http://www.janeg.ca/case/jcalc/images/FullUml.jpg
http://www.janeg.ca/case/jcalc/images/FullUml.jpg
http://www.janeg.ca/case/jcalc/images/JCalculator.jpg
http://www.janeg.ca/case/jcalc/images/CalculatorButton.jpg
http://www.janeg.ca/case/jcalc/images/CalculatorCommands.jpg
http://www.janeg.ca/case/jcalc/images/CalculatorField.jpg
http://www.janeg.ca/case/jcalc/images/CalculatorStack.jpg
if (command instanceof CalculatorCommands.Binary) { evaluate(); CalculatorField field = calculator.getField(); CalculatorStack stack = calculator.getStack(); stack.pushNumber(field.getNumber()); stack.pushFunction((CalculatorCommands.Function)command); field.clearField(); } if (!(command instanceof CalculatorCommands.Function)) { command.exec(calculator); } } // Handle '=' else evaluate(); } Command logic is being handled within the actionPerformed() method and a portion of the command behaviour is implemented in the CalculatorButton.evaluate() method rather than by the command object itself. protected void evaluate() { CalculatorStack stack = calculator.getStack(); if (!stack.isEmpty() && stack.isFunction()) { CalculatorField field = calculator.getField(); CalculatorCommands.Function function = stack.popFunction(); stack.pushNumber(field.getNumber()); function.exec(calculator); field.setNumber(stack.popNumber()); } } This makes it a little more difficult to work out what is actually happening when a calculator button is clicked on. UML Sequence diagrams can help when you're trying to sort out interactions between objects. Home | Case Studies | Previous | TOC | Next
From the above we can see that 1. when an ActionEvent is triggered it is sent to a CalculatorButton 2. the button invokes the exec() method of its assoicated command object, passing it a reference to the calculator object 3. the command object uses the reference to the calculator object to get a reference to the CalculatorField being used to display the numbers entered by the user and the results of any calculations 4. the command object then uses the field reference to set the text in the field or add a digit to the text already being displayed Let's say a user clicks on the "1" calculator button. This generates an ActionEvent and the button is notified; invoking its actionPerfomed() method. The method checks to make sure the command associated with itself is not a Function and calls the exec() method of it's Command object. In this case, the object is type One. The exec() method in the One class is implemented as follows: public void exec(JCalculator calculator) { CalculatorField field = calculator.getField(); field.addDigit(1); } The addDigit() of CalculatorField actually concatenates the digit '1' to any text currently being displayed. For example, what we see before we click on the '1' button is:
That's fairly straight forward. Unary function commands are a bit more complicated. Home | Case Studies | Previous | TOC | Next
Every button has an associated CalculatorCommands.Command object reference and a JCalculator reference. Lets assume the calculator button that was clicked has a Sqrt command of type CalculatorCommands.Sqrt which implements Unary. The code for Sqrt is: public static class Sqrt implements Unary { public void exec(JCalculator calculator) { CalculatorStack stack = calculator.getStack(); stack.pushNumber(Math.sqrt(stack.popNumber())); } } The Sqrt button is clicked, an ActionEvent is raised and the buttons actionPerformed() method is invoked.
1. the actionPerformed() method checks its objects (the buttons) command object type and determines its of type CalculatorCommands.Unary 2. it invokes its own evaluate() method 3. the buttons reference to the calculator object is used to get a reference to the calculators stack 4. the stack isEmpty() method is invoked and returns 'true' so evaluate() returns control to the actionPerformed() method 5. the actionPerformed() method retrieves a reference to the calculators stack through the buttons calculator reference 6. the buttons command object (in this case aSqrt) is pushed onto the stack 7. the buttons evaluate() method is again invoked 8. a reference to the calculators stack is retrieved 9. this time the stack is not empty and its top object is a function (the Sqrt object) 10. the buttons calculator reference is used to retrieve a reference to the calculators display field 11. the Sqrt object is popped off the calculators stack 12. the field reference is used to retrieve the number currently displayed 13. the retrieved number is pushed onto the stack 14. the Sqrt objects exec() method is invoked and a copy of the buttons calculator reference is passed as an argument 15. the Sqrt object uses its calculator reference (the one passed to exec() ) to get a reference to the calculator stack 16. the number pushed onto the stack in evaluate() is popped off the stack and used as an argument to Math.sqrt() 17. the result returned by Math.sqrt() is pushed onto the stack 18. control returns to the buttons evaluate() method 19. the result pushed onto the stack by the Sqrt object is retrieved and passed to the calculator field by invoking the fields setNumber() method 20. the evaluate() method returns control to the actionPerformed() method 21. there is nothing else to do Whew! There are an awful lot of busy objects! The actual job of providing the square of a number is handled by the command object, Sqrt, but the responsibility for getting everything ready for the Sqrt object is being handled by the button object. Hmmm ... still not all that clear; lets try to think of it as a conversation between actors. The cast: q Button - a CalculatorButton q Calculator - a JCalculator that belongs to Button q Sqrt - a CalculatorCommands.Unary that belongs to Button q Math.sqrt - a friend of Sqrt's q ActionPerformed - Button's helper q Evaluate - Button's helper q Stack - a CalculatorStack that belongs to Buttons calculator q Display - a CalculatorField that belongs to Buttons calculator Button: get to work!" ActionPerformed: Evaluate "Hey, I've just been clicked! ActionPerformed, you need to
"Ok. Do we have a command? Oh yeah, a Sqrt and its a Unary. can you check things for me?"
"Sure thing. Calculator, pass me your Stack for a minute." "Here he is." [Hands Stack to Evaluate] "Oops .. its empty nothing for me to do. ActionPerformed,
"Calculator, let me have your Stack. Stack, here, take a copy [Hands Sqrt to Stack] "Ok Evaluate, your turn again."
"Calculator, can you let me see Stack again?" "Sure." [Hands Stack to Evaluate] "Alright Stack are you empty?" "Nope." "Do you have a function?" "Let me see, yup, I got a function on top of me." "Great. Calculator, can you give me your Display?" [Calculator hands Display to Evaluate]
Evaluate:
"Stack, let me have that function and Display, you give Stack the number you're holding." [Stack hands Sqrt to Evaluate and Display gives Stack a
number] Evaluate: Calculator" "Ok Sqrt, you do your thing. Oops, here you need to talk to [Hands Sqrt a connection to Calculator] Sqrt: "Calculator, give me Stack please."
[Calculator hands over Stack] Stack (sotto voice): "Hey, I'm tired of being man handled! Geesh, don't you guys have anything better to do!" Sqrt: Math.sqrt." Math.sqrt: back now." Sqrt: I'm finished." Evaluate: hands everyone?" Display: all to see] Evaluate: ActionPerformed: Button: "Ok ActionPerformed, I'm finished!" "Button, we're all done now." "Thanks guys. What a team!" [The End] That's a little clearer. The calculator is basically acting as a holder for all the objects. The actionPerformed() and evaluate() methods in CalculatorButton are directing events and the actual work/function is being handled by the "Sure thing." [Display takes the number and holds it up for "Stack, give me the number your holding. I need to pass it to
"Here Sqrt, I did my thing with the number, you can have it
"Here you go Stack ... take number back now. Hey Evaluate,
"Stack, let me have the number Sqrt just gave you." [Stack the number to Evaluate]. "Display, can you show this to
CalculatorCommands.Command object. So what happens if the command object is a Binary function? Home | Case Studies | Previous | TOC | Next
Hmmm .. the stack is being setup but no calculations are happening. How does a Binary function get executed? You'd expect the user to enter another digit followed by "=". Lets take another look at actionPerformed(). public void actionPerformed(ActionEvent event) { if (command != null) { if (command instanceof CalculatorCommands.Unary) { evaluate(); CalculatorStack stack = calculator.getStack(); stack.pushFunction((CalculatorCommands.Function)command); evaluate(); } if (command instanceof CalculatorCommands.Binary) { evaluate(); CalculatorField field = calculator.getField(); CalculatorStack stack = calculator.getStack(); stack.pushNumber(field.getNumber()); stack.pushFunction((CalculatorCommands.Function)command); field.clearField(); } if (!(command instanceof CalculatorCommands.Function)) {
command.exec(calculator); } } // Handle '=' else evaluate(); } It looks like "=" is not a Command object. Only the evaluate() method comes into play. Ok, so let's say the user enters '1 + 1 =', what happens?
This time there is something on the stack; the '1' and '+' placed there earlier, so evaluate() pops off the function, pushes the current number (the one in the display area) onto the stack and then invokes the functions exec() method. Then Binary.exec() method then retrieves both the numbers from the stack and performs its operation, pushing the result back onto the stack. The evaluate() method then pops the result off the stack and calls the display fields setNumber() method; which shows the result of the operation to the user. But what happens if '=' isn't pressed after the second digit is entered? What if the user enters '1 + 1 + 2' before hitting '='?
Almost the same thing as happens when '=' is pressed except that the previous function is evaluated and the result of the operation is placed on the stack followed by the current function. The '1 + 1 + 2' would result in the following: User Enters 1 + 1 + Field Display 1 blank 1 blank Stack empty + 1 + 1 + 2
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the package contains three main groups of classes and interfaces 1. classes to build data streams 2. classes and interfaces for serialization 3. classes and interfaces for working with the file system
data streams that read values from a data source are input streams data streams that write values to a data repository are output streams the data can be either byte or character values Character Streams abstract class Reader abstract class Writer
DataStream SuperClasses Byte Streams abstract class InputStream abstract class OutputStream
q
there are two classes which convert bytes to characters class InputStreamReader extends Reader class OutputStreamWriter extends Writer data containers, for example files, usually provide methods which return a stream for either reading or writing data streams can be chained together
Filter Streams
q q q
filter streams perform some processing or filtering as the data is passed through a filter ouput stream performs the processing before the data is written out a filter input stream performs the processing after the data is read from its original source Character Streams class FilterReader class FilterWriter
there are number of filter streams for both byte streams BufferedInputStream DataInputStream LineNumberInputStream PushbackInputStream and character streams BufferedReader LineNumberReader PushbackReader BufferedOutputStream DataOutputStream PrintStream
PrintWriter
In-Memory Streams
q
there are also classes for reading and writing data held in memory CharArrayReader CharArrayWriter StringReader StringWriter the StringReader/Writer classes read data from a StringBuffer object ByteArrayInputStream ByteArrayOutputStream
Pipes
q
there are classes that allow you to build streams that operate between threads PipedInputStream PipedOutputStream PipedReader PipedWriter
Files
q
there are a number of classes for working with the file system File FileDescriptor FileInputStream FileReader FileOutputStream FileWriter FilenameFilter FilePermission RandomAccessFile note that File, FileDescriptor and RandomAccessFile are direct subclasses of Object Note
Serialization (JCL1)
q
serialization is the process of converting an object to a stream of bytes in such a manner that the original object can be rebuilt (lets you write an object to a file or other data container)
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
Suns Java Tutorial on I/O also breaks up the classes into Data Sink Streams and Data Processing Streams a sink is a specialized data container ie strings, files, pipes Byte Streams ByteArrayInputStream, ByteArrayOutputStream StringBufferInputStream PipedInputStream, PipedOutputStream FileInputStream, FileOutputStream
Sink Type Character Streams Memory CharArrayReader, CharArrayWriter StringReader, StringWriter Pipe File
q
data processing streams perform some type of operation ie buffering or character encoding CharacterStreams BufferedReader, BufferedWriter Byte Streams BufferedInputStream, BufferedOutputStream
Process Buffering Filtering Converting between Bytes and Characters Concatenation Object Serialization Data Conversion Counting
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
Reader and Writer are the abstract superclasses for all character streams.
Note: Classes shown in 'yellow' are abstract. Items shown in 'gray' read and write from data sinks. Images are from the Sun Tutorial on I/O character streams can read or write any Unicode character set. Byte streams are limited to ISO-Latin-1 8-bit encoding.
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams
Note:Classes in 'yellow' are abstract. Classes in 'gray' read and write to data sinks. Images from Sun Java I/O tutorial ObjectInputStream and ObjectOutputStream are used for serialization !!! Warning !!!
Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
used to access file and directory objects using the file-naming, path conventions of the implementing operating system the class has three constructors File(String pathname) File(String parent, String child) File(File parent, String child) where, parent is the pathname child is the filename used to create an instance of a File BUT does not actually create a file // does not create a file on the system new File("test.txt"); however, you can use the createNewFile() method File f = new File("test.txt"); // returns 'false' if file exists f.createNewFile(); or, the method createTempFile() which creates the file in the default temporary directory using specified file extensions the class has four CONSTANTS which define properties of the file conventions on the operating system char separatorChar the field is initialized to hold the system separator / for UNIX \ for Win32 : for Mac String separator a string representation of the separatorChar char pathSeparator initialized to hold the character used by the system to separate file names in a list : for UNIX ; for Win32 String pathSeparator string representation of the pathSeparator character
FileName Methods
q
there are a number of methods for retreiving filenames, paths, etc getAbsolutePath() getCanonicalPath() getName() getParent() getPath() compareTo() getAbsoluteFile() getCanonicalFile() getParentFile()
toURL() the absolute path is system dependent and may include relative indicators For example, the following code creates a file 'test2.txt' in the directory directly above the current directory: File f1 = new File("..", "test2.txt") f1.createNewFile(); System.out.println( f1.getAbsolutePath() ); Output (on Win98): D:\Java\jeg\io\..\test2.txt the canonical path is the same as the absolute path BUT all relative indicators are resolved For example, System.out.println( f1.getCanonicalPath() ); Output (on Win98): // '..' in absolute path is resolved D:\Java\jeg\test2.txt toURL() will construct a valid URL identifier for the File System.out.println( f.toURL() ); Output: file:/D:/Java/jeg/io/test1.txt Note
q q
the File class overrides the Object.equals() method. Two files are equal() if they have the same path, NOT if they refer to the same underlying file system object.
there are methods to check the status of a file canRead() canWrite() exists() length() lastModified() setLastModified() setReadOnly() isDirectory() isFile() isHidden() isAbsolute()
there are a number of methods for modifiying files and creating directories delete() mkdir() listFiles() deleteOnExit() mkdirs() listRoots() renameTo() list() and listFiles() can be used with FilenameFilters ie '*' listRoots() returns the system drives while renameTo() will change the name of the file on the system, the reference will return the original path and name // File object reference
q q q
File f = new File("test.txt"); f.createNewFile(); // creates the file // new File reference File f2 = new File("testRename.txt"); f.renameTo(f2); // renames the file System.out.println( f.getAbsolutePath() ); Output (on Win98): D:\Java\jeg\io\test1.txt // original path for 'f' And if you check to see which file actually exists on the system: System.out.println( f.exists() ); System.out.println( f2.exists() ); Output: false true Note
q
Security
q
many of the above methods will work correctly only if they are allowed by the security permissions for example, an Applet would probably not be allowed to create a new file
TestFileClass.java
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
InputStreamReader extends Reader and has one subclass, FileReader InputStreamReader reads bytes and translates them to Unicode characters using the specified character encoding or the default system encoding the class has two constructors InputStreamReader(InputStream in) InputStreamReader(InputStream in, String enc) to use an InputStreamReader you must first create an instance of it for a byte input stream. You can then read the stream using any of the Reader methods.
OutputStreamWriter
q q
OutputStreamWriter extends Writer and has one subclass, FileWriter OutputStreamWriter translates between Unicode characters and bytes using the specified character encoding or the default system encoding the class also has two constructors OuputStreamWriter(OutputStream out) OuputStreamWriter(OutputStream out, String enc) you use OutputStreamWriter by first creating an instance of it for a byte output stream; you can then write to the stream using an Writer methods.
Character Encoding
q q
Character encodings specify how 8-bit bytes are translated to 16-bit Unicode they are represented by Strings which follow the naming standards set by IANA Character Registry every implementation of Java is required to support the following sets: US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1 UTF-8 Eight-bit Unicode Transformation Format UTF-16BE Sixteen-bit Unicode Transformation Format, big-endian byte order UTF-16LE Sixteen-bit Unicode Transformation Format, little-endian byte order UTF-16 Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either order accepted on input, big-endian used on output) specific platforms ie those used in Japan, China, Mid-East, etc, may include other encodings
the streams are used to read and write data encoded in a character set which is different than the default system encoding For example (JPL pg238), to read bytes encoded under ISO 8859-6 for Arabic characters public Reader readArabic(String file) throws IOException { InputStream fileIn = new FileInputSgream(file); return new InputStreamReader(fileIn, "iso-8859-6"); }
File Class
Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
Filters sit between input and output streams, processing the bytes being transferred FilterInputStream extends InputStream and FilterOutputStream extends OutputStream this means a FilterInputStream, and any of it's subclasses, can take any InputStream as an argument and a FilterOutputStream can take any OutputStream this allows the chaining of filter streams ie a FilterInputStream can take another FilterInputStream; the original source can be an object that is not a filter stream as long as it isn't reading from another input stream Output filters can also be chained, you can have as many filters as you like but the last in the chain must be an OutpuStream both methods simply override all their inherited methods, passing all their processing along to the underlying Input or Output stream Constructors BufferedInputStream(InputStream in) BufferedInputStream(InputStream in, int size) DataInputStream(InputStream in) LineNumberInputStream(InputStream in) PushbackInputStream(InputStream in) PushbackInputStream(InputStream in, int size)
FilterOutputStream Subclasses Subclass Constructors BufferedOutputStream BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out, int size) DataOutputStream DataOutputStream(OutputStream out) PrintStream PrintStream(OutputStream out) PrintStream(OutputStream out, boolean autoflush)
q
technically, you should use PrintWriter when doing character related I/O , PrintStream is included for historical reasons. It should only be used with System.in as it assumes Latin-1 character encoding. most Reader and Writer classes can also act as filters as most of them already have constructors which take another character stream to create your own filter streams 1. Create subclasses of FilterInputStream and FilterOutputStream 2. Override the read() and write() methods 3. Override any other methods you might need 4. Make sure the input and output streams work together
Summary
q q q q
If its an input filter, it can take any InputStream object. If an output filter, it can take any OutputStream object. FilterWriter classes take a Writer object. FilterReader classes take a Reader object.
TestFilterWriter.java
File Class
Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
DataInputStream and DataOutputStream, like all filters, must be attached to some other stream DataInputStream implements DataInput and has one ctor DataInputStream(InputStream in) DataOutputStream implements DataOutput has one ctor DataOutputStream(OutputStream out) and one field written which contains the number of bytes written. Note: if this overflows it is set to Integer.MAX_VALUE. DataInputStream has specialized read() methods, and DataOutputStream, specialized write() methods to handle the various primitive types and UTF-8 characters DataOutputStream Methods write(int oneByte) write(byte[] buf) write(byte[] buf, int offset, int count) writeBoolean(boolean b) writeByte(int val) writeBytes(String str) writeChar(int val) writeChars(String str) writeDouble(double val) writeFloat(float val)
DataInputStream Methods read(byte[] buf) read(byte[] buf, int offset, int count) readBoolean() readByte() readChar() readDouble() readFloat() readFully(byte[] buf) readFully(byte[] buf, int offset, int count) readInt() readLine() readLong() readShort() readUnsignedByte() readUnsignedShort() readUTF() skipBytes()
writeUTF(String str) Items in red are deprecated. All the methods throw IOException
DataIOTest.java
Character Streams
Byte Streams
File Class
Filter Streams
Data Input/Output
Serialization
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
q q
FileStreams have three types of constructors 1. a constructor that takes a filename as a String 2. a constructor that takes a File object 3. a constructor that takes a FileDescriptor object when constructors (1) or (2) are used, a new FileDescriptor object is created. This can be accessed by calling getFD() a FileDescriptor object represents a system-dependent value that describes an open file FileOutputStream has one additonal constructor FileOutputStream(String name, boolean append) if the file exists, you can set append to true to force the write to occur at the end of the file; otherwise, the existing file is overwritten FileOutputStream (and FileWriter) have a flush() method that forces the underlying buffer to be flushed. Note
flush() does NOT guarantee that the contents will be written to disk. To guarantee the data is written to disk use the FileDescriptor method sync() FileReader and FileWriter read and write 16-bit Unicode characters FileInputStream and FileOutputStream read and write bytes
q q
the RandomAccessFile class is NOT a subclass of InputStream, OutputStream, Reader or Writer; instead it incorporates all their functionaly plus additional methods by implementing the DataInput and DataOutput interfaces. Note
You cannot use a RandomAccessFile object where any of the other input and output streams are required. the class has two constructors public RandomAccessFile(String name, String mode) public RandomAccessFile(File file, String mode) the mode argument must be either "r" or "rw" to indicate if the file is to be opened for reading only or reading and writing if the file is opened for writing and it does not exist; it will be created as with the other File streams, a FileDescriptor object is created when the file is opened the class allows you to set a read/write pointer to any position in the file key methods are: public public public public long void void long getFilePointer() throws IOException seek(long pos) throws IOException skipBytes(int count) throws IOException length() throws IOException
Feedback
q q q q
Read a file using FileInputStream Write to a file using FileWriter Copy a file (jung.txt) to another file using FileReader and FileWriter An example, CopyBytes, to do the same thing using FileInputStream and FileOutputStream Test using a RandomAccessFile
File Class
http://www.janeg.ca/scjp/io/jung.txt
The bigger the crowd the more negligible the individual becomes. But if the individual, overwhelmed by the sense of his own puniness and impotence, should feel that his life has lost its meaning--which, after all, is not identical with the public welfare and higher standards of living--then he is already on the road to State slavery and, without knowing or wanting it, has become its proselyte. The man who looks only outside and quails before the big battalions has no resource with which to combat the evidence of his senses and his reason. But that is just what is happening today: we are all fascinated and overawed by statistical truths and large numbers and are daily apprised of the nullity and futility of the individual personality, since it is not represented and personified by any mass organization. C.G. Jung, The Undiscovered Self, New American Library, 1958
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
serialization is the process of converting an object to a stream of bytes in such a manner that the original object can be rebuilt (lets you write an object to a file or other data container) an object can be serialized only if it's class implements the Serializable or Externalizable interface; it's superclass must have a no-arg default constructor or be Serializable itself a classes serializable fields are all of its nontransient and nonstatic fields; this applies to all public, protected, package and private fields (JCL1) Note
q q q q q
the serialized fields are written out using ObjectOutputStream.defaultWriteObject() and read back using ObjectOutputStream.defaultReadObject() all the objects referred to directly or indirectly are also serialized if a field contains an object that is not serializable, a NotSerializableException is thrown deserialization is the process of restoring a serialized object to a copy of the original object all Java primitive types, arrays, Strings and objects can be serialized/deserialized primitive types can be serialized using DataInputStream Interface and deserialized using DataOutputStream Interface
File Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
a collection is a container or object that groups multiple objects into a single unit a Collections Framework provides a unified system for organizing and handling collections and is based on four elements: 1. Interfaces that characterize common collection types 2. Abstract Classes which can be used as a starting point for custom collections and which are extended by the JDK implementation classes 3. Classes which provide implementations of the Interfaces 4. Algorithms that provide behaviours commonly required when using collections ie search, sort, iterate, etc.
the Collection Framework also provides an interface for traversing collections: Interator and it's subinterface ListIterator the Iterator interface should be used in preference to the earlier Enumeration interface
Collections Framework
Collection
Abstract Classes
Iterator
List
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
this is the root interface for the collection heirarchy it is not directly implemented by an SDK class; instead they implement the subinterfaces List or Set it is typically used to manipulate and pass collections around in a generic manner classes which implement Collection or one of it's subinterfaces must provide two constructors 1. a default, no-argument constructor, which creates an empty collection, and 2. a constructor which takes a Collection as an argument and creates a new collection with the same elements as the specified collection Query Methods
returns true if the collection contains the specified element returns true if the collection has no elements returns an Iterator object. There is no guarantee as to the order of the returned elements unless the collection is an instance of a class that guarantees the order. returns the number of elements in the collection or Integer.MAX_VALUE if the collection equals or exceeds Integer.MAX_VALUE returns the collection elements as an array. If the collection class guarantees an order, the array elements are in the guaranteed order. returns all the elements in the collection whose type is that of the array type. If the collection does not fit in the array, a new array of the same type is returned. If the array is larger than the collection, the array element after the last collection element is set to null Bulk Methods
size()
toArray()
toArray(Object a[])
containsAll(Collection c) returns true if the collection contains the all the elements in the specified collection addAll(Collection c) clear() adds all the elements in the specified collection to this collection removes all the elements in the collection
removeAll(Collection c) removes all the this collections elements that are in the specified collection. retainAll(Collection c) retains all the elements in this collection that are contained in the specified collection Modification Methods
add(Object o)
adds an element to the collection. Returns false if the element is not added as the collection class guarantees no duplicates. removes the specified object from the collection, if it exists. equals() and hasCode()
remove(Object o)
equals(Object o)
programmers may override the Object.equals() method to implement collection specific comparisons eg "value" comparison vs "reference" comparison programmers overriding equals() must also override Object.hashCode()
hashCode()
Tips
q
any SDK class which implements Collection or any of it's subinterfaces will contain the two required constructors CollectionName() and CollectionName(Collection c)
Collections Framework
Collection
Abstract Classes
Iterator
List
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
provide skeletal implementations that can be used as the basis for building custom collection classes available classes are: 1. 2. 3. 4. 5. AbstractCollection AbstractList AbstractMap AbstractSequential AbstractSet
JSK implementations extend the applicable Abstract class and implement the appropriate Interface
Collections Framework
Collection
Abstract Classes
Iterator
List
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
used to sequentially access collection elements element order depends on the collection ie List elements are presented as they appear in the List, Set elements can be in any order Iterator Methods
hasNext() returns true if the iteration has more elements next() returns the next element in the iteration
remove() removes the most recently retrieved element from the underlying collection
q
has one subinterface, ListIterator, which allows a programmer to traverse a List in either direction and make modifications to the underlying List java.util.ListIterator Methods Query Methods
returns true if there are more elements in a forward direction returns true if there are more elements in a backward direction returns the next element in the List returns the index of the next element in the list, or, the size of the list if there are no more elements returns the previous element in the List
previousIndex() returns the index of the previous element in the list. If positioned at the first element, returns -1 Modification Methods add(Object obj) inserts the new object immeadiately before the element which would be returned by next(). remove() removes the last element in the List retrieved by a next() or previous() operation. Can only be made once after a next() or previous() operation and cannot be made if there has been an intervening add(). set(Object obj) replaces the last element in the List retrieved by a next() or previous() operation; there can be no intervening call to add() or remove().
Collections Framework
Collection
Abstract Classes
Iterator
List
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
a List is a collection whose elements can be accessed by an index the indices are zero-based a list has methods for inserting and removing elements a list can contain duplicate elements a List provides a special ListIterator which allows you to move backwards and forwards through the elements there are three basic ways in which a List can be modified: 1. add an element 2. remove an element 3. replace an element a list can support any or none of the above; attempts to modify a list that does not support the above will result in an UnsupportedOperationException there is no way to append Lists unless you provide your own method java.util Implementations of List
ArrayList
extends AbstractList implements List, Cloneable, Serializable Elements are ordered. Internally uses an array to store elements. Index access is quick, while adding and removing elements, except at the end of the array, is expensive.
LinkedList extends AbstractSequentialList implements List, Cloneable, Serializable Elements are ordered. Internally uses a doubly linked list to store elements. Adding and removing elements involves updating two links; index access is slow as the entire list must be traversed. LinkedList retains a reference to both the first and last elements; retrieving the first or last element is efficient. Vector extends AbstractList implements List, Cloneable, Serializable Older class that was modified in JDK 1.2 to implement List. An expansible array. The vector will grow automatically to take new objects. You can also shrink a Vector. Otherwise, manipulated the same as an array. May contain null elements. All methods are synchronized
List Methods
Positional Methods get(int index) set(int index, Object element) add(int index, Object element) returns the element at the specified position replaces the element at the specified position with the given object inserts the specified element at the specified position, shifting all the elements and adds one to their index values removes the element at the specified position, shifiting all the elements and subtracting one from their indices Search Methods indexOf(Object o) lastIndexOf(Object o) returns the index of the first occurence of the specified element or -1 if it is not found returns the index of the last occurence of the specified element or -1 if it is not found List Iterator listIterator() listIterator(int index) returns a list iterator of the elements in their proper sequence returns a list iterator of elements starting at the specified index
remove(int index)
subList(int fromIndex, int toIndex) returns the portion of the list between the specified indices exclusive of the toIndex element
Collections Framework
Collection
Abstract Classes
Iterator
List
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the java.lang Package contains classes that are fundamental to the Java programming language it is always implicitly imported the most important classes are Object and Class
Object
q
the Object class is at the root of the class heirarchy, all other classes inherit it's methods protected Object clone() throws CloneNotSupportedException returns an identical copy of an object. The object must implement the Cloneable interface public boolean equals(Object obj) returns true if obj is the same object as the referenced object protected void finalize() throws Throwable called by the garbage collector prior to collecting the object public final Class getClass() returns the runtime class of an object public int hashCode() returns a distinct integer representing a unique object; supports hash tables public final void notify() wakes up a single thread waiting on the object's monitor public final void notifyAll() wakes up all threads waiting on the object's monitor public String toString() returns a string representation of the object public final void wait() throws InterruptedException, public final void wait(long timeout) throws InterruptedException, public fianl void wait(long timeout, int nanos) throws InterruptedException causes the current thread to wait until another thread invokes notify() or notifyAll() for this object, or, the specified time elaspses
Class
q q q q
q q
the Class class was introduced in JDK 1.2 instances of the Class class represent classes and interfaces in a running Java application also represents arrays, primitive types and void, all of which are Class instances at runtime objects of the Class class are automatically created as classes are loaded by the JVM; they are known as class descriptors provides over 30 methods which can be used to obtain information on a running class some of the more useful methods are: getName(), toString(), getSuperclass(), isInterface(), newInstance()
Other classes
q
q q q
Wrapper classes used to represent primitive types as Objects: Boolean, Byte, Short, Character, Integer, Float, Long and Double Math class provides commonly used mathematical functions ie cos, sine, tan String and StringBuffer classes provide commonly used operations on character strings System operation classes: ClassLoader, SecurityManager, Runtime, Process and System which manage the dynamic loading of classes, creation of external processes, security, and host inquiries ie time of day Package class is new to JDK 1.2. Provides methods for obtaining package version information stored in the manifest of jar files. Useful methods include: getPackage(), getAllPackages(), which provide package objects that are known to the class loader, and isCompatibleWith() which is used to determine wether a package is comparable to a particular version. all the Exception and Error classes, including Throwable
Interfaces
q
Cloneable. Contains no methods. Used to differentiate between objects that are cloneable and non-cloneable. Comparable, new in JDK 1.2. Defines the compareTo() method. Objects implementing this interface can be compared and sorted. Runnable. Defines the run() method which is invoked when a thread is activated. Wrapper Classes Math Class String Immutability String Class StringBuffer Class
Main Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package
one for each primitive type: Boolean, Byte, Character, Double, Float, Integer, Long, and Short Byte, Double, Float, Integer and Short extend the abstract Number class all are public final ie cannot be extended get around limitations of primitive types allow objects to be created from primitive types all the classes have two constructor forms r a constructor that takes the primitive type and creates an object eg Character(char), Integer(int) r a constructor that converts a String into an object eg Integer("1"). Throws a NumberFormatException if the String cannot be converted to a number Note
The Character class does not have a constructor that takes a String argument all, except Character, have a valueOf(String s) method which is equivalent to new Type(String s) all have a typeValue() method which returns the value of the object as it's primitive type. These are all abstract methods defined in Number and overridden in each class r public byte byteValue() r public short shortValue() r public int intValue() r public long longValue() r public float floatValue() r public double doubleValue() all the classes override equals(), hashCode() and toString() in Object r equals() returns true if the values of the compared objects are the same r hashCode() returns the same hashcode for objects of the same type having the same value r toString() returns the string representation of the objects value all have a public static final TYPE field which is the Class object for that primitive type all have two static fields MIN_VALUE and MAX_VALUE for the minimum and maximum values that can be held by the type
The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
q q
Void
q
there is also a wrapper class for Void which cannot be instantiated. Note
The constructors and methods described above do NOT exist for the Void class although it does have the TYPE field.
Character
q
contains two methods for returning the numeric value of a character in the various number systems
public static int digit(char ch, int radix) r public static int getNumber(char ch) and one method to return the character value of a number r public static char forDigit(int digit, int radix) has two case conversion methods r public static char toLowerCase(char ch) r public static char toUpperCase(char ch) also contains a variety of other methods to test wether a character is of a specific type eg isLetter(), isDefined(), isSpaceChar(), etc getType() returns an int that defines a character's Unicode type
r
all have parseType methods eg parseInt(), parseShort, etc that take a String and parse it into the appropriate type 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
q q
both classes have static fields which define POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN and the following methods to test a value r public boolean isNan() r public static boolean isNaN(type value) r public boolean isInfinite() r public static boolean isInfinite(type value) Float also has a constructor that takes a double value both classes have methods to convert a value into a bit pattern or vice versa r public static int floatToIntBits(float value) r public static float intBitsToFloat(int bits) r public static long doubleToLongBits(double value) r public static double longBitsToDouble(long bits) Wrapper Classes Math Class String Immutability String Class StringBuffer Class
Main Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads
contains static constants E and PI 2.718281828459045 3.141592653589793 contains methods for common mathematical operations ie abs, sin, exp, round, etc. all methods are static the Math class cannot be instantiated methods involving angles use radians vs degrees and minutes all methods, except round(), return a double all methods take at least one double as an argument, except random which takes no arguments the following methods are overloaded to return and handle int, long and float r static type abs(type a) r static type max(type a, type b) r static type min(type a, type b)
E: PI:
q q q q q q
The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes
IEEEremainder
q q
calculates the remainder as defined by IEEE-754 the remainder operator, %, makes values symmetric around zero ie negative and positive values return corresponding remainders
7 % 2.5: 2.0 -7 % 2.5: -2.0 q Math.IEEEremainder keeps resulting values y units apart Math.IEEEremainder( 7, 2.5): Math.IEEEremainder(-7, 2.5): -0.5 0.5
abs()
Projects
q
Favourite Links About Feedback Math.abs(1234.59): 1234.59 Math.abs(-0.0): 0.0 Math.abs(Float.NEGATIVE_INFINITY): Infinity Math.abs(Float.NaN): NaN q EXCEPT if the value is equal to Integer.MIN_VALUE, in which case, it returns the value as a negative Math.abs(Integer.MIN_VALUE): -2147483648
ceil()
q
returns the smallest double value not less than the argument and equal to an integer (counts up)
if the argument is already an integer, returns the argument if the argument is NaN or infinity, returns the argument if the argument is between -1.0 and 0, returns 0 10.0 -9.0 10.0 -0.0 NaN // counts up (away from zero) // counts up (towards zero)
floor()
q
q q q
returns the largest double value not greater than the argument and equal to an integer (counts down) if the argument is an integer, returns the argument if the argument is NaN, infinity, negative or positive zero, returns the argument if the argument is between -0 and 0, returns -0 9.0 -10.0 10.0 -1.0 NaN // counts down (towards zero) // counts down (away from zero)
min() returns the smallest of two values max() returns the largest of two values
Math.min(-1.5, 1.5): -1.5 Math.max(-1.5, 1.5): 1.5 Math.min(0.0, -0.0): -0.0 // zeros are not equivalent Math.min(Float.NaN, Float.POSITIVE_INFINITY)); NaN
random()
q q
returns a pseudo-random positive double number between 0.0 and 1.0 if you want to seed the number or generate random numbers in different ranges use the java.util.Random class 0.2379468138972043
Math.random():
round()
q
q q q q
has two versions r public static long round(double a) r public static int round(float a) only method that does not return a double adds 0.5 to the argument and returns the closest int if the argument is not a number, returns zero if the argument is a negative infinity or less than the MIN_VALUE for the type, returns the MIN_VALUE if the argument is a positive infinity or greater than the MAX_VALUE for the type, returns the MAX_VALUE
Math.round( 1.5): 2 Math.round(-1.5): -1 Math.round(Float.NaN): 0 Math.round(Float.NEGATIVE_INFINITY): -2147483648 Math.round(Double.POSITIVE_INFINITY): 9223372036854775807 Math.round(Float.MAX_VALUE): 2147483647 (Float.MAX_VALUE is 3.4028235E38) Note
q
rint()
q q
rounds to the closest integer if integers are equidistant, favours the even integer 6.0 -6.0 5.0 -5.0
sqrt()
q q
returns the positive square root of a number returns NaN if argument is negative 6.708203932499369 NaN
Math.sqrt(45): Math.sqrt(-45):
pow(double a, double b)
q
returns the first argument raised to the power of the second argument 4.0
Math.pow(2,2):
Trigometric functions
all results are returned in radians there are 2 * PI degrees in a circle, ie 2/PI = 90 degrees sin(double a) if the result is NaN or infinity, returns NaN if the result is negative zero, returns -0.0 cos(double a) if the result is NaN or infinity, returns NaN tan(double a) if the result is NaN or infinity, returns NaN if the result is negative zero, returns -0.0 asin(double a) returns a value between -PI/2 and PI/2 if the result is NaN or absolute value is greater than 1, returns NaN if the result is negative zero, returns -0.0 acos(double a) returns a value between 0.0 and PI if the result is NaN or absolute value is greater than 1, returns NaN
q q
atan(double a) returns a value between -PI/2 and PI/2 if the result is NaN, returns NaN if the result is negative zero, returns -0.0 q atan2(double a, double b) converts rectangular co-ordinates to polar co-ordinates q has two additional methods, new in JDK 1.2, to convert between radians and degrees r double toRadians(double angdeg) r double toDegrees(double angdeg) Math.sin(90): Math.cos(90): Math.tan(90): Math.asin(-0): Math.acos(-0): Math.atan(90): Math.toRadians(90) Math.toDegrees(Math.PI/2): 0.8939966636005579 -0.4480736161291701 -1.995200412208242 0.0 1.5707963267948966 1.5596856728972892 1.5707963267948966 90.0
Logarithms
q
q q q q
two functions to handle logs r double log(double a) r double exp(double a) log() returns the natural logarithm of the argument if the argument is less than zero, returns NaN if the argument is positive infinity, returns positive infinity if the argument is -0.0 or 0.0, returns negative infinity
Math.log(10): 2.302585092994046 Math.log(-10): NaN Math.log(0.0): -Infinity q exp() returns e to the power of the argument q if the argument is NaN, returns NaN q if the argument is positive infinity, returns positive infinity q if the argument is negative infinity, returns positive zero Math.exp(5): Math.exp(Float.NaN): Math.exp(Float.POSITIVE_INFINITY): Math.exp(Float.NEGATIVE_INFINITY): 148.4131591025766 NaN Infinity 0.0
Example Code
q
TestMath.java Wrapper Classes Math Class String Immutability String Class StringBuffer Class
Main Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
String objects are read-only or immutable ie the contents of a String object never change
String str = "Hello"; str = "Goodbye"; q in the above example, the second assignment of "Goodbye" to String, what actually happens is that a new string "Goodbye" is created and the object reference of the new string is stored in the variable str q operations that seem to modify a String object actually create new read-only String objects; leaving the original object unchanged q the StringBuffer class provides mutable or flexible string handling
Also see
String literals
Main Classes
Wrapper Classes
Math Class
String Immutability
String Class
StringBuffer Class
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
String literals are enclosed in double quotes "This is a string literal." A string constant expression occurs when two or more string literals are concatenated "This is " + "a string " + "constant expression." Character escape codes can be used in String literals "A line with a carriage return \r" !!! Warning !!!
You cannot use the character literals \u000a (newline) or \u000d (carriage return) in String literals as they will be interpreted as LineTerminators, not as input characters (JLS 3.10.5) "A line with unicode carriage return character \u000d"
q
If you use octal values in Strings to represent characters be sure to use a zero prefix (JPL pg33) Note: the zero prefix is not required for octal values in char literals "\0116" "\116" octal value equivalent to escape char \t followed by 6 "\t6" interpreted as letter N
Each String literal is a reference to an object of class String. String literals or strings that are the values of constant expressions, are interned so as to share unique instances.
the JLS gives example code using literals in the following classes: r class test r class Other (in the same java file as class test) r class other.Other (in a different package)
String variables initialized as: String hello = "Hello" String lo = "lo" (1) (2) (3) (4) (5) (6)
q
hello == "Hello" Other.hello == hello other.Other.hello == hello hello == ("Hel"+"lo") hello == ("Hel"+lo).intern() hello == ("Hel" + lo)
literal strings will represent the same reference if they are created 1. in the same class and in the same package 2. in different classes within the same package 3. in different classes in different packages 4. using constant expressions computed at compile time 5. by explicitly using the intern() method and the resulting string is already in the string pool literal strings will represent different references if they are newly created at runtime (Line 6) Summary
if String objects having the same data are created using a constant expression, a string literal, a reference to an existing string, or by explicitly using the intern() method, their references will be the same if String objects having the same data are created explicitly with the new operator or their values are computed at runtime, their references will be different str1 str2 str3 str4 str5 str6 str7 str8 = = = = = = = = "Lions and Tigers and Bears!"; "Lions and Tigers and Bears!"; str2; new String("Lions and Tigers and Bears!"); " Oh my!"; "Lions and Tigers and Bears! Oh my!"; str1 + str5; (str1 +" Oh my!").intern();
Comparison output: str1 == str2 -> true str1 == str3 -> true str1 == str4 -> false str2 == str3 -> true str2 == str4 -> false str3 == str4 -> false str6 == str7 -> false str6 == str8 -> true
// // // // // // // //
the str2 literal existed ("interned") hold the same reference str4 explicitly created hold the same reference str4 explicitly created str4 explicitly created str7 computed at runtime explicit use of intern() at runtime
JSK 1.3 for the java.lang.String class states: "Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared." In other words, because the compiler knows the strings original value cannot be changed once it's created it can safely use existing data and avoid cluttering up memory with duplicates.
Example code
q
TestStringLiteral.java
Traps
q
using == operator to compare contents of two string reference variables pointing to different String objects Package main() # Literals Import Identifiers char Literal Class Keywords Interface Defaults Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
Package declaration
q q q
if used, it must be the first non-comment statement in the source code file you can not declare more than one syntax: package packageName;
Import declarations
q q q
if used, must be the first non-comment statement directly following the package declaration. you can use as many import statements as you want if no package statement appears in the source code file, the import statement must be the first non-comment statement in the file
A top-level class or interface is defined as any class or interface whose declaration is not contained within the body of any other class or interface declaration. (JLS 8 and 9). you can declare multiple classes and interfaces within a file with the following caveats:
r
The Sun SDK allows one and only one public class or interface within a source code file. The filename must exactly match the name of the public class or interface declared in the file and have the .java extension
Non-public classes may have main() methods. If they have no access modifier (package access) they may still be run from the command-line using the classname.
Example Code
q
TestPkgImport.java
Tips
q q
an empty source file will compile without error if a .java file does not contain a public class or interface it can have any name
Traps
q q q
code with package or import declarations given in wrong order more than one package declaration file with more than one public class or interface declaration
filename.java does not match public class name as declared within the file Package main() # Literals Import Identifiers char Literal Class Keywords Interface Defaults Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About
q q
q q q q
The fact that they share a common subpackage, acme, has no meaning in terms of a types scope.
Feedback
q q
if no package declaration is found, the class or interface is made part of an unnamed package every implementation of Java must provide for at least one unnamed package most systems allow for one unnamed package per directory Package main() # Literals Import Identifiers char Literal Class Keywords Interface Defaults Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes
q q
q q
Case Studies
q
java.awt.Button myButton = new java.awt.Button(); imported types are available to all classes and interfaces within the same compilation unit (JLS 7.5) it is legal to import a single-type and a package having the same names (JLS 7.5.4) i.e.
// no compile error
Also see
q
Tips
a single-type import will take precedence over an import-on-demand import-on-demand types do not increase the size of the compiled code ie only the types actually used are added to the code I've read that while import-on-demand adds no overhead to the compiled code, they can slow down the speed of the compile; however, Peter van der Linden, in Just Java 2, 4th Edition says it ain't so and my guess is he knows ... he's a kernel programmer for Sun
Traps
q q q
single-type imports for two classes in different packages but with the same simple name single-type import with the same simple name as a class defined in the source file attempting to import a package vs a type ie import java.util vs import java.util.*
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About
Modifiers
public protected private abstract static final strictfp if two or more modifiers are used in a declaration it is customary, but not required, to show them in the order given (JLS 8.1.1) no modifiers are allowed in Anonymous class declarations (JJ pg 147) A class may not be both final and abstract as an abstract class implies extension package access (no access modifier declared) is also referred to as friendly access a compile error occurs if the same modifier appears more than once in a declaration (JLS 8.1.1)
q q q q
consists of the extends keyword followed by the name of the class being extended the extended class is referred to as the parent or superclass multiple extends are illegal ie a class may have only one superclass if no extends clause is used, the class automatically inherits from the java.lang.Object class a compile error occurs if a final class appears in the extends clause (JLS 8.1.1.2) an Anonymous class cannot have an extends clause (JPL pg74)
identifies interfaces implemented by the class consists of the implements keyword followed by a comma seperated list of the names of the interfaces to be implemented class X implements interfaceA, interfaceB, ... { } a class must provide a method implementation (execution code) for every method declared in or inherited by the interface if an interface is not provided in the implements clause, the class does not implement the interface even if it provides an implementation for every method declared in the interface
Feedback
q
the class body declares members (field variables and methods), constructors and initializers class members may also be inner classes or interfaces
Traps
q q
class attempting to extend more than one other class class declared both final and abstract
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
top-level interfaces may only be declared public private interface A {} protected interface B{} // compile error // compile error
inner interfaces may be declared private and protected BUT only if they are defined in a class public interface A { private interface B {} protected interface C {} } public class A { private interface B {} protected interface C {}
// compiles OK // compile OK
} a compile error occurs if the same modifier appears more than once in an interface declaration (JLS 9.1.1) every interface is implicitly abstract; the modifier is obsolete and should not be used in new programs (JLS 9.1.1.1)
extendsClause
q
consists of the extends keyword followed by a comma separated list of the interfaces being extended. Note
Classes are based on single-inheritance, they can only extend one class. Interfaces are allowed multiple-inheritance, they can extend more than one interface. interface InterfaceA extends interfaceX, interfaceY, ... {}
Interface body
q
q q
q q
an interface body may contain constant declarations, abstract method declarations, inner classes and inner interfaces fields in an interface are implicitly static and final ie they MUST be constants (JLS9.3) methods in an interface are implicitly abstract and public; they CANNOT be static (JLS9.4) methods cannot be declared strictfp, native or synchronized (JLS9.4) member classes declared in an interface are implicitly public and static (JLS9.5)
Also see
q q
Sun Tutorial: Interfaces and packages Tech Tip: Abstract classes vs interfaces
Code Examples
q q
TestInterfaceModifiers.java TestInterfaceInClass.java
Traps
q q
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Also see
Sun Tech Tip: Default Constructors
Tips
q
Traps
q
subclass with default constructor when the superclass does not have a no-args constructor or it's no-arg constructor has a throws clause
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Modifiers
q q q q q
legal access modifiers: public, protected, private or package (none declared) legal special modifiers: abstract, final, native, static, or synchronized a static method is referred to as a class method a non-static method is referred to as an instance method the access modifier of an overriding method must provide at least as much access as the method being overridden. (JLS 8.4.6.3) Original Method Access public protected package Overriding method must be public public or protected package, public or protected
legal return types: void, any primitive data type, an Object reference or Array type if void is used, the method may not use a return statement with an expression
return; return(x);
q
// legal // illegal
if a primitive data type is used, the method must return a value that is promotable to the declared type if an array type is used, the method must return a value of the same array type. For example, if the returnType is String[][] then the method must return a String[][] array a method can declare a return type without having a return statement in its body
parameterList
q
consists of a comma-separated list of parameter declarations myMethod(int a, long c, boolean flag){} a parameter may also be declared final
throwsClause
q
q q
consists of the keyword throws and a comma-separated list of the exceptions that may be thrown identifies all the checked exceptions that may be thrown but not caught by the method the throws clause must include exceptions that may be thrown by another method being invoked by the declared method it is not necessary to throw the predefined exceptions which are subclasses of the Error or RuntimeException classes (JLS 8.4.4) a method that overrides another method cannot be declared to throw more checked exceptions than the method being overidden.(JLS 8.4.4) class classA { void methodA() throws exX, exY{ // method body } }
class classB extends classA { void methodA() throws exX { // can throw less exceptions // method body } } class classC extends classA { void methodA() throws exX, exY, exZ { // method body } }
// illegal
Method Signature
q
A method signature is made up of the method name and parameter list (it does not include the return type) it is illegal for a class to declare two methods with the same signature
Method body
q
a static method cannot use this or super operators in it's body (static implies a class method unrelated to any specific instance) (JLS 8.4.3.2) a method declared native or abstract has a semi-colon (;) for a body. Do not use curly braces {}. (JLS 8.4.5) Example of native and abstract method declarations: public native void close() throws IOException; public abstract void open() throws IOException; versus non-native or abstract method declaration: public void close() throws IOException { // Method body } if a method is declared void then the body should not include a return statement that has an
expression (JLS 8.4.5) public void methodA() { return( 1 + 1 ); } public void methodA() { return; }
// illegal
// legal
Also see
Understanding that parameters are passed by value and not by reference
Code Examples
q
TestMethods.java
Tips
q q
any method can throw a Runtime or Error exception without declaring it in the throws clause methods having the same name and parameter types do not have the same signature unless the parameter types are listed in the same order
Traps
q q q q q q
an abstract method also declared private, native, final, synchronized, or strictfp an abstract method declared in a non-abstract class a native or abstract method with a method body method returning a type which is not convertible to the declared return type a void method returning a value a static method referencing this or super
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package
q q q q
q q q
References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
q q
main( String args[] ) main( String [] args ) main( String[] params ) main( String[] args ) // standard convention the args array is used to access command line arguments Example: java MyApp test this out the args array uses a zero based index therefore args[0] would return "test" in the above example an application can have more than one main() method as every class can have a main() method which main() is used by an application depends on the class started at runtime advantage is that each class can use it's own main() as a testing structure for the class main() is inherited and can be overridden if not declared final
SCJD Notes
q
Projects
q
q q
Code compiled with JDK 1.3 will work ok even it is declared private, protected or has no access modifier; however, for the purpose of the certification exam the correct method declaration is public static void main(String[] varname) (see discussion at JavaRanch)
Code Examples
q
TestMain.java
Tips
q q q
q q
main() can be declared final main() is inherited and can be overridden if not declared as final args[0] references first command line argument after the application name ( arrays in Java are zero-based) main() can be declared public static void ... or static public void ... the variable name does not have to be args; can be anything as long as the type is String[]
Traps
q
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package
q q q
The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Identifiers
q q q
an identifier is an unlimited-length sequence of Java letters and Java digits an identifier cannot have the same spelling as a Java keyword, boolean literal, or null literal valid identifiers begin with one of the following: r a Unicode letter r the underscore character ( _ ) r a dollar sign ( $ ) JLS 3.8 recommends that the dollar sign only be used for identifiers that are mechanically generated (ie within IDE's) JPL pg 5.4 recommends sticking to one language when writing identifiers as a number of characters look alike in various languages but have seperate Unicode values methods and variables can have the same names; method identifiers always take the form methodName() the parantheses allow Java to recognize the identifier as a method vs a variable and therefore distinguish between the two.
Naming Conventions
q q q q q
Package names - lowercase.for.all.components Class and Interface names - CaptializedWithInternalWordsCaptialized Method names - firstWordLowercaseButInternalWordsCapitalized() Variable names - firstWordLowercaseButInternalWordsCaptialized Constants - UPPER_CASE_WITH_UNDERSCORES
Tips
q
Traps
q q
local (automatic) variables declared with a modifier other than final identifier names beginning with a number or # sign
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
abstract, final, native, static, strictfp, synchronized, transient, volatile Control flow if, else, do, while, switch, case, default, for, break, continue OOP specific class, extends, implements, import, instanceof, interface, new, package, super, this Exception handling catch, finally, try, throw, throws Method specific return, void Unused * const, goto
* Note
q q
const and goto are not used in Java however they are reserved as keywords. true and false are Boolean Literals; null is a null Literal. They cannot be used as identifiers.
Tips
q
Java keywords are always lowercase; you can immeadiately eliminate any capitalized words appearing in a question listing possible keywords
Traps
q q
main listed as a possible keyword capitalized words listed as possible keywords; particularly wrapper classes Integer, Boolean, etc C/C++ keywords listed as possible Java keywords
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References
Automatic Initialization
q q q
Field variables (class members) are automatically initialized to default values Local variables (method or constructor variables) are not automatically initialized Arrays, whether field or local variables, are automatically initialized to the default values of their declared type
class CheckInit {
Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
}
// field variable static int i; // field array reference variable static String[] s = new String[10]; static void myMethod(){ int j; // local variable int[] a = new int[5]; // local variable array // causes compile error if not explicitly initialized j = 10; System.out.println(" Local variable: " + j); System.out.println(" Local array ref: " + a[3]); } public static void main(String[] args) { System.out.println("Field variable i: " + i); System.out.println(" Field array ref: " + s[2]); myMethod(); }
Output of CheckInit: Field variable i: Field array ref: Local variable: Local array ref: 0 null 10 0 // // // // default value of int default value for String[] explicit value default value of int[]
Declared with the Created when the class or interface is static keyword within a prepared. class or interface Automatically initialized to the default value of its type Duration: as long as the class is loaded Instance (Field) Declared within a class Created when a new instance is without the keyword created static Automatically initialized to the default value of its type Duration: for the life of the instance object Array components unnamed variables intialized to the default value of the created when an array array type object is created not Duration: until the array is no longer when declared referenced Method parameters named argument values a new parameter variable is created passed to a method each time the method is invoked initialized with the corresponding argument value from the method call Duration: method execution Constructor parameters named argument values a new parameter variable is created passed to the each time a new instance is created or constructor the constructor is called initialized to the corresponding argument value Duration: construction execution a new exception-handling parameter Exception-handling parameter variables in a catch clause is created each time an exception is caught by a catch clause initialized with the actual object associated with the exception Duration: catch clause execution Local variables declared by local a new local variable is created variable declarations whenever flow of control enters a new block or for statement initialized to whatever value is explicitly set within the block or for statement Duration: execution of the block or for statement
Class (Field)
Tips
q q
only field variables are automatically initialized to their types default value; local variables must be explicitly initialized arrays are initialized to the default value of their type when they are created, not declared, even if they are local variables
Traps
q
Source Methods
Package main()
Import Identifiers
Class Keywords
Interface Defaults
Constructors Arrays
Primitives
# Literals
char Literal
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams
arrays are Java objects all Java arrays are technically one-dimensional. Two-dimensional arrays are arrays of arrays. declaring an array does not create an array object or allocate space in memory; it creates a variable with a reference to an array array variable declarations must indicate a dimension by using [] Examples of valid array declarations: (JJ pg84) String[]s; String []s; String [] s; String [ ] s; String[] s; String[ ] s; String s[]; String s []; String s [ ];
String[] s[]; String[][]s; String s [] [ ]; // extra white space ignored declaring the size of the array with the following notation is illegal String[5] s; // illegal declaration the standard convention for declaring arrays is: String[] s; String[][] s; // one-dimensional array // two-dimensional array
Initializing arrays
q q
About Feedback
q q
all arrays are zero-based arrays must be indexed by int values or byte, short or char values (as these can be promoted to int) (JLS 10.4) using a long index value to access an array causes a compile error attempting to access an array with an index less than 0 or greater than the length of the array causes an ArrayIndexOutOfBoundsException to be thrown at runtime (JLS 10.4) since arrays are Objects they can be initialized using the new operator when created, arrays are automatically initialized with the default value of their type String[] s = new String[100]; // default values: null boolean[] b = new boolean[4]; // default values: false int[] i = new int[10][10]; // default values: 0 array references declared as members are initialized to null BUT array references declared in methods are not initialized {
class TestArray
int[] arr;
public static void main(String[] args) { int[] arr1; // reference variable 'arr1' not initialized // compiles ok System.out.println("arr:" + new TestArray().arr); // compile error System.out.println("arr1: " + arr1); } }
q
as arrays are allocated at runtime, you can use a variable to set their dimension int arrSize = 100; String[] myArray = new String[arrSize]; you can use curly braces {} as part of an array declaration to initialize the array String[] oneDimArray = { "abc","def","xyz" }; Note
Curly braces {} can only be used in array declaration statements. String[] s; // illegal initialization s = { "abc", "def", "hij"); int[] arr = new int[] {1,2,3}; // legal
you can assign an array a null value but you can't create an empty array by using a blank index int[] array = null; // illegal initialization int[] array = new int[]; // legal
the first dimension represents the rows, the second dimension, the columns curly braces {} may also be used to initialize two dimensional arrays. Again they are only valid in array declaration statements. int[][] twoDimArray = { {1,2,3}, {4,5,6}, {7,8,9} }; you can initialize the row dimension without initializing the columns but not vice versa int[][] myArray = new int[5][]; // illegal int[][] myArray = new int[][5]; the length of the columns can vary
class TestTwoDimArrays { // initialize # of rows static int [][] myArray = new int[3][]; public static void main(String[] args) { myArray[0] = new int[3]; myArray[1] = new int[4]; myArray[2] = new int[5]; for(int i=0; i<3; i++) fillArray(i, i+3); System.out.println(); } // end main() private static void fillArray(int row, int col) { // initialize # of cols // in each row
Also see
Sun Tech Tip: Manipulating Java Arrays
Code Examples
q
TestTwoDimArrays.java
Tips
q q
array index operator [] has highest level of precedence integer variables can be used as array dimension values
Traps
q q
q q q
incorrect array declaration statements, particularly: arrayType [#] varName; incorrect array initialization statements, particularly: arrayType[] varName = new arrayType[2]; varName = { value, value, value }; negative values for array index long value for array index array declaration used as an array creation statement
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
NEGATIVE_INFINITY signed 32-bit Can also have the value to floating-point NaN (Not a number) POSITIVE_INFINITY NEGATIVE_INFINITY signed 64-bit Can also have the value double to floating-point NaN (Not a number) POSITIVE_INFINITY float
q
0.0d
q q q
arithmetic with floating-point numbers will never throw an exception; instead one of the constant values: NEGATIVE_INFINITY, POSITIVE_INFINITY, or NaN are returned (BB pg 123) Variables declared as primitive types are not object references. They are placeholders for storing primitive values (JJ pg29) by default integer values are of type int and floating-point values are of type double float values are single-precision double values are double-precision
Wrapper classes
q
all the primitive types have corresponding wrapper classes which allow you to create objects of type Integer, Boolean, Float, etc. the wrapper classes have the same names as the primitive types except they begin with a Captial. !!! Warning - do NOT mix up the Types !!! boolean b;
IS NOT THE SAME AS Boolean b; You can say: boolean b = true; You CANNOT say: Boolean b = true; -> Boolean is a class, must use Boolean b = new Boolean(true);
Also see
Differentiate between reference and primitive types
Traps
q
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links
Integer literals
q
Integer constants are strings of octal, decimal, or hexidecimal digits decimal base 10 10 octal base 8 010 (8) hex base 16 0xA (16) Integer constants are long if they end in l or L
32l or 32L // capital L recommended use if an int literal is assigned to a short or a byte and it's value is within legal range, the literal is assumed to be a short or a byte. byte b = 5; // assumed to be a byte short s = 32500; // assumed to be a short short sh = 50000; // illegal In all other cases you must explicitly cast when assigning an int to a short or byte. (JPL pg 108) int i = 5; byte b; b = i; b = (byte)i; // declared and initialized int // declared byte // causes compile error // compiles
floating-point numbers are expressed as decimal numbers with an optional decimal point Examples of valid floating-point numbers: 0.10 1. .0001 1.8e1 // 'e' = exponential at least one digit must be present floating-point constants are double values unless they are suffixed with an f or F if a d or D suffix is used they are double values 10.5 // assumed double value 10.5F // float value a double constant cannot be assigned to a float variable even if the double is within the float value range; however, a double can be cast as a float double d = 3.213; float f; // double constant
About Feedback
q q
f = d; f = (float)d;
Traps
q q
assigning a non-integer literal to a byte, short or character assigning a double literal to a float
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package
the char type represents 16-bit Unicode characters Unicode is a superset of the ASCII character set which allows non-English language characters any Unicode character can be written as a literal using the Escape character (backslash \) and it's hexadecimal representation '\udddd' // where 'dddd' = hex digit (0 - F) single characters are represented within single quotes 'a' // char literal '9' // char literal there are three exceptions that require the use of the Escape character single quote ' \' ' displays as ' double quote ' \" ' displays as " backslash ' \\ ' displays as \ there are certain special characters which can be represented by escape sequences Unicode Char \u000A \u0009 \u0008 \u000D \u000C Definition newline tab backspace return form feed octal value \n \t \b \r \f \ddd
The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
Esc Char
Octal character constants can have three digits or less (\000 through \377) !!! Warning !!!
The compiler translates Unicode characters at the beginning of the compile cycle. Using the Unicode escape characters \u000A for newline and \u000D for return in a String or comment produces a compile-error as they are interpreted, literally, as 'end-of-line'. Always use the special characters '\n' or '\r'
Traps
q
String literal "c" assigned to char type Package main() # Literals Import Identifiers char Literal Class Keywords Interface Defaults Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
new in JDK 1.1 class literals are created by appending .class to the name of a primitive or reference type System.out.println(int.class); // output: int System.out.println(System.class); // output: java.lang.System you cannot use a variable with .class int i = 5; String s = "Hello"; System.out.println(i.class); System.out.println(s.class); // compile error // compile error
Also see
Sun Tech Tip: Using Class Literals
Class Keywords
Interface Defaults
Constructors Arrays
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
q q q q
Strings can be created implicitly by: 1. using a quoted string ie "Hello", or, 2. by using + or += on two String objects to create a new one strings can be created explicitly by using the new operator new String() creates an empty string new String(String value) creates a new string that is a copy of the string object value two basic String methods are r public int length() r public char charAt(int index). Index values range from 0 to length()-1 any String method requiring an index will throw an IndexOutOfBoundsException if 0 > index > length()-1 there are also a number of indexOf() methods which allow you to find the first and last position of a character or substring within a string indexOf(char ch) // first position of 'ch' indexOf(String str) // first position of 'str' lastIndexOf(char ch) // last position of 'ch' lastIndexOf(String str) // last position of 'str' each of the above methods also have overloads that allow a second int start argument which specifies the character position other than 0 from which to begin the search all the methods return -1 if the character or string is not found
Comparison
q q
SCJD Notes
q
Projects
q
characters in strings are compared numerically by their Unicode values equals() method returns true if both string objects are of the same length and have the same sequence of Unicode characters equalsIgnoreCase() can be used to compare strings, ignoring wether a character is lowercase or uppercase compareTo returns an int that is <, =, or > than 0 if one string, based on it's Unicode characters, is less-than, equal to or greater-than another string regions of strings can also be compared
Favourite Links About Feedback public boolean regionMatches(int start, String other, int ostart, int len) public boolean regionMatches(boolean ignoreCase, int start, String other, int ostart, int len) q an area of each string is compared for the number of characters specified by len q simple tests for the beginning and ending of strings can be done using public boolean startsWith(String prefix, int toOffset) public boolean startsWith(String prefix) public boolean endsWith(String suffix) Note
These methods return true if a comparison is done with an empty string "String".endsWith(""); "String".startsWith(""); // true // true
two utility methods hashCode() and intern() are available hashCode() returns the same hash value for any two strings having the same contents intern() returns a String that has the same contents as the one it is invoked on AND any two strings having the same content return the same String object allowing comparisons to be done using String references vs string contents using intern() for comparison purposes is equivalent to comparing contents but is much faster
Related strings
q
several methods return new strings that are like the original but with the specified modifications public public public public public public public String String String String String String String concat(String str) replace(char oldChar, char newChar) substring(int beginIndex) substring(int beginIndex, int endIndex) toLowerCase() toUpperCase() trim()
Because all of the above methods return new strings; comparisons such as String s = "String"; // in the pool
if(" String ".trim() == s) System.out.println("Equal"); else System.out.println("Not Equal"); OR if(" String ".trim() == "String") System.out.println("Equal"); else System.out.println("Not Equal"); q produce NOT EQUAL. The string pool is NOT checked for a matching string and as a result the string object references are always different or, not equal (refer to String Literals intern() for more info on the string pool)
q
HOWEVER, if the invoked method does not produce a different string ie the resulting string, after the method invocation, is the same as the original, THEN the original object reference is returned by the method and the results are EQUAL if("String".substring(0,6) == "String") System.out.println("Equal"); else System.out.println("Not Equal"); if("String".replace('t','t') == "String") System.out.println("Equal"); else
System.out.println("Not Equal");
there are a number of constructors and methods that will convert a character array to a String and vice versa
public String(char[] value) public String(char[] value, int offset, int count) public static String copyValueOf(char[] data) public static String copyValueOf(char[] data, int offset, int count) public void getChars(int srcBegin, intSrcEnd, char[] dst, int dstBegin) public char[] toCharArray() q there are also a number of constructors and methods that convert 8-bit character arrays to and from 16-bit String objects public String(byte bytes[], int offset, int length) public String(byte bytes[]) public byte[] getBytes() public String(byte bytes[], int offset, int length, String enc) public String(byte, bytes[], String enc) public byte[] getBytes(String enc) q where enc is the standard name for the character language encoding ie UTF8 or ISO-Latin-1
Also see
Sun Tech Tip: Interning Strings
Example Code
q q q q q
TestStringOperations.java TestStringCompares.java TestStringModifications.java TestStringMethods.java TestParseLine.java Wrapper Classes Math Class String Immutability String Class StringBuffer Class
Main Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package
used to modify or manipulate the contents of a string StringBuffer objects are NOT implicitly created; the following will not compile
StringBuffer sb = "Hello"; StringBuffer sb = { "Hello" }; q you must use the new operator to invoke one of three constructors public StringBuffer() public StringBuffer(int length) public StringBuffer(String str) every StringBuffer has an initial capacity (length) of 16 characters if the internal buffer overflows it is automatically made larger however it is more efficient to specify the capacity only once, there are three methods available to manage capacity
q q
The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback String s = ""; s = s + "a" + "b"; q is treated, by the compiler, as something similar to String s = ""; s = new StringBuffer("").append("a").append("b").toString(); q the StringBuffer class does not inherit from String q to use a StringBuffer object as a parameter to a method requiring a String, use the StringBuffer toString() method. For example, to print the result of a StringBuffer object manipulation StringBuffer sb = new StringBuffer("Hello"); sb.append(" World"); System.out.println(sb.toString() ); q StringBuffer has overloaded append() and insert() methods to convert any type, including Object and character arrays, to a String; both methods return the original StringBuffer object q the reverse() method returns the original StringBuffer object with the characters in reverse order q you can access and modify specific characters or a range of characters public char charAt(int index) public void setCharAt(int index, char ch) public StringBuffer(int capacity) public synchronized void ensureCapacity(int minimum) public int capacity() public int length() public void setLength(int newLength) q the String methods which return a new object ie concat(), replace(), etc actually use StringBuffer behind the scenes to make the modifications and then returns the final String using toString(). For example, the following code (JJ pg 208)
public StringBuffer replace(int start, int end, String str) public StringBuffer deleteCharAt(int index) public StringBuffer delete(int start, int end) Note: the subString() method returns a String public String subString(int start) public String subString(int start, int end) there are no methods to remove part of a buffer; you need to create a character array and build a new buffer with the portion of the array you're interested in; this can be done using
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
Example Code
q
TestStringBuffer.java Wrapper Classes Math Class String Immutability String Class StringBuffer Class
Main Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
Threads - Overview
q q q q q q
q q
q q
q q
q q q
on an operating system a running program is known as a process a single process can have seperate runnable tasks called threads a thread is a single sequential flow of control within a process a thread is also referred to as a lightweight process with a single-processor CPU, only one thread is executing at any given time the CPU quickly switches between active threads giving the illusion that they are all executing at the same time (logical concurrency) on multi-processor systems several threads are actually executing at the same time (physical concurrency) multi-programming occurs when multiple programs or processes are executed multi-threading occurs when concurrency exists amoung threads running in a single process (also referred to as multi-tasking) Java provides support for multi-threading as a part of the language support centers on the: r java.lang.Thread class r java.lang.Runnable interface r java.lang.Object methods wait(), notify(), and notifyAll r synchronized keyword every Java program has at least one thread which is executed when main() is invoked all user-level threads are explicitly constructed and started from the main thread or by a thread originally started from main() when the last user thread completes any daemon threads are stopped and the application stops a thread's default daemon status is the same as that of thread creating it you can check the daemon status using isDaemon() you can set the daemon status using setDaemon(). You cannot change a thread's status after it has been started main() daemon status is false if you want all your threads to quit when main() completes you can set their status to daemon using setDaemon(true) there are two basic ways to create and run threads 1. by subclassing the Thread class 2. by implementing the Runnable interface
q q
Also see
q q q q q
Sun Tutorial on Threads IBM Redbook: Java Thin-Client Programming - Introduction to Threads SunTech Tip: Why Use Threads? Beware the daemons Exploring Java, Chapter 6, Threads
Example Code
q
Source code to check daemon status of main() Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the easiest way to create a thread is by subclassing java.lang.Thread class BasicThread extends Thread { char c; BasicThread(char c) { this.c = c; }
} to actually start the thread running you must invoke its start() method BasicThread bt = new BasicThread('!'); BasicThread bt1 = new BasicThread('*'); bt.start(); bt1.start(); the start() method allocates system resources required for a thread, schedules the thread to run and invokes the run() method the above code will execute but nothing will happen if you want your thread to do something you need to override the run() method the run() method is actually defined in the Runnable interface which the class Thread implements public void run() { for(int i=0; i<100; i++) { System.out.print(c); } } if the above code is added and the threads started you see something like:
q q q
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!* !*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!**** *********************************************** q the output is intermingled because the threads are running concurrently and are interleaved q you can alter thread processing with program control mechanisms q one way is to use the sleep() method which is defined in the Thread class q the sleep() method stops the execution of a thread for a given number of milliseconds q it also throws an InterruptedException so you need to wrap it in a try-catch block q adding sleep() to the run method can alter the threads execution Note
q
the sleep() method uses a timed wait() but does not tie up the current object's lock (for information on locks see Synchronization)
New run() method: public void run() { for(int i=0; i<100; i++) {
http://www.janeg.ca/scjp/threads/threadClass.html (1 of 3) [15/03/2004 8:47:47 AM]
System.out.print(c); try{ sleep((int)(Math.random() * 10)); } catch( InterruptedException e ) { System.out.println("Interrupted"); } } } Example output: *!*!!*!*!**!!!*!!*!***!*!!***!*!*!*!*!!!!***!!*!* !!*!**!*!!*!**!*!**!!*!**!!*!!*!*!**!*!***!!!!*!* !!*!**!*!*!*!*!*!*!*!!*!*!*!!!*!*!!!*!*!!*!*!*!*! !*!**!*!*!**!**!!*!***!!!****!*!!****!*!**!!**!!! **** q you can give a thread a name by creating it with a String argument Thread t = new Thread("Thread1"); if a thread is created without a name, one is automatically generated in the form Thread-n, where n is an integer the following is output from TwoThreadsTest which creates two SimpleThread's and displays their automatically generated names using the getName() method of the Thread class. 0 Thread-0 0 Thread-1 1 Thread-0 1 Thread-1 2 Thread-0 2 Thread-1 3 Thread-0 3 Thread-1 4 Thread-1 4 Thread-0 DONE! Thread-0 DONE! Thread-1
ThreadGroup
q q q
you can group threads using the ThreadGroup class this allows multiple threads to be handled as one unit ie for setting priority, destroying, etc threads in the same group can access information about other threads in the group but not about the parent thread or threads in other groups a ThreadGroup can have both daemon and nondaemon threads
Example Code
q q q q q
BasicThread.java Bouncing Ball Applet: UpDown.java PrimeNumbers Applet: Ex1.java Java Is Hot: Thread1.java Traffic Simulation: Traffic.java and SetOfLights.java
Scheduling wait()
Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About
every instance of class Object and its subclass's has a lock primitive data type fields (Scalar fields) can only be locked via their enclosing class fields cannot be marked as synchronized however they can be declared volatile which orders the way they can be used or you can write synchronized accessor methods array objects can be synchronized BUT their elements cannot, nor can their elements be declared volatile Class instances are Objects and can be synchronized via static synchronized methods
Synchronized blocks
q
allow you to execute synchronized code that locks an object without requiring you to invoke a synchronized method synchronized( expr ) { // 'expr' must evaluate to an Object }
Synchronized methods
q
declaring a method as synchronized ie synchronized void f() is equivalent to void f() { synchronized(this) { // body of method } } the synchronized keyword is NOT considered part of a method's signature. IT IS NOT AUTOMATICALLY INHERITED when subclasses override superclass methods methods in Interfaces CANNOT be declared synchronized constructors CANNOT be declared synchronized however they can contain synchronized blocks synchronized methods in subclasses use the same locks as their superclasses synchronization of an Inner Class is independent on it's outer class a non-static inner class method can lock it's containing class by using a synchronized block synchronized(OuterClass.this) { // body }
q q
q q q
Locking
Feedback
q q
q q q
locking follows a built-in acquire-release protocol controlled by the synchronized keyword a lock is acquired on entry to a synchronized method or block and released on exit, even if the exit is the result of an exception you cannot forget to release a lock locks operate on a per thread basis, not on a per-invocation basis Java uses re-entrant locks ie a thread cannot lock on itself
class Reentrant {
public synchronized void a() b(); System.out.println("here } public synchronized void b() System.out.println("here } }
q
q q
in the above code, the synchronized method a(), when executed, obtains a lock on it's own object. It then calls synchronized method b() which also needs to acquire a lock on it's own object if Java did not allow a thread to reacquire it's own lock method b() would be unable to proceed until method a() completed and released the lock; and method a() would be unable to complete until method b() completed. Result: deadlock as Java does allow reentrant locks, the code compiles and runs without a problem the locking protocol is only followed for synchronized methods, it DOES NOT prevent unsynchronized methods from accessing the object once a thread releases a lock, another thread may acquire it BUT there is no guarantee as to WHICH thread will acquire the lock next
locking an object does not automatically protect access to static fields protecting static fields requires a synchronized static block or method static synchronized statements obtain a lock on the Class vs an instance of the class a synchronized instance method can obtain a lock on the class synchronized(ClassName.class) { // body } the static lock on a class is not related to any other class including it's superclasses a lock on a static method has no effect on any instances of that class (JPL pg 185) you cannot effectively protect static fields in a superclass by adding a new static synchronized method in a subclass; an explicit block synchronization is the preferred way nor should you use synchronized(getClass()); this locks the actual Class which might be different from the class in which the static fields are declared
q q q
Example Code
q
Source code for reentrant example Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the Runnable interface declares a single method: run() you can execute a Runnable object in its own thread by passing it to a Thread constructor here's the BasicThread class modified to use the Runnable interface
class RunBasicThread implements Runnable{ char c; RunBasicThread(char c) { this.c = c; } // override run() method in interface public void run() { for(int i=0; i<100; i++) { System.out.print(c); try{ Thread.sleep((int)(Math.random() * 10)); } catch( InterruptedException e ) { System.out.println("Interrupted Exception caught"); } } } public static void main(String[] args) { RunBasicThread bt = new RunBasicThread('!'); RunBasicThread bt1 = new RunBasicThread('*'); // start RunBasicThread objects as threads new Thread(bt).start(); new Thread(bt1).start(); } }
q q
the most significant code revisions are shown in red note that you can still make use of the methods declared in the Thread class but you now have to use a qualified name ie Thread.sleep() and you have to pass your runnable object to the thread when it is created ie new Thread(bt).start() the Clock applet is an example of an Applet (based on the Sun Thread tutorial) using the Runnable interface:
Whenever your class has to extend another class, use Runnable. This is particularly true when using Applets
Example Code
q q
PrimeNumbers applet: Ex1_a Java Is Hot: Thread2 Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
each thread has a life-cycle all it's own during it's life-cycle it can exist in a number of states r New r Runnable r Not Runnable r Dead Note
These states are those used in the Sun Java Thread tutorial. Other references may use 'ready', 'waiting' or other terminology to describe the Runnable and Non-runnable states.
New a new thread is an empty Thread object; no system resources have been allocated as yet. Calling any thread method other than start() causes an IllegalThreadStateException Runnable a thread enters the Runnable state after the start() method is invoked. The start() method allocates system resources, schedules the thread, and calls the threads's run() method. When the thread actually runs is determined by the scheduler Not Runnable a thread is not runnable when r it's sleep() method is invoked r it's wait() method is invoked r it is blocked on I/O ie waiting on system resources to perform an input or output operation the thread becomes runnable again when a specific condition has been met based on the action which put it in the not runnable state r when the number of milliseconds called in sleep() have elapsed r when the condition it is waiting on has changed and it receives a notify() or notifyAll() message r when the required system resources are made available and the I/O completes Dead a thread enters the dead state when it's run() method completes. an interrupt does not kill a thread the destroy() method kills a thread dead but does not release any of it's object locks
a thread can bounce between runnable and not runnable states as a result of either
Scheduling wait()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps
execution of multiple threads in some order on a single CPU system is called scheduling Java uses fixed-priority scheduling algorithms to decide which thread to execute the thread with the highest priority runs first if another thread with a higher priority is started, Java makes the lower priority thread wait if more than one thread exists with the same priority, Java quickly switches between them in round-robin fashion BUT only if the operating system uses time-slicing (see below)
Priorities
q q
q q q q q
it's possible to assign a thread priority the Thread class contains three integer priority constants 1. [ 1] MIN_PRIORITY 2. [ 5] NORM_PRIORITY 3. [10] MAX_PRIORITY the default thread priority is NORM_PRIORITY when a thread is created, it takes the priority of the thread which created it you can check a threads priority using getPriority() you can change a threads priority using setPriority() if you change the priority on an executing thread to a lesser priority, it may stop executing as there may be another thread with a higher-priority (BB pg 259)
SCJD Notes
q
q q
the above act as a guide to scheduling however the actual implementation depends on the Operating System most operating systems use one of two scheduling methods 1. Preemptive scheduling 2. Time slicing In preemptive scheduling the highest priority thread continues to run until it dies, waits, or is preempted by a thread of higher priority In time slicing a thread runs for a specific time and then enters the runnable state; at which point the scheduler decides wether to return to the thread or schedule a different thread (method used by Win95/NT) DO NOT rely on thread priority as a guarantee that the highest priority thread will always be running; the operating system has the final say priorities are used as guides to efficiency priority manipulations CANNOT be used as a substitute for locking (see synchronization)
following represent the general conventions for setting thread priorities based on the type of activity the thread is involved in Range ----10 7-9 Use ---------------------------Crisis management Interactive, event-driven
IO Background computation Run only if nothing else can Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
a thread normally ends when it's execution completes there are other methods of stopping it, some of which should not be used
interrupt()
q q q q q
interrupting a thread tells it that you want it to pay attention it does not force the thread to halt although it will wake up a sleeping thread isInterrupted checks to see if a thread is in an interrupted state the static method interrupted can be used to clear a thread's interrupted state if a thread is waiting or sleeping and the thread is interrupted, the methods wait() and sleep() will throw an InterruptedException
join()
q q
one thread can wait for another to complete using the join() method invoking join() guarantees that the method will not return until the threads run() method has completed join() will also take a milliseconds argument which will cause it to wait until the thread completes for the designated time period
destroy()
q
destroy() kills a thread dead without releasing any of it's locks which could leave other threads blocked forever it's use should be avoided
stop()
q q q q
you can force a thread to end by calling stop() which in turn throws the Error ThreadDeath you can also throw ThreadDeath yourself ThreadDeath SHOULD NOT BE CAUGHT! NOTE: stop() is a deprecated method and should not be used!!!
setDaemon(true)
q
if you want your thread to stop executing when main() completes, set it's daemon status to true using setDaemon(true)
yeild()
q
Java does not time-slice ie it will not preempt a currently executing thread to allow another thread of the same priority to run the operating system may use time-slicing but you should not rely on time-slicing when creating threads a well behaved thread will use the yield() method to voluntarily yield to the CPU, giving it a
q q q
chance to run another thread of the same priority. if no threads of the same priority are available, execution of the yielding thread continues. Note: lower priority threads are ignored. the yield() method only hints to the JVM that if there are other runnable threads the scheduler should run one in place of the current thread. The JVM may interpret this hint any way it likes ie how the yield is handled is dependent on the JVM implementation for the operating system
Also see
Sun Tech Tip: Handling Interrupted Exceptions Overview Execution Thread Mechanics Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
q q
the Thread class includes an isAlive() method which returns true if a thread has been started and not stopped a thread stops when its run() method finishes executing the isAlive() method returns false if the thread is new or dead there is no way to detect if a thread is not alive because it was never started or because it is dead there is also no way to detect if a live thread is Runnable or Not Runnable neither can a thread identify which thread started it
the thread does not have the highest priority and can't get CPU time Example: LowPriority the thread has been put to sleep via sleep() method Example: Sleeping there is more than one thread with the same priority and the JVM is switching between the threads Example: SamePriority the thread's wait() method has been invoked Example: Waiting the thread's yield() method has been invoked Example: Yielding the suspend() method has been invoked (this is a deprecated method and should no longer be used)
Scheduling wait()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
This information is not required for the Certification exam. I've included it because I found it useful in helping me to understand how thread locks or monitors actually worked. each program has an area of main memory where it stores it's classes, arrays and variables the main memory has a master copy of every variable and contains one lock for each object this main memory area is accessible by all the programs threads threads can only communicate thru the shared main memory each thread has a working memory where it keeps copies of the values of variables it uses or assigns to access a shared variable, a thread obtains a lock and flushes its working memory, guaranteeing the shared value will be loaded from main memory as a thread executes, it operates on its working copies when a synchronized block or method is entered, actions by the thread and main memory must occur in a specific order 1. the thread obtains a lock on the object and flushes its working copy of the object 2. main memory reads the objects value from it's master copy 1. the thread loads the value passed by the main memorys read operation 2. the thread uses it's working copy of the object, passing it to it's excuatable engine 3. the thread assigns the resulting value back to it's working copy 4. the thread stores the new value, passing it back to main memory 3. main memory writes the value passed by the threads store action back to the master copy 4. the thread releases it's lock on the object every read action by main memory must be followed by a load action in the thread every store action in the thread must be followed by a write action in main memory the read and write actions in main must be executed in the order they were performed in the thread every use action in a thread must be followed by an assign action however an assign does not necessarily have to be proceeded by a use all use and assign actions must occur in the order dictated by the threads executable code assign must follow a load before a store can occur or another load can occur every lock action by a thread MUST be paired with an unlock as Java allows re-entrant locks, a thread may obtain multiple locks which must be paired with matching unlocks only one thread at a time can hold a lock on an object a thread is not permitted to unlock a lock it doesn't own a thread can only release it's lock after it has performed a store
q q q q q
q q
q q q
q q q q
q q q
double and long variables are handled as two 32-bit variables if the variables are not declared volatile and if they are being used by two or more threads the
volatile
q
declaring a thread volatile prevents the compiler from optimizing and in-lining the code; forcing the thread to reread the value every time the variable is accessed
int value = 5; for(;;) { display.showValue(value); Thread.sleep(1000); // wait one second } q in the above example, value is assigned a literal, under normal conditions, if display.showValue() does not make any changes to value the compiler would in-line the code, assuming value will not be changed while the method is running q however, if you have other threads that can change value then you should declare it as volatile q this will stop the compiler from in-lining the code and force the value to be reread each time the loop iterates Overview Execution Thread Mechanics Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
threads often need to share a common resource ie a file, with one thread reading from the file while another thread writes to the file this is an example of a producer/consumer relationship
Race conditions
q
q q
race conditions occur when multiple, asynchronously executing threads access the same object returning unexpected (wrong) results they can be avoided by synchronizing the methods which access the shared resource the Sun Thread tutorial has an example which uses a Producer class, and a Consumer class which respectively write and read integers from a CubbyHole class. If the CubbyHole class is unsynchronized, as in the following code:
public class CubbyHole { private int contents; public int get() { return contents; } public synchronized void put(int value) { contents = value; } }
public class CubbyHole { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notifyAll(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); } }
q q
the keyword synchronized is added to the method declarations the Object methods wait() and notifyAll() are used to communicate between executing threads
An example using a synchronized statement on a common object Thread4 An example of synchronizing access to variables Account An example of a museum which uses Walkmen radios for tours: WalkmanHire uses Museum, Counter, and Visitors classes.
Also see
Sun Tech Tip: Using Synchronized Statements Acquire multiple locks in a fixed, global order to avoid deadlock Overview Execution Thread Mechanics Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References
q q q q
Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
the wait() method causes a thread to release the lock it is holding on an object; allowing another thread to run the wait() method is defined in the Object class wait() can only be invoked from within synchronized code it should always be wrapped in a try block as it throws IOExceptions there are actually three wait() methods 1. wait() 2. wait(long timeout) 3. wait(long timeout, int nanos) the timeout is measured in milliseconds nanos is measured in nanoseconds wait() can only invoked by the thread that own's the lock on the object when wait() is called, the thread becomes disabled for scheduling and lies dormant until one of four things occur: 1. another thread invokes the notify() method for this object and the scheduler arbitrarily chooses to run the thread 2. another thread invokes the notifyAll() method for this object 3. another thread interrupts this thread 4. the specified wait() time elapses when one of the above occurs, the thread becomes re-available to the Thread scheduler and competes for a lock on the object once it regains the lock on the object, everything resumes as if no suspension had occurred if the thread was interrupted by another thread, an InterruptedException is thrown BUT not until after the thread regains it's lock on the object
Throws
q
the wait() method throws three exceptions 1. IllegalArgumentException - if the timeout value passed is invalid 2. IllegalMonitorStateException - if the current thread does not own the object's lock 3. InterruptedException - if another thread interrupts the current thread. The interrupted status of the current thread is cleared
Scheduling wait()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
the notify() and notifyAll() methods are defined in the Object class they can only be used within synchronized code notify() wakes up a single thread which is waiting on the object's lock if there is more than one thread waiting, the choice is arbitrary ie there is no way to specify which waiting thread should be re-awakened notifyAll() wakes up ALL waiting threads; the scheduler decides which one will run if there are no waiting threads, the notifys are forgotten only notifications that occur after a thread has moved to wait state will effect it; earlier notifies are irrelevant
Scheduling wait()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps
q q q
just as every object has a lock it also has a wait set that is manipulated using wait(), notify(), notifyAll() and Thread.interrupt objects having locks and wait sets are referred to as monitors any object can act as a monitor each object's wait set is maintained internally by the JVM and holds threads blocked by wait until a corresponding notify is received or the waits are otherwise released the methods wait(), notify() and notifyAll() can only be invoked when the synchronized lock is held on their target
wait()
the following happens when wait() is invoked r if the current thread has been interrupted, the method exits immeadiately and throws an InterruptedException; otherwise, the thread is blocked r the JVM places the thread in the wait set associated with the target object r the lock for the target is released but all other locks held by the thread are retained. A full release occurs even if the lock is re-entrantly held due to the thread having nested synchronized calls r when the thread resumes (ie wait state ends) the lock status is fully restored
timed waits()
r r r
Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q
if a timed wait() has not been notified before it's time is up, it releases automatically there is no way to tell if a wait has returned due to notification or timeout the thread may resume at any arbitrary time after it has timed out based on thread contention, scheduling and timer granularities
notify()
the following happens when notify() is invoked q the JVM arbitrarily chooses a thread, if one exists, from the target's wait set q the thread must re-obtain it's synchronized lock on the target object. It will always be blocked at least until the thread calling notify() releases it's lock or if some other thread obtains the lock first q once the lock is obtained, the thread resumes from the point of it's wait
notifyAll()
works the same as notify() except all waiting threads are removed from the target wait set and allowed to compete for the lock only one thread can obtain the lock so they continue one at a time
Thread.interrupt
q
if a thread suspended in wait is invoked, the same notify mechanics apply except that after re-acquiring the lock, an InterruptedException is thrown if an interrupt and notify occur together there is NO guarantee as to which will take
precedence
Example Code
q
Using wait() and notify() to control access to a shared resource Thread5 Thread Class Synchronization Runnable Interface Locking Protocols Thread States synchronized keyword Scheduling wait() Ending a Thread notify(), notifyAll()
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Encapsulation
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Modularity
q
because the object encapsulates all it's variables and the methods needed to make it work, it is a self-contained entity that can be maintained independently of other objects
Maintainability
q
because the object hides it's implementation details behind a well-defined interface, the details can be changed without affecting other parts of the program
Example
class TestBook{ public static void main(String[] args) { Book b1 = new Book(); System.out.println(b1); // // b1.title = "Java Programming Language"; b1.author = "Ken Arnold and James Gosling"; // must use accessor methods b1.setTitle("The Java Programming Language: Second Edition"); b1.setAuthor("Ken Arnold and James Gosling"); // System.out.println(b1.title, b1.author); System.out.println(" Title: " + b1.getTitle() ); System.out.println("Author: " + b1.getAuthor() ); } }
q
In the example code, the instance variables title and author are private; they can only be accessed by their gettor and settor methods any attempt to directly set or get the variables produces a compile error
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Encapsulation
Example Code
q
TestBook.java isA/hasA Inner Classes Overloading Overriding Field Variables Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Polymorphism
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
polymorphism translates from Greek as many forms ( poly - many morph - forms) in OOP's it refers to the propensity of objects to react differently to the same method (VA pg 110) method overloading is the primary way polymorphism is implemented in Java
Overloading methods
q
overloaded methods: 1. appear in the same class or a subclass 2. have the same name but, 3. have different parameter lists, and, 4. can have different return types an example of an overloaded method is print() in the java.io.PrintStream class
public void print(boolean b) public void print(char c) public void print(char[] s) public void print(float f) public void print(double d) public void print(int i) public void print(long l) public void print(Object obj) public void print(String s) q the actual method called depends on the object being passed to the method q Java uses late-binding to support polymorphism; which means the decision as to which of the many methods should be used is deferred until runtime
Overriding methods
q q q
late-binding also supports overriding overriding allows a subclass to re-define a method it inherits from it's superclass overriding methods: 1. appear in subclasses 2. have the same name as a superclass method 3. have the same parameter list as a superclass method 4. have the same return type as as a superclass method 5. the access modifier for the overriding method may not be more restrictive than the access modifier of the superclass method s if the superclass method is public, the overriding method must be public s if the superclass method is protected, the overriding method may be protected or public s if the superclass method is package, the overriding method may be packagage, protected, or public s if the superclass methods is private, it is not inherited and overriding is not an issue
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Polymorphism
6. the throws clause of the overriding method may only include exceptions that can be thrown by the superclass method, including it's subclasses class LBException extends Exception {} class LBException1 extends LBException {} In superclass: public void testEx() throws LBException { throw new LBException(); } In subclass: public void testEx() throws LBException1 { throw new LBException1(); } overriding is allowed as LBException1 thrown in the subclass is itself a subclass of the exception LBException thrown in the superclass method
it is Java's use of late-binding which allows you to declare an object as one type at compile-time but executes based on the actual type at runtime
class LB_1 { public String retValue(String s) { return "In LB_1 with " + s; } } class LB_2 extends LB_1 { public String retValue(String s) { return "In LB_2 with " + s; } }
q q
if you create an LB_2 object and assign it to an LB_1 object reference, it will compile ok at runtime, if you invoke the retValue(String s) method on the LB_1 reference, the LB_2 retValue(String s) method is used, not the LB_1 method LB_2 lb2 = new LB_2(); LB_1 lb3 = lb2;
// compiles ok
Example Code
q
Encapsulation Polymorphism
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Polymorphism
Initialization
Top-level Classes
Inner Classes
Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - is A vs Has A
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
is a defines a direct relationship between a superclass and a subclass has a identifies a relationship in which one object contains another object (defined by field variables)
Examples
q
A circle is a shape that has a center point and a radius. (JJ pg 138) public class Circle extends Shape { // a circle is a shape Point center; // a circle has a point double radius; // a circle has a radius } Define a class hierarchy for the following classes (BB pg14): 1. An Employee class that maintains an employee number. 2. A Full-time employee class that maintains an employee number, hours worked per week and calculates it's own pay using a salary() method. 3. A Retired employee class that maintains an employee number, the number of years worked, and calculates it's own pay using a salary() method. public class Employee { long id; String status; } // an employee // has an id, and // a status
abstract class EmployeeStatus extends Employee { abstract double salary(); } // fulltime is a status class FullTime extends EmployeeStatus { double hrs; double salary(){ return hrs * 60.0; } } // retired is a status class Retired extends EmployeeStatus { int years; double salary() { return 0; } } Create classes for 2DShape, Circle, Square and Point. Points have an (x,y) location. Circles have an (x,y) location and a radius. Squares have an (x,y) location and a length. (BB pg17) class Point { int x; int y; // a point // has an x-location, and // a y-location
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - is A vs Has A
class Circle extends 2DShape { double radius; } class Square extends 2DShape { double length; } Encapsulation Polymorphism Initialization Top-level Classes isA/hasA Inner Classes
Overloading
Overriding
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Overloading Methods
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
overloaded methods can have the same name but must have different parameter lists parameter lists are considered different if the order of the arguments are different a subclass method can overload a superclass method
the following code shows the method test(int i, long j) in a Super class, and method test(long j, int i) in a Sub class
Super class: test(int i, long j); Sub class test(long j, int i); q this code will compile fine if any variables passed to the methods are easily recognizable as either an int or a long Sub sb = new Sub(); // second arg is defined as L(ong); no ambiguity sb.test(100, 3000L); Output: uses test(int i, long j) in Super class q however, if the compiler cannot differentiate between a long and an int a compiler error will occur Sub sb = new Sub(); // causes compile-error, 3000 can also be an int sb.test(100, 3000); Ouput: compile-error: reference to test() is ambiguous !!! Warning !!!
q
When analyzing code, watch for ambiguous references that can cause compile errors.
Overloading constructors
q
you can overload constructors within the same class class SuperCtor { SuperCtor(){} SuperCtor(int i) {} // compiles ok } you can't overload them in subclasses as they must have the same name as the class (ie they would have to have the superclass name and would therefore not be constructors in the subclass)
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Overloading Methods
// compile-error
Also see
q q
Example Code
q q
TestOverload.java TestOverloadCtor.java isA/hasA Inner Classes Overloading Overriding Field Variables Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Overriding Methods
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q
fields cannot be overridden but they can be hidden ie if you declare a field in a subclass with the same name as one in the superclass, the superclass field can only be accessed using super or the superclasses type a subclass can override methods in it's superclass and change it's implementation it must have the same return type, name, and parameter list and can only throw exceptions of the same class/subclass as those declared in the original method
class Super { void test() { System.out.println("In Super.test()"); } } class Sub extends Super { void test() { // overrides test() in Super System.out.println("In Sub.test()"); } } q cannot have weaker access rights than the original method In Sub class: // compile-error, original has package access private void test() {} protected void test() {} // compiles ok public void test() {} // compiles ok q you can have multiple overloaded methods in a class but only one overriding method In Sub class: void test() {} public void test() {}
// overrides test() in Super // compile-error: test() already declared // different access modifiers not part of // method signature for naming purposes void test(String str) {}// compiles ok, overloads test() q Only accessible non-static methods can be overridden q static methods can be hidden ie you can declare a static method in the subclass with the same signature as a static method in the superclass. The superclass method will not be accessible from a subclass reference q any class can override methods from its superclass to declare them abstract, turning a concrete method into an abstract one at that point in the type tree. Useful when a class's default implementation is invalid for part of the class hierarchy (JPL pg 77)
you cannot override a constructor in a superclass as they are not inherited you cannot override a constructor in the same class as they would both have the same signatures; get an 'already declared' compile-error if you're instantiating a Subclass object and if the Superclass constructor calls a method that is overridden in the Subclass, the Subclass method will called from the superclass
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Overriding Methods
constructor -- NOT the one in the superclass class Super { Super(){ System.out.println("In Super constructor"); test(); } void test() { System.out.println("In Super.test()"); } } class Sub extends Super { Sub() { System.out.println("In Sub constructor"); } void test() { // overrides test() in Super System.out.println("In Sub.test()"); } } Output In In In if Sub sb = new Sub() is invoked: Super Constructor Sub.test() Sub Constructor
Also see
q
Polymorphism
Example Code
q
TestOverride.java isA/hasA Inner Classes Overloading Overriding Field Variables Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Field Variables
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes
q q q
consider the following scenario: 1. Super has a field 'i' and a method test() which displays 'i' 2. Sub is a subclass of Super with it's own field 'i' and method test() 3. Super calls the test() method in it's constructor Which value for 'i' will be displayed when a Sub object is instantiated? Answer: the default value of the field 'i' in Sub the subclass object is instantiated as follows: the Superclass constructor is called the Subclass method test() is used as the Subclass has not been fully initialized, the default value of it's field variable is displayed the Subclass variables are initialized the Subclass constructor is called When an overridden method is called from a superclass constructor both the Subclass method and field variables are used Which methods and variables are used when an object reference for a Superclass is created and the assigned object is a Subclass type? Answer: both the Subclass methods and variables are used. The declared type is only valid at compile-time. The actual object type is used at runtime. BUT if you access the field variable directly, ie not through a method, the variable for the declared type is returned.
Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Creating a Super objref and pointing it to Sub obj // subclass obj stored in super reference Super sp1 = sb; // field variable in Sub object test() in Sub uses i: 20.0 // field variable in Super object sp1.i 10
Example Code
q
TestFields.java
Overloading
Overriding
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Initialization
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Initialization
JLS 12.4.1
q
before a class is initialized it's direct superclass must be initialized but interfaces implemented by the class need not be initialized a reference to a class field only causes the initialization of it's class even if it is referred to by a subclass ie if 'taxi' is a static field in 'Super' class and is referenced by 'Sub.taxi'; only 'Super' is initialized; not 'Sub' the initialization of an Interface does not implicitly cause initialization of it's SuperInterfaces
JLS 8.8.5.1
q
a constructor beginning with this() or super() can not use any class or superclass instance variables as an argument to a parameter
No argument constructor
q
ONLY the no-arg constructor is called implicitly when new instances are created // extends ClassA, has no ctor
New ClassB instance ClassA() ctor New ClassD instance ClassA() ctor ClassD() ctor
New ClassF instance with no-args ClassA() ctor ClassE() ctor ClassF() ctor
// invoked with different ctor New ClassF instance with parameter ClassA() ctor // no-arg ctor's of superclasses implicitly ClassE() ctor // called ClassF(String name) ctor q if the constructor being invoked explicitly calls a superclass constructor then the superclass no-arg constructor is not implicitly invoked ClassC extends ClassB which extends ClassA // (no call to super(str) in ClassC(String str)) New ClassC instance created ClassA() ctor // implicitly called ClassB() ctor // implicitly called Hello // (ClassC(String str) explicitly calls super(str)) New ClassC instance created ClassA() ctor // implicitly called In ClassB // explicit call; // NO implicit call to ClassB() Hello !!! Remember !!!
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Initialization
1. If NO constructor exists, the compiler will add a default no-arg constructor 2. The no-arg constructor of all superclasses in the hierarchy will be invoked and executed BEFORE the type constructor is executed UNLESS the type constructor explicitly calls another superclass constructor 3. There are NO IMPLICIT invocations to any other constructors
Also see
Sun Tech Tip: Constructor and Initialization Ordering
Example Code
q q
TestCtor.java TestCtor_1.java isA/hasA Inner Classes Overloading Overriding Field Variables Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Top-level Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
a top-level class can be declared public, final or abstract or it can have no access modifier which defaults to package or friendly access public class TestTopLevel {} final class FinalClass {} abstract class AbstractClass {} class PackageClass {} you can have more than one top-level class in a source code file; however, you can have only one public class in a source code file
Example Code
q
TestTopLevel.java
Overloading
Overriding
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Inner Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Inner classes are non-static classes defined within other classes (JLS8.1.2) class Outer { class Inner {}
q q q
} the compiled class files for the above are: Outer.class and Outer$Inner.class the Inner class type is: Outer.Inner instances of inner classes can be created in a number of ways
Create an Outer class object: Outer o1 = new Outer(); Then create an Inner class object: Outer.Inner i1 = o1.new Inner(); Or, create the inner class directly: Outer.Inner i2 = new Outer().new Inner(); Or, create one from within the outer class constructor class Outer { Outer() { new Inner(); } } q inner classes may have no declared access modifier, defaulting the class access to package q or, inner classes may be declared public, protected, private, abstract, static or final class Outer { public class PublicInner{} protected class ProtectedInner {} private class PrivateInner{} abstract class AbstractInner {} final class FinalInner {} static class StaticInner {} } q each instance of a non-static inner class is associated with an instance of their outer class q static inner classes are a special case. See Static Inner Classes
q
q q q
inner classes may not declare static initializers or static members unless they are compile time constants ie static final var = value; (JLS8.1.2) you cannot declare an interface as a member of an inner class; interfaces are never inner (JLS8.1.2) inner classes may inherit static members (JLS8.1.2) the inner class can access the variables and methods declared in the outer class to refer to a field or method in the outer class instance from within the inner class, use Outer.this.fldname
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Inner Classes
Example Code
q
TestInner.java isA/hasA Inner Classes Overloading Overriding Field Variables Anonymous Classes
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Static Nested Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
Overloading, Overriding, Runtime Types and Object Orientation - Static Nested Classes
q
a static inner class behaves like any top-level class except that its name and accessibility are defined by its enclosing class (JPL pg 50) ie use new Outer.Inner() when calling from another class formally called top-level nested classes (JPL pg 50) Note
There is alot of confusion over the terminology involving 'static nested classes'. They are not inner classes! While the formal name, as stated in the Java Programming Language, Second Edition by Ken Arnold and James Gosling, is 'top-level nested', it is a bit of an oxymoron. Joshua Bloch, author of Effective Java, prefers the term 'static member class' which provides a clearer sense of how such classes are utilized. class Outer { public static void main(String[] args) { int x = Inner.value; } static class Inner { static int value = 100; } }
q
they are not associated with an instance of their outer class ie you can create an Inner class object from within the Outer class using new Inner(); you do not need to create an Outer class object first as is required with non-static inner classes static inner classes can directly access static fields of the outer class but must use an instance of the outer class to access the outer classes instance fields
Example Code
q
TestStaticInnerClass.java
Overloading
Overriding
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Local Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads
may be declared within a block of code class Outer { void display() { class Local { // body of Local class } } } the compiled name of the above Local class is: Outer$1$Local.class local inner classes are not class members and are not tied to an instance of the enclosing class as they are not class members, they cannot be instantiated outside of the code block in which they are declared by using the class as a reference ie new Outer.new Local(); won't work they may not be declared private, public, protected, or static. May be declared final they may access static and non-static members of the enclosing class they may only access final variables or parameters of the enclosing code block
q q
The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
Example Code
q
TestLocalInner.java
Overloading
Overriding
Java Quick Reference - Overloading, Overriding, Runtime Types and Object Orientation - Anonymous Classes
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
anonymous classes are classes which have no name they are declared and defined using the name of the class or interface they extend ie new Enumeration() no modifiers, extends or implements are allowed if any parameters are passed the superclass must have a corresponding constructor Anonymous classes do not have constructors of their own as constructors always take the name of the class and Anonymous classes have no name even though you cannot use an extends clause, you can extend the superclass by overriding methods you cannot 'overload' or 'add' new methods. See example code
Once you create an anonymous class and override a method, that method is used until the class is unloaded they are most often used to implement an event listener interface or extend an adapter class
Example Code
q q
TestAnonymous.java TestAnonymousClass.java
Overloading
Overriding
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package
q q q
The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q
the Java garbage collector consists of three basic activities: 1. monitors program objects to determine when they are no longer required 2. informs selected objects that they should release any non-memory resources 3. destroys objects and reclaims their memory resources the gc operates as a seperate asynchronous background thread that tracks all program objects an object ceases to be needed by a program when it is no longer reachable an object is reachable if a reference to the object exists in any variables of any executing code an object is subject to garbage collection when it can no longer be reached but it is not necessarily garbage collected immeadiately there are no guarantees as to when the gc will reclaim an object or the order in which objects are reclaimed there is no way to tell if and when an object will be collected, you can only tell when an object becomes eligible for garbage collection you can request garbage collection by calling one of Runtime.getRuntime().gc() // no guarantee gc will run System.gc() // no guarantee gc will run you can also request that the finalize() method be run for objects deemed eligible for collection but which have not yet had their finalization code run Runtime.runFinalization() System.runFinalization()
Also see
q q q
Garbage Collection in Java Sun Tech Tip: Reference Objects Sun Tech Tip: Performance tip: Garbage Collection and setting to null
Traps
q q
a question that targets a specific object for garbage collection (can't be done) a question that presumes to force the gc to run (can only suggest it run)
Behaviour
Eligibility
finalize()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
variables and objects are eligible for garbage collection when they become unreachable following summarizes the normal duration of a declared object or variable Duration as long as the class is loaded for the life of the instance as long as the array is referenced until method execution ends until the constructor execution ends until the catch clause completes execution in a for-loop, until the loop completes in a code-block, until the code block completes
Declaration static field instance field Array components Method parameters Constructor parameters Exception handling parameters Local variables
q
any variable set to null automatically becomes eligible for garbage collection gc and the String pool
You may run across mock exam questions or discussions that state Strings created as part of the String pool are never garbage collected. This may well be true as garbage collection is implementation dependent. The certification exam will not contain questions that rely on specific implementations of any JVM; for exam purposes it is unlikely you will see any gc questions involving pooled Strings. Just remember once an Object reference has been set to null it is eligible for garbage collection.
Behaviour
Eligibility
finalize()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes
q q
q q q
protected void finalize() throws Throwable { try { close(); // close open files } finally { super.finalize(); } } q any exception thrown by finalize() during garbage collection halts the finalization but is otherwise ignored q finalize() is never run more than once on any object
Also see
q q
Object finalization and cleanup - JavaWorld, June 1998 Sun Tech Tip: Using finally versus finalize to guarantee quick resource cleanup
Example Code
q
TestGC.java
Behaviour
Eligibility
finalize()
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
protected
May be accessed by other classes in the same package or from any subclasses of the class in which they are declared.
private
May be accessed only from within the class in which they are declared.
no modifier
May only be accessed from within the package in which they are declared.
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
final
native
static
synchronized
transient volatile
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Java Quick Reference - Declarations and Access Control - this and super
this is an Object-Oriented Programming (OOP) operator it is used to refer to the current instance of an object it can be used in the body of a class constructor to refer to the object being created it can be used in the body of an instance method or initializer to refer to the object whose method is being executed it cannot be used in a static method or initializer most commonly appears in constructors can be used to explicitly call another constructor when used in a constructor it must be the first statment in the constructors body
class Super { int x; int y; Super(){ System.out.println("Super object being created."); } Super( int x, int y ) { this(); // call no-arg constructor this.x = x; this.y = y; } }
super
q q q q
super is an Object-Oriented Programming (OOP) operator used to call a constructor declared in a classes superclass commonly used in constructors and to access hidden fields or invoke overridden methods in the superclass if used in a constructor, must be the first statment in constructor body Remember
q
Java Quick Reference - Declarations and Access Control - this and super
} Subclass( int x, int y, int w ) { super(x,y); // call superclass constructor this.w = w; } } Remember You cannot use this() and super() in the same constructor. Subclass( int x, int y, int w) { this(); super(x,y); // compile-error }
Example Code
q
TestThisAndSuper.java
TestThisAndSuper.java class TestThisAndSuper { public static void main(String[] args) { Super sup = new Super(10,15); System.out.println("Super x: " + sup.x + " y: " + sup.y); Subclass sub = new Subclass(20,25,30); System.out.println("Sub x: " + sub.x + " y: " + sub.y + " w: " + sub.w); } } class Super { int x; int y; Super(){ System.out.println("Super object being created."); } Super( int x, int y ) { this(); // call no-arg constructor this.x = x; this.y = y; } }
http://www.janeg.ca/scjp/declarations/this.html (2 of 3) [15/03/2004 8:48:18 AM]
Java Quick Reference - Declarations and Access Control - this and super
Subclass( int x, int y ) { this(x,y,0); // call 3-param constructor } Subclass( int x, int y, int w ) { super(x,y); // call superclass constructor this.w = w; } } TestThisAndSuper.java
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
names are used to identify entities declared in a program ie classes, methods, variables, parameters, etc each name or identifier occupies a particular namespace every declaration has a scope; the areas of a program from which it can be accessed by its simple name Scope (accessible from) all compilation units within the package all the classes and interfaces within the compilation unit (source code file) all other declarations within the same file the statements immeadiately enclosed by the labeled statement ie if a loop is labelled, everything declared within the loop-construct has access to the label the body of the class and anything declared within the class the body of the method or constructor the code block in which the declaration occurs the enclosing block including the local class body the body of the for-loop the body of the catch clause
member parameter local variable local class local variable in a for-loop initializer parameter in a catch clause
1. 2. 3. 4. 5. 6. 7. 8.
when a name (identifier) is used; the meaning, or scope, of it's name is searched for based on where it appears in the code starting with: if used in a code block, for-loop, or in a catch clause, search is for a local variable within the enclosing construct if in a method or constructor, searches for a matching parameter search continues for a class or interface member, including inherited members if its a nested type, searches enclosing block or class. If its a static type, only static members of enclosing blocks or classes are searched. explicitly named imported types other types declared in the same package implicitly named imported types packages on the host system
Because of the way identifiers are looked up; shadowing declarations can occur For example, a field declaration can be shadowed by a local variable declaration
// field variable
System.out.println("x = " + x); System.out.println("TestShadowing.x = " + TestShadowing.x) } } Output: x = 0 TestShadowing.x = 1 q 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(). As one is found, int x = 0, the simple identifier name x is assumed to be within scope as a local variable q to access the field variable x, you must use its fully-qualified name TestShadowing.x Note
q
it was not necessary to instantiate an instance of the TestShadowing object to access the static field variable. If x had been an instance variable it would have been necessary to create a new instance of TestShadowing and use it's reference to access x
Hiding
q q
Shadowing is not the same as hiding hiding applies to members that would normally be inherited but are not because of a declaration of the same identifier in a subclass (JLS 6.1.3)
class SuperA { int x = 10; } class SubA extends SuperA { int x = 20; // hides x in superclass } q a method can hide a method in the superclass by overriding it static Methods cannot be overridden
q
a method cannot override a static method in the superclass; however, it can hide it by using the same declaration
class SuperA { static void method2() { } } class SubA extends SuperA() { void method2() { // declaration causes a compile-error } static void method2() { // compiles ok } }
q
static methods are hidden vs overridden as the JLS states they "cannot be overridden" so the compiler never compares subclass method declarations to static superclass method declarations. a static method in a subclass cannot hide an instance method in the superclass (JLS 8.4.6.2)
class SuperA { void method1() { } } class SubA extends SuperA() { static void method1() { // compile-error } }
q
a hidden method can be accessed by using super(), casting to the superclass or using the methods fully qualified name (JLS 8.4.6.2) ((SuperA)y).method2(); // cast to access hidden method instance variables can hide static and non-static variables in the superclass (JLS 8.4.6.1)
q q q
there may be times when a simple name could be interpreted as a variable, a type or a package based on the rules, a variable will be chosen before a type, and a type before a package in such situations a declaration is said to be obscured following naming conventions helps to avoid obscuring (see Naming conventions).
Also See
Tech Tip on Sun Site re: Shadowing, hiding, etc
Example Code
q q
TestShadowing.java TestHiding.java
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding
q q q
package members include all subpackages, and all top-level class and interface types declared in the package source files subpackages are determined by the host system. the java package always includes the subpackages lang and io and may include others no two distinct members of a package may have the same simple name
Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
class members are fields, methods, classes or interfaces declared within the body of the class or inherited by the class constructors are not members a field or method can have the same simple name a member class or interface can have the same name as a field or method a class can have two different field variables with the same simple name if they are declared in different interfaces and are inherited but they can only be accessed using their fully-qualified names (compile-error: ambiguous results if simple names are used) a class can have two or more methods with the same simple-name if their signatures are different (overloading) a class may have a method with the same simple-name and signature as an inherited method. The original method is not inherited and the new member is said to implement it, if the original was abstract or override it
the public final field length which contains the number of components in the array (may be zero or any positive number) the public method clone which overrides the method clone in Object and throws no checked exceptions all members inherited from class Object
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
accessibility is a static that can be determined at compile time it depends only on types and declaration modifiers accessibility effects inheritance of class members including hiding and overriding
Favourite Links About Feedback Even though ThreePoints is a subclass of Point, it cannot access the protected fields in Point. The subclass must be involved in the implementation of Point. The fact that the code is within the body of a subclass is irrelevant. To the compiler, Point is a type reference and p.x and p.y are declared protected in the type Point. If the parameter is changed to ThreePoints p the code will compile as the type ThreePoints inherits the protected fields x and y from Point. q declared private, accessible only from within the body of the enclosing class; private members are not inherited
class Private1 { private boolean state; Private1() { System.out.println("Private1 state: " + state); } } class Private2 extends Private1 { Private2() { // compile-error System.out.println("Private1 state: " + state); } }
q
if no access was declared, default access applies ie accesible only from code within the same package
Example Code
q q q
Access Modifiers
Special Modifiers
Scope
Inheritance
Access Control
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
while
do
transfers the flow of control to a labeled block or out of an enclosing statement forces a loop to start the next iteration catches and processes exception errors that occur during the execution of a given block of code try { // some operation } catch (Exception e) { // handle the exception } finally { // do this }
throw synchronized
throw an exception gets a lock on an object and executes a statement block synchronized(obj){ obj.setProperty(x); }
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps
q q q q
// nested 'if'
Example Code
Favourite Links
q
TestIf.java
About Feedback
Traps
q q
a non-boolean value used in the if( ) using the assignment operator '=' vs '==' if Exceptions switch Handling Exceptions for try-catch-finally while do
Statements Labels
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
q q q
no two case constant expressions may be the same the default case does not have to be at the end of the code block if no case matches the expression, the default case will be executed if break is omitted between case blocks the code will fallthrough, continuing to execute statements until a break statement or the end of the switch block is encountered
Example Code
q
TestSwitch.java
Tips
q q
you do not have to have a default statement the default statement can appear anywhere in the construct, does not have to be last
Traps
q q q q
using an expression vs a value promotable to int duplicate case values case statements with wrong type missing break statements
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
executes some initialization code, then repeatedly executes a boolean expression and some iteration code until the expression is false all three parts are optional ie the following examples are legal for( for( for( for( intialization; ; ) ; expression; iteration ) ; ; iteration) ; ; ) // endless loop
Initialization
q q q
initializes variables used within the loop if variables are declared within the loop, they are discarded after the loop completes For example, in the following code the initialization variable i is declared outside the for loop; so it's value is still available once the loop completes int i; for ( i=0; i<10 ; i++ ) { // do something } System.out.println("value of i: " + i ); In the following code, x is declared and initialized inside the for-loop and is therefore only accessible within the loop for ( int x=0; x<10 ; x++ ) { // do something } // compile-error, cannot resolve symbol: x System.out.println("value of i: " + x ); can be more than one initialization statement but the variables must either be declared outside the for-loop or the type for the variables must be declared at the beginning
Following compiles and runs ok: for( int x=10, y=0; x>y; x--, y++){ System.out.println( x + "\t" + y); } Following produces compile error int x;
for( x=10, int y=0; x>y; x--, y++){ System.out.println( x + "\t" + y); }
Boolean expression
q
if the expression evaluates to true the loop continues; otherwise, the loop is exited and execution continues after the loop statment block
Iteration
q
if the expression evaluates to true, the block statements are executed and then the iteration occurs if the expression evaluates to false, iteration does not occur
Break statement
q q
you can use a break statement to exit a for-loop at any time the break forces processing to the line following the for-loop statement block for( i=0; i<10; i++ ){ if( i==5 ) break; } // process continues here after the break
Continue statement
q
you can use continue to force processing to the next loop iteration for( i=0; i<10; i++){ if( i==5) continue; // skip printing 5 else System.out.println(i); }
Example Code
q q q
Tips
q
Traps
q q q
attempting to access a variable declared in the initialization outside of the for-loop incorrect initialization expression non-boolean expression
Statements
if
switch
for
while
do
Labels
Exceptions
Handling Exceptions
try-catch-finally
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
executes statement(s) repeatedly until the value of expression is false if the expression is false the first time, the statements will never execute int i = 1; while( i>3 ) { System.out.println("This shouldn't print"); }
both the break and continue statements can be used to alter the processing of a while loop while( i < 10 ){ if( i == 5 ) break; System.out.println(i); i++; } while( i < 10 ){ if( i==5 ) { i++; continue; }
System.out.println(i); i++; }
Example Code
q
TestWhile.java
Traps
q q
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection
q q
System.out.println("Always executed at least once"); } while( false ); break can be used to alter do-loop processing do { if( i==6 ) break; // exit loop System.out.println(i); i++; }while( i < 10 ); continue can be used to alter do-loop processing do {
The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback if( i==6 ) { i--; continue; // skip 6 } else { System.out.println(i); i--; } } while ( i >= 0);
q
Example Code
q
TestDo.java
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
outer: for( i=0; i<10; i++ ){ for( j=10; j>0; j--){ if( j == 5 ) { break outer; } } } Output: 0 5 outer: for( i=0; i<10; i++ ){ for( j=10; j>0; j--) { if( j== 5 ) { continue outer; } } } Output: 10 5 Note
q
// next iteration of i
two or more statements can have the same name as long as one is not enclosed within the other
Example Code
q q q
TestLabels.java Jaworski Exam Question 9, Chapter 5 Jaworski Exam, Question 10, Chapter 5
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
methods must declare which checked exceptions they may throw in their throws clause
public void methodName throws Exception1, Exception2,() q you do not have to include any checked exception which will be caught and handled within the method q a method can throw multiple exceptions q a method can only throw exceptions that have been declared in the throws clause q an overriding method cannot throw any checked exceptions which are not part of the original methods throws clause q the throws clause must also include any possible exceptions that can be thrown by the method q if you invoke a method that has a checked exception in its throws clause you can 1. catch and handle the exception 2. catch it and throw one of the exceptions listed in the method throws clause 3. declare the exception in your throws clause q a method which does not have a throws clause may still throw unchecked exceptions or errors q these exceptions and errors can occur at any time, in any code Standard Unchecked Exceptions: ArithmeticException IllegalTrheadStateException ArrayStoreException IndexOutOfBoundsException ClassCastException MissingResourceException EmptyStackException NegativeArraySizeException IllegalArgumentException NoSuchElementException IllegalMonitorStateException NullPointerException IllegalStateException NumberFormatException SecurityException Standard Unchecked Errors: AbstractMethodError NoSuchFieldError ClassFormatError NoSuchMethodError ExceptionInInitializerError OutOfMemoryError IllegalAccessError StackOverflowError IncompatibleClassChangeError ThreadDeath InstantiationError UnknownError InternalError UnsatisfiedLinkError LinkageError VerifyError NoClassDefFoundError VirtualMachineError q Static initializers, instance initializers, and class or variable initializers must not produce any checked exceptions q exceptions are thrown using the throw statement throw Expression; throw new ExampleException();
or by invoking a method that throws an exception the expression must be an instance of a Throwable object ie the exception class must implement Throwable
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
If a catch clause invokes System.exit() the finally clause WILL NOT execute.
Favourite Links
Also see
About
q
Sun Tutorial on Handling Errors with Exceptions Sun Tech Tip: Finally Clause
Feedback
Example Code
q q q q
Example code from Java 2 Certification Some other exception handling code Jaworski Exam Question 14, Chapter 5 Jaworski Exam Question 15, Chapter 5
Statements Labels
if Exceptions
for try-catch-finally
while
do
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding
Conversions
Implicit conversions (JPL pg 121)
q q
q q
conversions which happen automatically any primitive type value can be converted to a type which supports a larger value (widening primitive conversion) implicit conversion occurs from integer to floating point values but not vice versa you can use an object of one type wherever a reference to one of it's supertypes is required ie you can reference up the class hierarchy but not down you can assign a null object reference to any object reference
Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
when one type cannot be assigned to another type through implicit conversion you can use the cast operator
narrowing conversion loses all but the lowest bits (see Working with Binary, Octal and Hex numbers) narrowing from floating-point numbers to integer numbers occurs within the following minimum and maximum values (values are rounded-toward-zero)
long: -9223372036854775808..9223372036854775807 int: -2147483648..2147483647 short: 0..-1 char: 0..65535 byte: 0..-1 q if the floating-point value is NaN the result is an int or long value of zero
convert from any class, interface or array reference to an Object reference convert from any class to any interface that it implements convert from any class, interface or array type to a null reference convert from any subinterface to any interface it extends from any array to type Cloneable or type java.io.Serializable from any array of references to an array of compatible reference types the above conversions never produce a runtime error or require special action
You can't instantiate an interface reference as interfaces are always abstract SuperInterface si = new SuperInterface(); // compile-error
q q q
from Object to any other class, interface or array type from any superclass to a subclass from any non-final class to any interface as long as the class does not implement the interface from any interface to any non-final class from any interface to any final class providing the final class implements the interface from any interface to any other non-superinterface and providing neither interface contains methods with the same signature from any array of reference types to any other array of reference types as long as the types of each array are compatible under the Narrowing Reference rules
The above will be allowed at compile time but may throw a runtime ClassCastException if the types are not compatible Summary
q
widening conversions do not require casts and will not produce compile or runtime errors narrowing conversions require explicit casts. Will compile ok but may result in runtime ClassCastException errors
String Conversions
q
Method Conversion
q q
each argument is converted to the type of the method parameters widening conversion is implicit
reference to primitive primitive to reference (excepting String) null to primitive reference or primitive to boolean boolean to reference (excepting String) or primitive one class to another unless they have a superclass/subclass relationship (excepting String) final class to interface unless the final class implements the interface class to array unless the class is Object array to any class other than Object or String array to any interface other than java.io.Serializable or Cloneable interface to interface if they contain methods with the same signature
Also see
Sun Tech Tip: Narrowing and Widening Conversions
Example Code
q
TestConversions.java
Traps
q q
variables requiring narrowing conversion being passed to methods without using a cast assigning a typed byte or short variable to a char variable
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
the cast operator (type) is used to convert numeric values from one numeric type to another or to change an object reference to a compatible type used to enable conversions that would normally be disallowed by the compiler byte a = 1; byte b = 2; byte c = a + b; // a and b are promoted to int byte c = (byte)(a + b); // compiles ok
a reference of any object can be cast to a reference of type Object a reference to an object can be cast into a reference of type ClassName if the actual class of the object, when it was created, is a subclass of ClassName a reference to an object can be cast into a reference of type InterfaceName if the class of the object implements Interface, if the object is a subinterface of InterfaceName or if the object is an array type and InterfaceName is the Cloneable interface
If you cast up the class hierarchy you do not have to use the cast operator; if you are cast down the class hierarchy you must use the cast operator (BB pg 41) However, the compiler uses the declared type to verify the correctness of each method call; which means you cannot invoke a subclass method from a superclass reference. (See post by Michael Ernest at JavaRanch)
q
q q
a cast may work at compile-time but fail at runtime if the actual class of the object cannot be converted legally while you can cast up and down the class hierarchy, you cannot cast sideways you can cast an object reference using String Example from Java 2 Certification by Jamie Jaworski, pg 69
String s1 = "abc"; String s2 = "def"; Vector v = new Vector(); v.add(s1); s2 = (String) v.elementAt(0); // cast allowed System.out.println(); System.out.println("Value of s2: \t\t" + s2); output: abc Note: if the String cast is omitted, the type of v.elementAt(0) is an Object and a compile error (incompatible types) results. you cannot use String as a cast type for a primitive type String s = (String)x is invalid you can use String s = new Byte(x).toString();
X xy = new Y(); X xz = new Z(); Y yz = new Z(); Y y1 = new X(); Z z1 = new X(); X x1 = X x2 = Y Z Y Z Y Z y1 z1 y2 z2 y3 z3 = = = = = = y; z; (Y) (Z) (Y) (Z) (Y) (Z) x; x; x1; x2; z; y;
// compiles ok (up the hierarchy) // compiles ok (up the hierarchy) // incompatible type // X is not a Y // X is not a Z // compiles ok (y is subclass) // compiles ok (z is subclass) // // // // // // compiles ok but produces runtime error compiles ok but produces runtime error compiles and runs ok (x1 is type Y) compiles and runs ok (x2 is type Z) inconvertible types (casts sideways) inconvertible types (casts sideways)
Object o = z; Object o1 = (Y)o; // compiles ok but produces runtime error The casts work at compile time since the cast variable could conceivably be of a compatible type; however, at runtime the type of the variable is known and if it cannot guarantee to implement the contract of the cast type a java.lang.CastClassException will be thrown.
to cast an object reference to an array type reference, the object must be an array of a component type that is compatible with the component type of the array type reference
double arr[] = {1.5, 2.256, 3.59}; int arr1[] = (int) arr; // compile-error X[] arrX = { new X(), new X(), new X() }; Y[] arrY = { new Y(), new Y(), new Y() }; arrX = arrY; // compiles ok
Also see:
q
Conversions
Example Code
q
TestCast.java
Tips
q q
you cannot cast a primitive type to an object reference, or vice versa you cannot cast a boolean type to another primitive type
Traps
q
result of an integer operation on byte or short types being assigned to a byte or short without an explicit cast
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package
the Unary operators + and - when applied to byte, char or short numeric types result in the operand being automatically promoted to an int.(JLS 5.6.1) Example producing compile error: byte b = 5; // assign byte value byte b1 = +b; // found int, required byte unary promotion also applies for all shift operators. A long operator does not force the conversion of a left-hand int operator to long(JLS5.6.1)
The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects
q q
when operands are of different types, automatic binary numeric promotion occurs with the smaller operand type being converted to the larger. the following rules are applied in the order given. (JLS 5.6.2) r if either operand is a double, the other operand is converted to double r otherwise, if one of the operands is a float, the other operand is converted to a float r otherwise, if one of the operands is a long, the other operand is converted to a long r otherwise, both operands are converted to int
Examples producing compile-errors: byte = byte + byte; int = float + int; long = float + long; float = double + float; // // // // found found found found int, required byte float, required int float, required long double, required float
Remember to check the type of the variable to which results are assigned
Additive: + and Multiplicative: *, /, and % Comparison: <, <=, >, and >= Equality: = and != Bitwise: &, ^, and |
if one of the operands is byte and the other is short then the type of the expression is short byte = true ? byte : short // found short, required byte if one of the operands is a constant of type int and the other operand has a type of byte, short, or char and the value of the int operand is within the other type range, the type of the expression will be the type of the non-int operand.
short = true ? short : 1000; // compiles and runs OK short = false ? short : 1000; // compiles and runs OK
Example Code
q
TestNumericPromotion.java
Traps
q
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
an overflow results when a calculated value is larger than the number of bytes allowed for its type a underflow results when a calculated value is smaller than the number of bytes assigned to its type Java handles overflows by discarding the high-order-bytes that won't fit into the number of bytes allowed by its type (JJ pg 52)
int n = 2000000000; System.out.println(n * n); // output: -1651507200 An int is 32-bits, the result of n*n is 4,000,000,000,000,000,000 which needs 64-bits which in binary is: ---------- high-order bytes ------00110111 10000010 11011010 11001110 ------- low order bytes ----------10011101 10010000 00000000 00000000 because an 32-bit cannot retain the number, the 4 high-order bytes are dropped leaving the four low-order bytes: 10011101 10010000 00000000 00000000 which represent 1651507200 and since the right most bit is a 1 the sign value is negative
q
overflow or underflow conditions never throw a runtime exception; instead the sign of the result may not be the same as that expected in the mathematical result
You probably won't need to calculate overflows or underflows on the exam but should understand how they work. (also see Working with Hex, Octal and Binary numbers)
Java Quick Reference - Operators and Assignments - Binary/Octal/Hex and Decimal Number Systems
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes
Decimal system
q q q
the decimal number system we use every day is built on base ten 1010 it is based on 10 positions numbered 0 thru 9 each position corresponds to a power of 10 1024 = 1 0 2 4 x x x x 103 102 101 100 -> -> -> -> 1 0 2 4 x 1000 x 100 x 10 x 1 = 1000 = 000 = 20 = 4 ---1024
Binary system
q q
Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q q q
computer memory is based on the electrical representation of data each memory position is represented by a bit which can be either 'on' or 'off'. This makes it easier to represent computer memory using a base 2 number system rather than the base 10 decimal system. the binary system represents numbers by a series of 1's and 0's which correspond to 'on' and 'off' values a 1 represents an 'on' position, a 0, an 'off' position a byte is represented by 8 bits numbered 0 to 7 from left to right the leftmost bit is called the high-order bit, the right most bit, the low-order bit in the decimal system, each position corresponds to a power of 10, in the binary system, each position corresponds to a power of 2 = 0 = 64 = 0 = 0 = 8 = 0 = 0 = 1 -73 the largest number which can be represented by a byte is 255 or 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 or the bit pattern: 1111 1111 the smallest number is 0 represented by the bit pattern: 0000 0000 0 to 255 gives 256 possible values x x x x x x x x 27 26 25 24 23 22 21 20 -> -> -> -> -> -> -> -> 0 1 0 0 1 0 0 1 x 128 x 64 x 32 x 16 x 8 x 4 x 2 x 1
01001001 = 0 1 0 0 1 0 0 1
q q
Two's-complement
q
the two's complement method allows us to represent negative and positive values within the
Java Quick Reference - Operators and Assignments - Binary/Octal/Hex and Decimal Number Systems
q q q
0 to 256 bit positions in this system the numbers 0 thru 127 represent themselves and the numbers 128 to 256 represent negative numbers where 255 = -1, 254 = -2, 253 = -3, ... -1 is represented by 256 - 1 = 255, -127 is represented by 256-127 = 129, and -50 would be represented by 256 - 50 = 206 the high-order bit (the 7th position) is reserved for the sign value of a number a 0 in the high order bit means 'the sign value is set to positive' a 1 in the high-order bit means 'the sign value is set to negative'
01111111 = 0 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 127 10000000 = 128 or set sign negative 11111111 = 0 - 64 - 32 - 16 - 8 - 4 - 2 - 1 = -127 q larger numbers are represented by increasing the number of bits in a memory block q this is done in multiples of 8 hence 16-bit, 32-bit and 64-bit memory
q q q
16-bit memory can store numbers up to 216-1, 32-bit, 232-1, 64-bit, 264-1 if signed numbers are being used, the left-most bit still represents the sign so, 16-bits allows us to store 0 to 65,535 positions (216 - 1), 32-bits, 0 to 4,294,967,295 (232 1) using two's-complement arithmetic with 32-bit memory, subtract the negative number from 65,536 to find it's positive complement ie -336 would be represented by 65536 - 336 = 65200
Octal system
q q q q q
uses base 8 octal digits are represented by 0 thru 7 each position is a power of 8 each octal number can be represented by 3 binary digits 22+21+20 = 4+2+1 = 7 Octal 0 1 2 3 4 5 6 7 Binary 000 001 010 011 100 101 110 111
Decimal 0 1 2 3 4 5 6 7
q
to convert from Octal to Binary just replace the octal digit with the corresponding binary pattern Octal: 17 Binary: 001 111 to convert from Binary to Octal just replace the binary pattern with the corresponding octal digit Binary: 111 010 Octal: 72
Hexidecimal system
q q q
the hexidecimal system uses a base of 16 hexidecimal digits are represented by 0 thru 9 and the letters A,B,C,D,E,F one hexidecimal digit corresponds to a four-digit binary number
Java Quick Reference - Operators and Assignments - Binary/Octal/Hex and Decimal Number Systems
q
23+22+21+20 = 8 + 4 + 2 + 1 = 15 Hex 0 1 2 3 4 5 6 7 Binary Decimal 0000 8 0001 0010 0011 0100 0101 0110 0111 9 10 11 12 13 14 15 Hex 8 9 A B C D E F Binary 1000 1001 1010 1011 1100 1101 1110 1111
Decimal 0 1 2 3 4 5 6 7
q
this makes it easy to convert a number from binary to hex (just replace the binary pattern with the hex digits) or from hex to binary (replace the hex digit with the binary pattern) -> Hex: -> Hex: -> Binary: -> Binary: 0x0F 0xB302 1010 0000 1111 1111 1111 0000 0111 0101
Binary: 0000 1111 Binary: 1011 0011 0000 0010 Hex: Hex: 0xA0FF 0xF075
to convert a decimal number to a Hex, Octal or Binary number divide by the required base, the resulting remainders, in reverse order represent the required value
Convert Decimal 49 to Binary 49: 49 24 12 6 3 1 / / / / / / 2 2 2 2 2 2 = 24 = 12 = 6 = 3 = 1 = 0 remainder: remainder: remainder: remainder: remainder: remainder: 1 0 0 0 1 1 ( 49 - 2*24 = 49 - 48 = 1) ( 24 - 2*12 = 24 - 24 = 0) ( 12 - 2* 6 = 12 - 12 = 0) ( 6 - 2* 3 = 6 - 6 = 0) ( 3 - 2* 1 = 3 - 2 = 1) ( 1 - 2* 0 = 1 - 0 = 1)
Proof: 110001 = 32+16+0+0+0+0+1 = 4910 Convert Decimal 49 to Octal 49: 49 / 8 = 6 6 / 8 = 0 remainder: remainder: 1 6 ( 49 - 8*6 = 49 - 48 = 1) ( 6 - 8*0 = 6 - 0 = 6)
Proof: 618 = (6 * 81) + (1 * 80) = 48 + 1 = 4910 Convert Decimal 49 to Hexidecimal 49: 49 / 16 = 3 3 / 16 = 0 remainder: remainder: 1 3 ( 49 - 16*3 = 49 - 48 = 1) ( 3 - 16*0 = 3 - 0 = 3)
in Java octal numbers are represented by 3 digits beginning with a zero, so 618 would be written as 061 Hex numbers are always represented by 4 digits preceeded by 0x, so 3116 would be written as 0x0031 when converting large decimal numbers to binary, the simplest method is to convert to Hex and then to binary
Java Quick Reference - Operators and Assignments - Binary/Octal/Hex and Decimal Number Systems
Convert 4823 to Hex: 4823 301 18 1 / / / / 16 16 16 16 = 301 remainder: 7 = 18 remainder: 13 = 1 remainder: 2 = 0 remainder: 1 (4823 ( 301 ( 18 ( 1 16*301 16* 18 16* 1 16* 0 = 4823 - 4816 = 7) = 301 - 288 = 13) = 18 16 = 2) = 1 0 = 1)
Hex value: 0x12D7 Hex value converted to binary: 0001 0010 1101 0111
q
when converting large binary numbers, the simplest method is to convert to Hex and then to decimal
Convert Binary 0001 0010 1101 0111 to decimal 0001 0010 1101 0111 1 2 D 7 1 2 13 7 * * * * 163 162 161 160 = 4096 = 512 = 208 = 7 ---4823
Study aids
q
If you have Windows 95 you can use the Calculator in the Scientific mode (Start->Programs->Accessories->Calculator) to check results of decimal to hex, binary, and octal conversions. You can also use the Java Integer wrapper class to output binary, hex and octal strings. Example: System.out.println(Integer.toBinaryString(-29)); Marcus Greene has a great applet that lets you play around with bit-shifting at http://www.software.u-net.com/applets/BitShift/BitShiftAr.html
References:
q q
C: Step-by-Step by Mitchell Waite and Stephen Prata, SAMS, 1991 Hexidecimal and Octal Notation
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links
operate on a single operand the unary ~ , + and - operators can only be applied to numeric primitive types the unary ! (logical complement) can only be applied to a boolean type rules of unary numeric promotion apply
only used with integer values inverts the bits ie a 0-bit becomes 1-bit and vice versa in all cases ~x equals (-x)-1 byte b0 = 7; byte b1 = ~b0; ~7 = -7 -1 ~3578 = -3578-1 ~-1234 = -(-1234)-1 // binary: 0000 0111 // binary: 1111 1000 ( -8 ) = -8 = -3579 = 1233
returns the logical complement of a boolean type !(false) = true; !(true) = false; // complement of 'false' is 'true' // complement of 'true' is 'false'
the result of the unary + operator is a value not a variable byte b = +5; // result: 5
The unary plus (+) operator has no effect on the sign of a value; it is included for symmetry only and to allow the declaration of constants ie MIN_VALUE = +2.0; (JPL pg 128)
About Feedback
for integers negation effect is the same as subtraction from zero two's complement is used for integers so for all values of x, -x equals (~x)+1 byte b; b = -5; b = (~5) + 1;
// result: -5 // result: -5
negation of the maximum negative int or long value results in the same number. An overflow occurs but no exception is thrown. int i; long l = 0L; i = -(-2147483648);
// result: -2147483648
q q
l = -(-9223372036854775808L) // result: -9223372036854775808; for floating-point negation is not the same as subtraction from zero the unary (-) operator merely negates the sign of the value double d = 0D; d = -(15.63); d = -(-15.63);
Example Code
q
TestUnaryQuestions.java
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links
the operators ++ and -- are used to increment or decrement a variable value by 1 binary numeric promotion is applied on both the 1 and the variable value before the addition or subtraction occurs (ie at a minimum both values are promoted to an int) BUT the type of the expression is the type of the variable so narrowing conversion is applied if necessary ie if the original variable is a byte, short, or char the result is narrowed to the corresponding type
byte b = 2; byte b1; b1 = ++b; // no error although promotion occurs b = 127; b1 = ++b; // result: -128 (no error as fits within byte type) q the expression has the same type as the variable q they can appear before a variable (prefix) or after a variable (postfix) q cannot be used with final variables
1 is added to the value of the variable and the result is stored back in the variable both operators have the same effect as x = x + 1; int x; x = 0; ++x; x = 0; x++;
// result: 1
// result: 1
1 is subtracted from the value of the variable and the result is stored back in the variable both operators have the same effect as x = x - 1 int x;
// result: -1
when a prefix expression (++x or --x) is used as part of an expression, the value returned is the value calculated after the prefix operator is applied
x is incremented by 1 and the result is assigned to y when a postfix expression (x++ or x--) is used as part of an expression, the value returned is the value calculated before the postfix operator is applied int x = 0; int y = 0; y = x++;
original value of x is stored, x is incremented, original value of x is assigned to y when using the postfix form of the operators do not try constructs like int x = 0; x = x++; // result: 0, x is not incremented original value of x is saved (x0rig) x is incremented x0rig is assigned to x therefore, x will always equal original value
both the prefix and postfix forms may be used on char types char c = 'a'; c++; // result: b --c; // result: a the type of the variable does not change
Example Code
q
TestPrefixAndPostfix.java
Tips
q q
postfix/prefix operators have the highest level of precedence remember that when the postfix operator is used in an expression, the current value of the variable is used
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection
+ and have the same precedence and are left-associative operands must be primitive numeric types (see exception for String and +) or compile error occurs
Overloading and Overriding Threads The java.lang Package The java.util Package
*, /, % have the same precedence and are left-associative operands must be primitive numeric types or compile error occurs;
integer division rounds towards 0; ie result is truncated 10 / 3 = 3; // truncated result if the value of the divisor in integer division is 0 an ArithmeticException is thrown 10 / 0 // runtime error: ArithmeticException if the value of the divisor in floating-point division is 0 no exception is thrown; the value of the results are as follows: r division of a positive floating-point value: POSITIVE_INFINITY r division of a negative floating-point value: NEGATIVE_INFINITY r division of a floating-point value by -0: POSITIVE_INFINITY / 0 / 0 / -0 / 0 // // // // result: Infinity result: -Infinity result: Infinity result: NaN (Not a number)
References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About
q q
Feedback
q q
the modulo operator % is also called the remainder operator as it returns the remainder, or fractional part, of a division operation x % y is equivalent to x - ((int) (x/y) * y) can be used with both integer and floating-point numbers following rules apply as to the sign of the result: r result is negative if the divdend is negative r result is positive if the divdend is positive r if the divisor is zero, a runtime ArithmeticException is thrown r if the dividend is a floating-point value and the divisor is zero, no exception is thrown and the result is NaN 5 % 3 = 2
% % % %
3 3 3 0
// not a number
Also see:
q q q
Binary numeric promotion Overflow and underflow Sun Tech Tip: Division by Zero
Example Code
TestArithmetic.java
Traps
q
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the + and += operators both work on Strings operators actually signfy concatenation the result of the operation is a new string Strings are objects, not primitive types, and are read-only and immutable; the contents never change String variables store references to a string object NOT the string itself
String str = "Hello"; String str1 = "Universe!"; String str2 = str + str1; // join the two strings together String str3 = ""; str3 += str; // += only works with an initialized var String str4 = str2; q in the above code a reference to the string "Hello" is stored in the variable str q a reference to the string "Universe!" is stored in the variable str1 q a reference to a new string "Hello Universe!" is stored in the variable str2 q the reference for a new string "Hello" is stored in variable str3 str3 == str // false (ref to different String objects) q the reference for str2 is stored in variable str4 str4 == str2 // true (references are the same)
the String class creates a pool of Strings when you create a String by using the new operator or by using the + and += operators (the string is computed at runtime) you are implicitly telling the compiler to create a new String object when you create a String by assigning a string literal the compiler searches the existing string pool for an exact match. If it finds one, a new string is NOT created. Instead the variable is assigned a reference to the existing pooled string.
String str5 = "Hello Universe!"; // created in the string pool String str6 = "Hello Universe!"; str5 == str2 // false (str2 is not part of the pool, created // using '+' operator) str5 == str6 // true (matched an existing string found // in the pool) q to actually compare the contents of String objects use the String method equals() str5.equals(str2); // true (both objects hold the same string // characters)
by the rules of String Conversion (see Conversion) any type can be converted to a string this includes the primitive types for primitive types, conversion occurs by the compiler calling Type.toString(x) behind the scenes.
int x = 10; System.out.println("Result: " + x); is the same as System.out.println("Result: " + (Integer.toString(x)) );
Also see:
q q
Example Code
q
TestStringOperators.java
Tips
q
String operations whose result does not alter the original string (ie calling toUpperCase() on a String that is already in uppercase) return the original string reference; otherwise they return a reference to a new String Strings are immutable; the original String value can never be changed
Traps
q
using == to compare the contents of two different String objects Promotion Bitwise Ternary Overflow Shift String Unary Comparison equals() Prefix Logical Precedence Arithmetic Assignment Bit vs Logic
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package
& AND, | OR, ^ exclusive OR used for operations on integer and boolean values (see logical bitwise operators) results are calculated bit-by-bit binary numeric promotion rules apply left associative order of precedence: &, ^, |
returns a 1 if corresponding bits in both operands have a 1, otherwise returns a 0 = 00000000 00000000 00000000 00111111 = 00000000 00000000 00000000 11111100 ----------------------------------00000000 00000000 00000000 00111100 -> 60
63 252
| OR operator
q
returns a 0 if corresponding bits in both operands are 0, otherwise returns a 1 = 00000000 00000000 00000000 00111111 = 00000000 00000000 00000000 11111100 ----------------------------------00000000 00000000 00000000 11111111 -> 255
The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback 63 252 = 00000000 00000000 00000000 00111111 = 00000000 00000000 00000000 11111100 ----------------------------------00000000 00000000 00000000 11000011 -> 195 63 252
^ exclusive OR
q
returns a 0 if the corresponding bits of both operands are both 0 or both 1, otherwise returns a 1
Also see
q q
Example Code
q
TestBitwise.jsva
Tips
q
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
when both operands are boolean the result of the bitwise operators & | and ^ is a boolean & - true if both operands are true, otherwise false ^ - true if both operands are different, otherwise false | - false if both operands are false, otherwise, true
true & true true & false true ^ false true ^ true
// both operands true // one operand is false // both operands are different // both operands are the same // one operand is true // both operands are false
both operands must be boolean result is a boolean returns true if both operands are true, otherwise false evaluates the right-hand operand only if the left-hand operand is true
Conditional OR Operator ||
q q q q
both operands must be boolean result is a boolean returns true if one of the operands is true evaluates the right-hand operand only if the left-hand operands is false false false true true || || || || true false false true = = = = true; false; true; true; // both operands evaluated // only lef-operand evaluated
Also see
q
Example Code
q
TestLogical.java
Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding
q q q q
<< left-shift, >> right-shift, >>> unsigned right-shift only used on integer values binary numeric promotion is not performed on the operands; instead unary promotion is performed on each operand separately (JLS 15.19) both operands are individually promoted to int if their type is byte, short or char a long shift operator does not force a left-hand int value promotion to long (JLS5.6.1) left-associative left-hand operator represents the number to be shifted right-hand operator specifies the shift distance value << 2 // 2 is the distance to be shifted when the value to be shifted (left-operand) is an int, only the last 5 digits of the right-hand operand are used to perform the shift. The actual size of the shift is the value of the right-hand operand masked by 31 (0x1f). ie the shift distance is always between 0 and 31 (if shift value is > 32 shift is 32%value) 00000000 00000000 00000000 00100011 00000000 00000000 00000000 00011111 ----------------------------------00000000 00000000 00000000 00000011
Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
-> 3
-29 11111111 11111111 11111111 11100011 31 -> 0x1f 00000000 00000000 00000000 00011111 & ----------------------------------Shift value 00000000 00000000 00000000 00000011 -> 3 q when the value to be shifted (left-operand) is a long, only the last 6 digits of the right-hand operand are used to perform the shift. The actual size of the shift is the value of the right-hand operand masked by 63 (0x3D) ie the shift distance is always between 0 and 63 (if shift value is greater than 64 shift is 64%value) q the shift occurs at runtime on a bit-by-bit basis
bits are shifted to the left based on the value of the right-operand new right hand bits are zero filled equivalent to left-operand times two to the power of the right-operand For example, 16 << 5 = 16 * 25 = 512 00000000000000000000000000010000
Decimal 16
Left-shift 5 00000000000000000000000000010000 fill right 0000000000000000000000000001000000000 discard left 00000000000000000000001000000000 q the sign-bit is shifted to the left as well, so it can be dropped off or a different sign can replace it
new left hand bits are filled with the value of the left-operand high-order bit therefore the sign of the left-hand operator is always retained for non-negative integers, a right-shift is equivalent to dividing the left-hand operator by two to the power of the right-hand operator For example: 16 >> 2 = 16 / 22 = 4 00000000000000000000000000010000 00000000000000000000000000010000 00000000000000000000000000000100 00000000000000000000000000000100 -> Decimal 4 11111111111111111111111111110000 11111111111111111111111111110000 1111111111111111111111111111110000 11111111111111111111111111111100 -> Decimal -4
Decimal 16 Right-shift 2 fill left discard right Decimal -16 Right-shift 2 fill left discard right
identical to the right-shift operator only the left-bits are zero filled because the left-operand high-order bit is not retained, the sign value can change if the left-hand operand is positive, the result is the same as a right-shift if the left-hand operand is negative, the result is equivalent to the left-hand operand right-shifted by the number indicated by the right-hand operand plus two left-shifted by the inverted value of the right-hand operand For example: -16 >>> 2 = (-16 >> 2 ) + ( 2 << ~2 ) = 1,073,741,820 00000000000000000000000000010000 00000000000000000000000000010000 00000000000000000000000000000100 00000000000000000000000000000100 -> Decimal 4 11111111111111111111111111110000 11111111111111111111111111110000 0011111111111111111111111111110000 00111111111111111111111111111100
Decimal 16 Right-shift 2 fill left discard right Decimal -16 >>> 2 fill left discard right
Don't panic that it will take you forever to convert a shift question on the exam. You probably won't get more than one or two questions and they'll likely involve numbers under 20.
Also see
q
Example Code
q
TestShift.java
Method Invocation
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
used to compare primitive types and object references organized into three subgroups: relational, equality and the instanceof operator
produce a boolean result work with integers and floating-point numbers binary numeric promotion rules apply for numeric types any relational expression with NaN is false positive and negative zero are considered equal therefore -0.0 < 0.0 is false and -0.0 <= 0.0 is true
This is not true for Math.min() and Math.max(), which treats -0.0 as being strictly smaller than 0.0 q results, otherwise, are the same as their mathematical equivalents Less than: Less than or equal to: Greater than: Greater than or equal to: 5 5 5 5 < <= > >= 6 5 6 5 true true false true false true false
Less than: -0.0 < 0.0 Less than or equal to: -0.0 <= 0.0 Greater than: 5 > NaN
produce a boolean result lower precedence than the relational operators are used to compare primitive types, including boolean, and object references binary numeric promotion rules apply for numeric types if either operand is a Nan the result is false for == but true for != -0.0 and 0.0 are considered equal if the operands are object references, the result is true if both refer to the same object or array or if both are null if the operands are String objects, the result is false unless they refer to the same String object, even if the two objects contain the same characters (to compare the characters in a String object use the String.equals() method) (see String Literals) 5 == 5.0 5 != 5.0 arr1 == arr2 arr1 == arr3 arr1 != arr2 arr1 != arr3 s1 == s2 s1 == s3 true false false [different array objects] true [ref to same array object] true false true [same literal] true [same object reference]
Equals: Not Equal: Equals: Equals: Not Equal: Not Equal: Equals: Equals:
Equals: s1 == s4
left-operand must be a reference object or null; cannot use primitive types right-operand must be a Class, Interface name or Array type determines if the left-operand is an instance of the class, interface or array type specified by the right-operand returns the boolean value true if: r left-operand is a class or subclass of the right-operand r left-operand is an interface or subinterface of the right-operand r left-operand is an array of the same class, subclass or interface, subinterface of the right-operand array type -> true -> false -> true // arr = array of Strings // null is not an object // arr1 is an arry of int
Example Code
q
TestComparison.java
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding
q q q q
12 assignment operators: = *= /= %= += -= <<= >>= >>>= &= ^= |= all are right-associative ie a=b=c groups as a=(b=c) vs (a=b)=c except the simple assignment operator = which is left-associative eg a+b+c = (a+b)+c all are used with primitive data types except = and += which can be used with Strings all operators of the form op = cast their result to the type of the left-operand there is no implicit cast with the simple assignment operator = in all cases, x oper= y is equivalent to x = x oper y
For Example: Threads The java.lang Package The java.util Package The java.awt Package The java.io Package
q
x += y x %= y x |= y
x = x + y x = x % y x = x | y
References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
q
//
A a1 B b1
//
= = = =
// // // //
//
= inB; = inA;
= inA; // an Object type can take any reference = inB; = new C(); = new Object(); // incompatible types = null; = null; // any object reference can take a null Summary
If everything in the left-operands type contract can be met through the contract of the right-operand type, then the assignment will work. It doesn't matter if the right-operand type implements more than the left-operand type; as long as it implements what the left-operand type contract guarantees. !!! Warning !!!
The compiler treats the object on the right-side of the assignment as if it was the same type as the object on the left-side of the assignment. At runtime, the real class of the object is always used. of of of of object object object object a1 o1 o2 o3 -> -> -> -> Class Class Class Class B D D C // // // // declared declared declared declared type type type type was was was was Class A Object Object Object
an array can only be assigned to a variable of the same array type, of type Object, of interface Cloneable, or of interface java.io.Serializable
int intArr[] = { 1,2,3 }; int intArr1[] = intArr; // String arr[] = new A(); // String arr[] = inA; Object // Serializable Cloneable obj inA inS inC = = = = intArr; intArr; intArr; intArr;
// compiles ok // incompatible types // incompatible types // // // // compiles ok incompatible types compiles ok compiles ok
Also see
q q
Example Code
q
TestAssignment.java
Tips
q
a class may be assigned to an Interface type if the class implements the interface or one of it's sub-interfaces
Traps
q q
assigning subclasses with the same parent to each other assigning a parent class to a subclass without a cast Promotion Bitwise Ternary Overflow Shift String Unary Comparison equals() Prefix Logical Precedence Arithmetic Assignment Bit vs Logic
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads
q q
q q
The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes
q q q q q
// subclass of Class_A
c1 = false ? a : c; a1 = true ? b : a;
Example Code
q
TestTernary.java
Traps
q
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
defined in java.lang.Object therefore inherited by all classes returns true if and only if the two variables being compared hold a reference to the same object
To check if objects are of the same class use the Comparison operator: instanceof Class_A Class_B Class_C Class_B Class_A a b c d e = = = = = new Class_A(); new Class_B(); new Class_A(); b; null;
// false (different obj refs) // false (different obj refs) // true (same object refs) // false (always returned when // compared to a null) java.lang.String overrides the java.lang.Object equals() method to return true if and only if the objects being compared contain the same sequence of characters.
// true (diff objects, same chars) // true (same chars, coincidence // they are same objects) java.lang.Boolean overrides the java.lang.Object equals() method, returning true if and only if the Boolean objects represent the same boolean value b0 b1 b2 b3 = = = = new Boolean(true); new Boolean(false); new Boolean(true); b1; // false (different boolean values) // true (same boolean values) // true (same boolean values) FYI
You cannot assign values to Boolean types with either of the following constructs: Boolean b3 = new Boolean(); boolean b4 = true; b3 = b4; b3 = true; // compile-error: incompatible types // compile-error: incompatible types
Example Code
q
TestBooleanEquals.java
Tips
q
all the primitive type wrapper classes override the Object.equals() method to compare the value of the objects; the default Object.equals() checks if the variables reference the same object Promotion Bitwise Ternary Overflow Shift String Unary Comparison equals() Prefix Logical Precedence Arithmetic Assignment Bit vs Logic
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References
Operators [] . (params) expr++ expr-++expr --expr +expr -expr ~ ! new (type)expr */% +<< >> >>> < > >= <= instanceof == != & ^ | && || ?: = += -= *= /= %= >>= <<= >>>= &= ^= |=
Precedence can be overridden using parantheses 5 + 3 * 2 // Result: 11 (5 + 3) * 2 // Result: 16 when two operators of the same precedence are next to each other, associativity rules apply all binary operators (except assignment operators) are left-associative assignment is right-associative a - b + c is evaluated as (a - b) + c 5 - 2 + 1 // Result: 4, not 2
Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
q q q
a = (b = c)
// Result: 1
where boolean expressions are used to control loops while( v = stream.next() != null ) processValue(v); according to precedence rules, evaluates as
Example Code
q
TestPrecedence.java
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies SCJA Notes SCJD Notes Projects Favourite Links About Feedback
the operand of every expression is evaluated before the operation is performed except for the short-circuit operators (&&, ) and ternary operator behaviour can produce unexpected results if you're not careful. For example, the following code illustrates what can occur if you try to set the value of a variable in an if condition and you always expect the new value to be available:
int i = 10; int j = 12; if( (i<j) (i=3) > 5 ) if( (i<j) (i=3) > 5 ) // value of i after oper: 3 // value of i after oper: 10
if( (i>j) & (i=3) > 5 ) // value of i after oper: 3 if( (i>j) && (i=3) > 5 ) // value of i after oper: 10 q with & and both operands are always evaluated q with && and the second operand is only evaluated when it is necessary q with (i<j) evaluates to true; there is no need to check the other operand as returns true if either of the operands are true q with && (i>j) evaluates to false; there is no need to check the other operand as && returns true only if both operands are true. In this case one is false so there is no need to check the other operand
Also see
Bitwise operators Logical operators
Example Code
q
TestBitwiseAndLogical.java
Traps
q
using a new value based on a short-circuit operation that was never evaluated
Home SCJP2 Study Notes Language Fundamentals Operators and Assignments Flow Control and Exceptions Declarations and Access Control Garbage Collection Overloading and Overriding Threads The java.lang Package The java.util Package The java.awt Package The java.io Package References Miscellaneous Notes Tips & Traps Mock Exams Case Studies
when you pass a primitive value to a method, a copy of the value is made available to the method, not the value itself any changes made to the value in the method do not affect the original value int i = 50; changeValue(i);
Output: Original value of i: Value of i in the method: Value of i after method invocation:
when you pass an object reference to a method, a copy of the reference is passed. Operations in the method which change the object reference do not affect the original; however, changes to the object itself within the method affect the original object
int[] array = { 10,10,10 } // original array changeObjectReference(array) // set the reference to a new array changeActualObject(array) // set the 2nd element of the array Output: Original array values: Array in the method: After Object reference changed in method: After object changed in method:
10 20 10 10
q q
each argument is converted to the type of the method parameters widening conversion is implicit narrowing conversion is not implicit (values must be cast)
Also see:
q q
Conversion Understanding that parameters are passed by value and not by reference
Example Code
q
TestMethodInvocation.java
Traps
q q q
code that results in a primitive value being changed in a method (can't happen) code that results in an unchanged object value when it was changed in a method failing to cast a value to match a method parameter type ie assuming narrowing conversion
on a method call