Java Tips

Object-Oriented Programming

  • No explicit cast needed for upcasting, but explicit cast needed for downcasting.
  • Defining your class as implementing an interface marks objects of that class as an instance of that interface.
  • An abstract method cannot (obviously) be final.
  • An abstract method cannot be static because static methods cannot be overridden.
  • An instance method can be both protected and abstract. A static method can be protected.
  • Before Java runtime clones an object, it checks to see if the object’s class implements the Cloneable interface. If it does, the clone() method returns a clone of the object. If not, the clone() method throws a CloneNotSupportedException.
  • The clone method is protected, so an object can only request a clone of another object which is either in the same package or which it inherits from. (i.e. standard meaning of protected)
  • The JVM does not call an object’s constructor when you clone the object.
  • Classes can be modified from their default state using any of the three keywords: public, abstract, and final. So, can’t have a static class, only static methods.
  • A final variable is a constant, and a final method cannot be overridden.
  • A synchronised method can belong to an object or to a class.
  • Only one public class per file.
  • package statement must come first in file and must be followed by any import statements.
  • An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter. Java letters include _ and $. Digits include 0..9.
  • The JVM does not call an object’s constructor when an object is cloned.
  • Constructors never return a value. If you do specify a return value, the JVM will interpret your intended constructor as a method.
  • If a class contains no constructor declarations, then a default constructor that takes no arguments is supplied. This default constructor invokes the no-args superclass constructor, i.e. calls super();
  • If, in a constructor, you do not make a direct call to super or this (with or without args) [note: must be on the first line] then super(no args) will first be invoked then any code in the constructor will be executed. See constructors.jpr project.
  • A call to this in a constructor must also be on the first line. Note: can’t have an explicit call to super followed by a call to this in a constructor - only one direct call to another constructor is allowed.
Memory and Garbage Collection
  • As soon as you lose the reference to an object, that object becomes eligible for garbage collection.
  • Setting your object reference to null makes it a candidate for garbage collection.
  • You can directly invoke the garbage collector by getting an object which represents the current runtime and invoking that object’s gc() method (see p.95 of Exam Guide).
  • Can’t predict when garbage collection will occur, but it does run whenever memory gets low.
  • If you want to perform some task when your object is about to be garbage collected, you can override the java.lang.Object method called finalize(). This method is declared as protected, does not return a value, and throws a Throwable object, i.e. protected void finalize() throws Throwable.
  • Always invoke the superclass’s finalize() method if you override finalize().
  • The JVM only invokes finalize() once per object. Since this is the case, do not resurrect an object in finalize as when the object is finalized again its finalize() method will not be called. Instead you should create a clone of the object if you must bring the object back to life.
  • Remember that Java passes method parameters by value and not by reference. Obviously then, anything that happens to a primitive data type inside a method does not affect the original value in the calling code. Also, any reassignment of object references inside a method has no effect on the objects passed in.
Data Types and Values
  • Ranges for primitive data types are as follows:-

Data Type Range of Values  
-27.. 27-1
signed integer
-215.. 215-1
signed integer
-231.. 231-1
signed integer
-263.. 263-1
signed integer
32 bit
signed floating point
64 bit
signed floating point
16 bit
Unicode character
either true or false
  • To specify an octal (base 8) number, put a leading ‘0’ in front of i
  • To specify a hexadecimal (base 16) number, put a leading ‘0x’ in front of it.
  • By default, integer values are of type int. However, you can force an integer value to be a long by placing an ‘L’ after it.
  • By default, floating point values are of type double. However, you can force a floating-point value to be a float by placing an ‘F’ after it.
  • Java sets each element in an array to its default value when it is created. Default object value is null, default integer value is 0, default boolean value is false, default floating point value is 0.0, default char value is ‘\u0000’.
  • Arrays are objects allocated at runtime, so you can use a variable to set their length.
  • First element in an array is at index 0 and last element is at length-1. length is a special array variable (not a method, so don’t need round brackets after it).
  • Can only use curly braces in array initialisation when array is actually declared, i.e. can’t declare the array on one line then initialise it with curly braces on line below.
  • ASCII characters are all found in the range ‘\u0000’ to ‘\u00ff’
  • The default value for any class variable or instance variable declared as a char is ‘\u0000’.
  • >> is right shift keep the sign, >>> is right shift don’t keep the sign.
  • & and | can be used with both integral and boolean types. If used with integers the result is integral. If used with booleans, both operands are evaluated, even when the result of the operation can be determined after evaluating only the left operand.
  • && and || are used with boolean operands only. The right operand is not evaluated if the result of the operation can be determined after evaluating only the left operand.
  • The equals() method (defined at the ‘highest’ level as a method of Object) is used to test the value of an object. The == operator is used to test the object references themselves.
  • By default, equals() returns true only if the objects reside in the same memory location, i.e. if the object references are equal. So, by default, equals() and == do the same things. This will be the case for all classes that do not override equals().
  • String, Wrappers (including Integer, Long, Float, Double, Character and Boolean), BitSet, Date and File classes all override equals() so that the value true is returned if the values are equal.
  • The + and += operators are overloaded for Strings.
  • Dividing an integer by 0 is illegal and would cause Java to throw an ArithmeticException. Floating point numbers have values for infinity and not-a-number, so using arithmetic operators on floating point numbers never results in an exception.
Control Flow
  • A loop counter is usually an integer, however it could also be a floating point number - incrementing by 1.0
  • Breaking to a label means that the loop at the label is terminated. Any outer loop will keep iterating.
  • In contrast, a continue to a label continues execution with the next iteration of the labelled loop.
  • The expression for an if and while statement must be a Boolean.
  • The expression in a switch statement must be an int or a char.
  • A default statement in a switch is optional.
  • A case block will fall through to the case block which follows it, unless the last statement in a case block is a throw, return or break.
  • As with if statements, for and while loops, it is possible to nest switch statements.
  • Any line of code can be labelled BUT can only do a labelled continue to a loop, and can only do a labelled break to a loop or to an enclosing statement.
  • It is possible to have multiple catch blocks in a try-catch-finally. The finally block is optional.
  • A catch block must always be associated with a try block, i.e. can’t have a catch block by itself or with a finally block.
  • A finally block must always be associated with a try block, i.e. can’t have a finally block by itself or with a finally block.
  • With multiple catch blocks, the type of exception caught must progress from the most specific exception that you wish to catch to the superclasses for these exceptions. (Makes sense!)
  • Methods must declare any exception which they throw.
  • Invoking a method which declares it throws exceptions is not possible unless either the code is placed in a try-catch, or the calling method declares that it throws the exceptions, i.e. checked exceptions must be caught or rethrown. If the try-catch approach is used, then the try-catch must cope with all of the exceptions which a method declares it throws.
  • You can list more than one exception in the throws clause if you separate them with commas.
  • RuntimeException and its subclasses are unchecked exceptions.
  • Unchecked exceptions do not have to be caught.
  • All Errors are unchecked.
  • You should never throw an unchecked exception in your own code, even though the code will compile.
  • You cannot use a try block on its own. It must be accompanied by a following catch or finally (or both).
  • Code in a finally block will always be executed, whether an exception is thrown or not and whether any exception thrown is caught or not. Only terminating the program will stop the finally code from being executed.
  • A method can only throw those exceptions listed in its throws clause, or subclasses of those exceptions.
  • A method can throw any unchecked exception, even if it is not declared in its throws clause.
  • When you override a method, you must list those exceptions that the override code might throw. You can list only those exceptions, or subclasses of those exceptions, that are defined in the method definition you are inheriting from, i.e. you cannot add new exception types to those you inherit. You can choose to throw a subset of those exceptions listed in the method’s superclass, however, a subclass further down the hierarchy cannot then re-list the exceptions dropped above it.
  • If you define more than one method with the same name in the same class, Java must be able to determine which method to invoke based on the number and types of parameters defined for that method.
  • The compiler will complain if you have two methods with identical signatures exception for the return type and/or the exceptions thrown, i.e. can’t overload based on return type and/or exceptions thrown.
  • Determining which methods will be invoked with integer params - see p.195 of the Exam Guide.
  • It is possible to declare an inherited method abstract.
  • Obviously, it is not possible to override a final method.
  • A subclass may make an inherited method synchronized, or it may leave off the synchronized keyword so that its version is not synchronized. If a method in a subclass is not synchronized but the method in the superclass is, the thread obtains the monitor for the object when it enters the superclass’s method.
  • It is possible to declare an inherited method as abstract, but then there is no way to get to the behaviour in the hierarchy above the abstract declaration.
  • Return types must match the overriden method in the superclass exactly. The parameter types must match those in the superclass exactly, i.e. in the same order. If this is not the case, then the superclass’s method is not overridden. Compiler will not complain, however, unless exactly the same signature except for return type (or exceptions thrown - see earlier).
  • You cannot make a method in a subclass more private than it is defined in the superclass, ‘though you can make it more public.
  • Coercion of arguments only happens with overloading, not overriding.
  • It is perfectly legal to have two different instance variables with the same name if they are defined in different classes where one class inherits from the other.
  • Which variable is accessed depends on the type of object reference which the variable was declared to hold. Which method gets invoked depends on the underlying object. See p.106 Q1 & p.201 of Exam Guide.
  • A native method does not have a body, or even a set of braces, e.g. public native void method();
  • A native method cannot be abstract.
  • A native method can throw exceptions.
Math and String Classes
  • ceil() returns the next highest integer (expressed as a double)

Method call Returns
  • round() returns the closest integer (expressed as an int if the parameter was a float, or a long if the parameter was a double)

Method call Returns
  • random() returns a random number, a double, between 0.0 and 1.0
  • sqrt() takes a double and returns a double. If the argument is NaN or <0, the result is NaN.
  • sin(), cos() and tan() all take a double and return a double.
  • All objects respond to toString(), which you can override to return a String representation of your object.
  • String objects have the following methods: length(), toUpperCase(), toLowerCase(), equals(), equalsIgnoreCase(), charAt(), indexOf(), lastIndexOf(), substring(), toString() and trim().
  • There are four versions of indexOf()

Arguments Results
(int ch) - works if you put a char in! Finds the first occurrence of this character
(int ch, int fromIndex) Finds the first occurrence of this character starting from fromIndex
(String substring) Finds the start of this substring
(String substring, int fromIndex) Finds the start of this substring searching from fromIndex
  • There are four versions lastIndexOf() - as above table but, in each method, finding the last index rather than the first index.
  • First character in a String is at position 0, last character is at position length()-1
  • There are two versions of substring()

Arguments Results
(int startIndex) Returns a substring starting with startIndex and extending to the end of the String
(int startIndex, int endIndex) Returns a substring starting with startIndex and extending to (but not including) endIndex
  • For a StrintoString() returns itself - the same object reference (obviously pointing to the same object) that was used to invoke the method.
  • trim() returns a new String object that cuts off any leading and trailing whitespace for the String for which it was invoked.
  • Java considers "whitespace" to be any character with a code less than or equal to ‘\u0020’ which is the space character.


  • InputStream and OutputStream are abstract classes.
  • FileInputStream and FilterInputStream both inherit directly from InputStream.
  • FileOutputStream and FilterOutputStream both inherit directly from OutputStream.
  • DataInputStream inherits directly from FilterInputStream.
  • DataOutputStream inherits directly from FilterOutputStream.
  • When you create a Filter stream, you must specify the stream to which it will attach.
  • A Filter stream processes a stream of bytes in some way. By "chaining" any number of Filter streams, you can add any amount of processing to a stream of bytes.
  • DataInputStream, DataOutputStream and RandomAccessFile know how to work with Java data types because they implement the DataInput and DataOutput interfaces, whereas FileInputStream and FileOutputStream know only how to work with individual bytes.
  • RandomAccessFile implements both DataInput and DataOutput methods - RandomAccessFile objects can read from and write to files.
  • The File class is not used to create files. Can create a file using an instance of class RandomAccessFile and FileOutputStream.
  • To test if a File object refers to an existing file, you can invoke exists() which returns true or false. The File methods canRead() and canWrite() return boolean values that indicate whether the application can read from or write to the file. (Note: applets can’t write to a file.)
  • Can use File methods to make a permanent change to the file system. For example, you can call delete() or rename(). For rename(), need to supply a File object which embodies the new name.
  • You can create a directory using the File class. The method mkdir() does this.
  • It is possible to navigate the filing system using the File class. Methods getParent(), getPath() and getName() are provided, and also getAbsolutePath().
  • The method getAbsolutePath() returns the name of the current user directory (the full pathname included) with the file name concatenated. See Practice Exam 1 Q.45
  • Creating a FileOutputStream object creates the appropriate file. If the file already exists, FileOutputStream replaces it (unless the FileOutputStream object is created using the constructor which takes a String and a boolean - see later)
  • Upon creation of a RandomAccessFile object, need to supply a file object plus a mode. Alternatively, can supply a filename plus a mode.
  • Valid modes for RandomAccessFile are "r" and "rw".
  • Constructors for FileInputStream: one takes a String, one takes a File, one takes a FileDescriptor
  • Constructors for FileOutputStream: one takes a String, one takes a File, one takes a FileDescriptor, one takes a String and a boolean (which indicates whether or not to append).
  • Constructors for FilterInputStream: one only, which takes an InputStream
  • Constructors for FilterOutputStream: one only, which takes an OutputStream
  • See Chapter 11 Review Questions for io stuff - very useful.
  • A Java program runs until the only threads left running are daemon threads.
  • A Thread can be set as a user or daemon thread when it is created.
  • In a standalone program, your class runs until your main() method exists - unless your main() method creates more threads.
  • You can initiate your own thread of execution by creating a Thread object, invoking its start() method, and providing the behaviour that tells the thread what to do. The thread will run until its run() method exists, after which it will come to a halt - thus ending its life cycle.
  • The Thread class, by default, doesn’t provide any behaviour for run().
  • There are two ways to provide the behaviour for a thread
  • Subclass the thread and override the run() method - see p.253 of Exam Guide.
  • Implement the Runnable interface and indicate an instance of this class will be the thread’s target.
  • A thread has a life cycle. Creating a new Thread instance puts the thread into the "new thread" state. When the start() method is invoked, the thread is then "alive" and "runnable". A thread at this point will repond to the method isAlive() by returning true.
  • The thread will continue to return true to isAlive() until it is "dead", no matter whether it is "runnable" or "not runnable".
  • If 2 threads are alive, with the same highest priority, the JVM switches between them. The JVM will switch between any number of threads with the same highest priority.
  • The priority numbers for threads falls between the range of Thread.MIN_PRIORITY and Thread.MAX_PRIORITY.
  • The default thread priority is Thread.NORM_PRIORITY.
  • New threads take on the priority of the thread that spawned them.
  • You can explicitly set the priority of a thread using setPriority(), and you can get the priority of a thread using getPriority(). There is no constructor for thread which takes a priority.
  • The JVM determines the priority of when a thread can run based on its priority ranking, but this doesn’t mean that a low priority thread will not run.
  • The currently executing thread can yield control by invoking yield(). If you invoke yield(), Java will pick a new thread to run. However, it is possible the thread that just yielded might run again immediately if it is the highest priority thread.
  • There are 3 types of code that can be synchronized: class methods, instance methods, any block of code within a method.
  • Variables cannot take the synchronized keyword.
  • Synchronization stays in effect if you enter a synchronized method and call out to a non-synchronized method. The thread only gives up the monitor after the synchronized method returns.
  • Using a thread’s stop() method will make it die.
  • There are 3 ways to transition a thread between "runnable" and "not runnable"

    put it to sleep and wake it up  (not on the test)
    pause it and resume it  (not on the test)
    use the methods wait(), notify() and notifyAll() 
    - these are methods of class Object. wait() throws InterruptedException.
  • The third method listed above allows communication between the threads, whereas the other 2 methods don’t.
  • By using the methods wait(), notify() and notifyAll(), any thread can wait for some condition in an object to change, and any thread can notify all threads waiting on that object’s condition that the condition has changed and that they should continue.
  • When a waiting thread pauses, it relinquishes the object’s monitor and waits to be notified that it should try to reacquire it.
  • If you know you only have one thread waiting on a condition, you can feel free to use notify(), otherwise you should use notifyAll(). The notifyAll() method wakes up all threads waiting to reacquire the monitor for the object.
  • The reasons why a thread might be "alive" and "not runnable" are as follows:
  • the thread is not the highest priority thread and so is not able to get CPU time
  • the thread has been put to sleep using the sleep() method (of class Thread. Throws InterruptedException)
  • the thread has been suspended using the suspend() method
  • the thread is waiting on a condition because someone invoked wait() for the thread
  • the thread has explicitly yielded control by invoking yield()
Graphical User Interfaces
  • If you want to explicitly repaint a component, you should not call paint() directly. Instead you should invoke your component’s repaint() method.
  • The repaint() method is overloaded. The no-args version of repaint() does not cause your user interface to repaint right away. In fact, when repaint() returns, your component has not yet been repainted - you’ve only issued a request for a repaint(). There is another version of repaint() that requests the component to be repainted within a certain number of milliseconds.
  • The repaint() method will cause AWT to invoke a component’s update() method. AWT passes a Graphics object to update() - the same one that it passes to paint(). So, repaint() calls update() which calls paint().
  • The Graphics object that AWT hands to update() and paint() is different every time the Component is repainted.
  • When Java repaints on its own, such as when the user resizes an applet, the AWT does not invoke update() - it just calls paint() directly.
  • The update() method does three things in this order:
  • clears the background of the object by filling it with its background colour
  • sets the current drawing colour to be its foreground colour
  • invokes paint(), passing it the Graphics object received
  • Common graphics methods:
  • drawString() - takes a String, followed by x then y co-ord of baseline for first char
  • drawLine() - takes x then y co-ords of starting point, then x then y co-ords of end point
  • drawRect() / fillRect() - take 4 params - x then y co-ords of top left corner, then width then height
  • drawOval() / fillOval() - take 4 params - x, y, width, height and draw an oval inside corresponding rectangle
  • drawPolygon() / fillPolygon() - (int[] xpoints, int[] ypoints, int npoints) - array of x co-ords then array of y co-ords followed by the number of points to use
  • drawArc() / fillArc() - takes 6 params - x then y co-ord of top left corner (of bounding rectangle of corresponding oval), width then height of arc, then start angle (not really an angle, more a position on the clock - 0 represents 3 o’clock), then number of degrees to move along the arc. Last parameter can also be negative, if you want to move in a clockwise direction round the arc.
  • The Image class does not provide a constructor for specifying where an image will come from.
  • You can obtain an Image, typically by downloading it from the Internet by specifying a URL. You can retrieve an image and obtain an Image object by invoking an Applet method named getImage(). This method takes a URL.
  • When the getImage() method returns, the data for the image is not necessarily immediately available. The method returns right away, even if the image resource is located over the Internet on a Web server and must be downloaded.
  • When you invoke the Graphics method drawImage() the image download begins. The object you specify as an ImageObserver keeps the Java graphics system up-to-date on the state of the download. When the ImageObserver sees that the download is complete, it notifies the graphics system that it can draw the image in its entirety.
  • ImageObserver is an interface. The Component class implements this interface, so any component (such as an Applet itself) can be used as an ImageObserver.
  • TextArea takes rows then cols in constructor. If you type in more text than can be displayed all at one, scrollbars appear automatically.
  • TextField takes only cols. A user may one type one line into a TextField. No scrollbars appear if the line is too long to be displayed, but can use arrow keys to move to beginning or end of text.
  • TextArea and TextField both inherit from TextComponent which provides a setEditable() method.
  • For a variable width font, TextArea / TextField width is based on average of letter widths.
  • Can populate a List using addItem() method.
  • As well as a no-args constructor and a constructor which takes number of rows, List class also has a constructor which takes number of rows followed by a boolean value which represents whether or not multiple list item selections are allowed.

  • Java 1.0 



    • Component methods for Java 1.0.2 - enable(), disable(), show(), hide(), size(), resize(), setForeground(), setBackground(). 
    • enable() / disable() - make a component selectable or not by the user. 
    • size() / resize() - the size() method retrieves the size of the Component as a Dimension object which has two fields (width and height). The resize() method sets the size of the Component. The method is overloaded - one version takes a Dimension object and the other takes width and height directly as int values. 
    • show() / hide() - the show() method makes a Component visible, the hide() method makes a Component invisible. The show() method is overloaded so that you can supply a boolean parameter to indicate whether to show the Component (if the parameter is true). 
    • A Frame is only visible when the show() method has been invoked. 
    Java 1.1
    • Component methods for Java 1.1 - setEnabled(), getSize(), setSize(), setVisible(), setForeground(), setBackground(). setEnabled() replaces enable() / disable() and takes a boolean value. getSize() and setSize() replace size() / resize(). setVisible() replaces show() / hide() and takes a boolean value. 
  • Java provides a Color class which defines many static constants that contain instances of class Color already initialized to common colours. To use red, for example, you can access The Color class has a constructor which takes three int values of red, green and blue so that you can make up your own colour.
  • Each container has exactly one layout manager which determines how to arrange the Components within a Container.
  • A layout manager is any class that implements the LayoutManager interface. Java’s 5 layout managers all inherit directly from class Object, but they implement the LayoutManager interface, which defines 5 abstract methods:
            • addLayoutComponent()
            • layoutContainer()
            • minimumLayoutSize()
            • preferredLayoutSize()
            • removeLayoutComponent()
  • Instead of invoking the layout manager’s methods yourself, Java’s default Container methods invoke them for you at the appropriate times. These Container methods include add(), getMinimumSize(), getPreferredSize(), remove() and removeAll() (these are all Java 1.1 methods).
  • Each type of container comes with a default layout manager. Default for a Frame, Window or Dialog is BorderLayout. Default for a Panel is FlowLayout().
  • A FlowLayout object arranges components left to right and top to bottom, centering each line as it goes. The FlowLayout layout manager is the only layout manager which allows components to be their preferred size. If a container using a FlowLayout is resized, all of the components inside it might need to be rearranged, and some might not be completely visible.
  • A BorderLayout object arranges components according to the directions "North", "South", "East" and "West". There’s also an area for "Center" which includes any space left over from other regions.
  • Components are rarely allowed to be their preferred size in a BorderLayout. BorderLayout stretches components. Stretches "North" and "South" components horizontally. Stretches "East" and "West" components vertically. Stretches "Center" components both horizontally and vertically.
  • If nothing is placed in "East" or "West", for example, then the "Center" stretches all the way from the left edge of the Container to the right edge.
  • Some components are stretchable and others are not. For example, Button, Label and TextField are stretchable, whereas Checkbox is not.
  • GridLayout objects allow you to specify a rectangular grid in which to place the components. Each cell in the grid is the same height as the other cells, and each width is the same as the other cells. Components are stretched both horizontally and vertically to fill the cell.
  • When a GridLayout object is first constructed, you must first specify how many rows and how many columns the grid will have. Components are added to the grid left to right and top to bottom. If more components are added than there are columns, the GridLayout keeps the same number of rows but adds the necessary number of columns.
  • You can change a Container’s layout manager to be a different one by invoking setLayout().
Event Handling
  • All of the events dispatched by AWT’s components use event classes that are subclasses of AWTEvent, which is in java.awt. These subclasses are defined in the java.awt.event package.
  • The AWT does not notify your event handler of every event that occurs over a component, as in the old days of 1.0.2. Now, AWT informs your event handler only about the events it is interested in.
  • Define a class which implements the necessary Listeners and then use the Component addABCListener() method to register an interest in a certain type of event, e.g. addMouseListener(this).
  • The Listener interfaces inherit directly from java.util.EventListener.
  • The Listener interfaces are
            • ActionListener
            • AdjustmentListener
            • ComponentListener
            • FocusListener
            • ItemListener
            • KeyListener
            • MouseListener
            • MouseMotionListener
            • TextListener
            • WindowListener
  • If you define a class which implements a listener, you must obviously include stubs for those listener methods not implemented as interfaces are implicitly abstract and failure to implement all of the methods would result in an abstract subclass.
  • The Listener methods are as follows: (Note - all are declared as public void and all take only one parameter which is an Event of the same name as the Listener, i.e. ActionListener methods take an ActionEvent etc.

Listener Methods
ActionListener actionPerformed
AdjustmentListener adjustmentPerformed
ComponentListener componentHidden




ContainerListener componentAdded


FocusListener focusGained


ItemListener itemStateChanged
KeyListener keyPressed



MouseListener mouseClicked





MouseMotionListener mouseDragged


TextListener textValueChanged
WindowListener windowClosed







See pages 360-363 for Event classes.

  • There’s an Adapter class to match each Listener interface. Each Adapter class defines no-op stubs for the methods declared in the corresponding interface. So can extend an Adapter rather than implement a Listener interface (but this only makes sense when the object that will listen for and handle the event has no other responsibilities).
Passing Arguments to Programs
  • The main() method must be declared as a public, static method that does not return a value and takes an array of String objects. The order of public and static, and the way in which the String array is defined, is not strictly enforced.
  • When main() ends, that may or may not be the end of the program. The JVM will run until the only remaining threads are daemon threads. If main() does not spawn any more threads, then the program will end when main() ends.
Embedding Applets into Web Pages
  • The applet tag requires three codewords - code, width and height, e.g. <applet code=Metric.class width=200 height=100></applet>
  • If the applet is loaded relative to the page, there are two things that can change the base location - one of which is if the HTML file itself contains a <base> tag - this tag specifies where to look for the applet class.
  • The conventional way to pass a parameter to an applet is to use the <param> tag, using one <param> tag per parameter. Each <param> tag can take only one parameter.
  • Each parameter value can be retrieved by the applet as a String, using methods defined in class Applet.
  • If you want to pass a different type of value, such as an int or a boolean, you must convert it from a String, most likely by using a wrapper class.
  • If you’d like a parameter to contain spaces, you should place this value between quotes. Otherwise it’s not strictly necessary to pass params in quotes (good style though).
  • You retrieve the value of a parameter using the getParameter() method defined by the Applet class. This method returns a String containing the value of the parameter, or null if the parameter was notdefined at all.
  • Class Applet inherits from Panel.
  • When an applet instance is first instantiated, Java invokes the applet’s init() method.
  • When the Web page containing the applet is about to appear, Java invokes the applet’s start() method.
  • When the Web page is about to be replaced with another page, Java invokes the applets stop() method.
  • When the Web page is removed from the browser’s cache and the applet instance is about to go away, Java invokes the applet’s destroy() method.
Inner Classes
  • In Java 1.1 you can define classes inside classes - these are known as "inner classes".
  • If you define an inner class at the same level as the enclosing class’ instance variables, the inner class can access those instance variables - no matter what their access control.
  • If you define an inner class within a method, the inner class can access the enclosing class’ instance variables and also the local variables and parameter for that method.
  • If you do reference local variables or parameters from an inner class, those variables or parameters must be declared as final to help guarantee data integrity.
  • You can also define an anonymous class - a class without a name. See p.399 Exam Guide for syntax.
  • If you’d like to refer to the current instance of the enclosing class, you can write EnclosingClassName.this.
  • If you need to refer to the inner class using a fully qualified name, you can write EnclosingClassName.InnerClassName.
  • If your inner class is not defined as static you can only create new instances of this class from a non-static method.
  • Anonymous classes cannot have const
JAR Files
  • JAR stands for "Java Archive". The 1.1 JDK comes with a utility called ‘jar’ that creates JAR files. Example syntax: jar -cf Jungle.jar Panther.class Leopard.class
  • Directories are processed recursively
  • Can specify a JAR file in a Web page by adding ‘archive="jars/Jungle.jar" ’ to the <applet> tag. E.g. <applet code=ExampleApplet.class archive="jars/example.jar" width=200 height=110> </applet>
  • You can also define more than one JAR file in the archive value by listing them all within the quotes and separating their names with commas.
Serializing Objects
  • In Java 1.1 it is now possible to read and write objects as well as primitive data types, using classes that implement ObjectInput and ObjectOutput. These two interfaces extend DataInput and DataOutput to read or write an object. ObjectInputStream and ObjectOutputStream implement these interfaces.
  • If a class implements the Serializable interface, then its public and protected instance variables will be read from and written to the stream automatically when you use ObjectInputStream and ObjectOutputStream.
  • If an instance variable refers to another object, it will also be read or written, and this continues recursively.
  • If the referenced object does not implement the Serializable interface, Java will throw a NotSerializableException.
  • The Serializable interface serves only to identify those instances of a particular class that can be read from and written to a stream. It does not actually define any methods that you must implement.
  • If you create your own class and want to keep certain data from being read or written, you can declare that instance variable using the transient keyword. Java skips any variable declared as transient when it reads and writes the object following the Serializable protocol.
  • Using the Reflection API, a program can determine a class’ accessible fields, methods and constructors at runtime.

More Java Questions

Have a Java Problems
Do you have a Java Question?

Java Books
Java Certification, Programming, JavaBean and Object Oriented Reference Books

Return to : Java Programming Hints and Tips

All the site contents are Copyright © and the content authors. All rights reserved.
All product names are trademarks of their respective companies.
The site is not affiliated with or endorsed by any company listed at this site.
Every effort is made to ensure the content integrity.  Information used on this site is at your own risk.
 The content on this site may not be reproduced or redistributed without the express written permission of or the content authors.