![]() |
A3. Java Basics
In this section, you will learn about the Java language's:
PortabilityJava programs are portable across operating systems and hardware environments. Portability is to your advantage because:
Three features make Java programs portable:
SecurityThe Java language is secure in that it is very difficult to write incorrect code or viruses that can corrupt/steal your data, or harm hardware such as hard disks. There are two main lines of defense:
RobustnessThe Java language is robust. It has several features designed to avoid crashes during program execution, including:
Java Program StructureA file containing Java source-code statements is considered a compilation unit. Such a compilation unit contains a set of classes and, optionally, a package definition to group related classes together. Classes contain data and method members that specify the state and behavior of the objects in your program. Java programs come in two flavors:
The major differences between applications and applets are:
Java Program ExecutionThe Java byte-code compiler translates a Java source file into machine-independent byte code. The byte code for each publicly visible class is placed in a separate file so that the Java run-time system can easily find it. If your program instantiates an object of class A, for example, the class loader searches the directories listed in your CLASSPATH environment variable for a file called A.class that contains the class definition and byte code for class A. There is no link phase for Java programs; all linking is done dynamically at run-time. The following diagram shows an example of the Java compilation and execution sequence for a source file named A.java containing public class A and non-public class B: Java programs are, in effect, distributed applications. You may think of them as a collection of DLLs (dynamically loadable libraries) that are linked on demand at run-time. When you write your own Java applications, you will often integrate your program with already-existing portions of code that reside on other machines. A Simple ApplicationConsider the following trivial application that prints "hi there" to standard output:public class TrivialApplication { // args[0] is first argument // args[1] the second public static void main(String[] args) { System.out.println("hi there"); } } The command java TrivialApplication tells the Java run-time system to begin with the class file TrivialApplication.class and to look in that file for a method with signature: public static void main(String[] args); The main method will always reside in one of your class files. The Java language does not allow methods outside of class definitions. The class, in effect, creates scoped symbol StartingClassName.main for your main method.
Magercise
Applet ExecutionAn applet is a Java program that runs within a Java-compatible WWW browser or in an appletviewer. To execute your applet, the browser:
The predefined methods automatically invoked by the run-time system are:
The basic structure of an applet that uses each of these predefined methods is: import java.applet.Applet; // include all AWT class definitions import java.awt.*; public class AppletTemplate extends Applet { public void init() { // create GUI, initialize applet } public void start() { // start threads, animations etc... } public void paint(Graphics g) { // draw things in g } public void stop() { // suspend threads, stop animations etc... } public void destroy() { // free up system resources, stop threads } } All you have to do is fill in the appropriate methods to bring your applet to life. If you don't need to use one or more of these predefined methods, simply leave them out of your applet. The applet will ignore messages from the browser attempting to invoke any of these methods that you don't use. A Simple AppletThe following complete applet displays "Hello, World Wide Web!" in your browser window: import java.applet.Applet; import java.awt.Graphics; public class TrivialApplet extends Applet { public void paint(Graphics g) { // display a string at 20,20 // where 0,0 is the upper-left corner g.drawString("Hello, World Wide Web!",20,20); } } An appletviewer may be used instead of a WWW browser to test applets. For example, the output of TrivialApplet on an appletviewer looks like:
HTML/Applet InterfaceThe HTML applet tag is similar to the HTML img tag, and has the form: <applet code=AppletName.class width=w height=h> [parameters] </applet> where the optional parameters are a list of parameter definitions of the form: <param name=n value=v> An example tag with parameter definitions is: <applet code=AppletName.class width=300 height=200> <param name=p1 value=34> <param name=p2 value="test"> </applet> where p1 and p2 are user-defined parameters. The code, width, and height parameters are mandatory. Parameters codebase, alt, archives, align, vspace, and hspace are optional within the <applet> tag itself. Your applet can access any of these parameters by calling: Applet.getParameter("p") which returns the String value of the parameter. For example, the applet: import java.applet.Applet; public class ParamTest extends Applet { public void init() { System.out.println("width is " + getParameter("width")); System.out.println("p1 is " + getParameter("p1")); System.out.println("p2 is " + getParameter("p2")); } } prints the following to standard output: width is 300 p1 is 34 p2 is test
Magercise
CommentsJava comments are the same as C++ comments, i.e., /* C-style block comments */ where all text between the opening /* and closing */ is ignored, and // C++ style single-line comments where all text from the opening // to the end of the line is ignored. Note that these two comments can make a very useful combination. C-style comments (/* ... */) cannot be nested, but can contain C++ style comments. This leads to the interesting observation that if you always use C++-style comments (// ...), you can easily comment out a section of code by surrounding it with C-style comments. So try to use C++ style comments for your "normal" code commentary, and reserve C-style comments for commenting out sections of code. The Java language also has a document comment /** document comment */ that is used by the javadoc program to generate documentation from your source code. For example, /** This class does blah blah blah */ class Blah { /** This method does nothing */ /** * This is a multiple line comment. * The leading * is not placed in documentation. */ public void nothing() {;} } DeclarationsA Java variable may refer to an object, an array, or an item of primitive type. Variables are defined using the following simple syntax: TypeName variableName; For example, int a; // defines an integer int[] b; // defines a reference to array of ints Vector v; // reference to a Vector object Primitive TypesThe Java language has the following primitive types:
Primitive Types
Java int types may not be used as boolean types and are always signed. ObjectsA simple C++ object or C struct definition such as "Button b;" allocates memory on the stack for a Button object and makes b refer to it. By contrast, you must specifically instantiate Java objects with the new operator. For example, // Java code void foo() { // define a reference to a Button; init to null Button b; // allocate space for a Button, b points to it b = new Button("OK"); int i = 2; } ![]() As the accompanying figure shows, this code places a reference b to the Button object on the stack and allocates memory for the new object on the heap. The equivalent C++ and C statements that would allocate memory on the heap would be: // C++ code Button *b= NULL; // declare a new Button pointer b = new Button("OK"); // point it to a new Button /* C code */ Button *b= NULL; /* declare a new Button pointer */ b = calloc(1, sizeof(Button)); /* allocate space for a Button */ init(b, "OK"); /* something like this to init b */ All Java objects reside on the heap; there are no objects stored on the stack. Storing objects on the heap does not cause potential memory leakage problems because of garbage collection. Each Java primitive type has an equivalent object type, e.g., Integer, Byte, Float, Double. These primitive types are provided in addition to object types purely for efficiency. An int is much more efficient than an Integer. StringsJava string literals look the same as those in C/C++, but Java strings are real objects, not pointers to memory. Java strings may or may not be null-terminated. Every string literal such as "a string literal" is interpreted by the Java compiler as new String("a string literal") Java strings are constant in length and content. For variable-length strings, use StringBuffer objects. Strings may be concatenated by using the plus operator: String s = "one" + "two"; // s == "onetwo" You may concatenate any object to a string. You use the toString() method to convert objects to a String, and primitive types are converted by the compiler. For example, String s = "1+1=" + 2; // s == "1+1=2" The length of a string may be obtained with String method length(); e.g., "abc".length() has the value 3. To convert an int to a String, use: String s = String.valueOf(4); To convert a String to an int, use: int a = Integer.parseInt("4");
Magercise
Array ObjectsIn C and C++, arrays are pointers to data in memory. Java arrays are objects that know the number and type of their elements. The first element is index 0, as in C/C++.
The syntax for creating an array object is: TypeName[] variableName; This declaration defines the array object--it does not allocate memory for the array object nor does it allocate the elements of the array In addition, you may not specify a size within the square brackets. To allocate an array, use the new operator int[] a = new int[5]; // Java code: make array of 5 ints
In C or C++, by contrast, you would write either int a[5]; /* C/C++ code: make array of 5 ints on the stack */ or int *a = new int[5]; /* C/C++ code: make array of 5 ints on the heap */ An array of Java objects such as // Java code: make array of 5 references to Buttons Button[] a = new Button[5]; creates the array object itself, but not the elements:
You must use the new operator to create the elements: a[0] = new Button("OK"); a[3] = new Button("QUIT"); In C++, to make an array of pointers to objects you would write: // C++: make an array of 5 pointers to Buttons Button **a = new Button *[5]; // Create the array a[0] = new Button("OK"); // create two new buttons a[3] = new Button("QUIT"); In C, code for the same task would look like: /* C: make an array of 5 pointers to structs */ Button **a = calloc(5, sizeof(Button *)); /* Allocate the array */ a[0] = calloc(1, sizeof(Button)); /* Allocate one button */ setTitle(a[0], "OK"); /* Init the first button */ a[3] = calloc(1, sizeof(Button)); /* Allocate another button */ setTitle(a[3], "QUIT"); /* Init the second button */ Multi-dimensional Java arrays are created by making arrays of arrays, just as in C/C++. For example, T[][] t = new T[10][5]; makes a five-element array of ten arrays of references to objects of type T. This statement does not allocate memory for any T objects. Accessing an undefined array element causes a run-time exception called ArrayIndexOutOfBoundsException. Accessing a defined array element that has not yet been assigned to an object resuls in a run-time NullPointerException.
Magercise
InitializersVariables may be initialized as follows:
ConstantsVariables modified by the static final keywords are constants (equivalent to the const keyword in C++; no equivalent in C). For example, // same as "const int version=1;" in C++ static final int version = 1; static final String Owner = "Terence"; ExpressionsMost Java expressions are similar to those in C/C++.
Constant Expressions
General Expressions
OperatorsThe Java language has added the >>> zero-extend right-shift operator to the set of C++ operators. (C++ operators include instanceof and new, which are not present in C. Note that sizeof has been removed, as memory allocation is handled for you.) The operators are, in order of highest to lowest priority:
Note that the precedence of the new operator and the '.' operator bind differently than in C++. A proper Java statement is: // Java code new T().method(); In C++, you would use: // C++ code (new T)->method(); StatementsJava statements are similar to those in C/C++ as the following table shows.
Forms of Common Statements
The Java break and continue statements may have labels. These labels refer to the specific loop that the break or continue apply to. (Each loop can be preceded by a label.) Java SemanticsWe say that the Java language has "reference semantics" and C/C++ have "copy semantics". This means that Java objects are passed to methods by reference in Java, while objects are passed by value in C/C++. Java primitive types, however, are not treated in the same way as Java objects. Primitive types are assigned, compared, and passed as arguments using copy semantics, just as in C/C++. For example, i=j for two int variables i and j performs a 32-bit integer copy. Assignment of ObjectsAssignment makes two variables refer to the same object. For example, class Data { public int data = 0; public Data(int d) { data = d; } } I Data a = new Data(1); // a.data is 1 I Data b = new Data(2); // b.data is 2 II b = a; // b.data and a.data are 1 III a.data = 3; // b.data and a.data are 3 IV a = new Data(4); // b.data is 3 and a.data is 4 ![]() To copy objects, define and use clone(): class Data implements Cloneable { public int data = 0; public Data(int d) { data = d; } public Object clone() { Data d = (Data) super.clone(); d.data = data; return d; } } ... Data a = new Data(1); // a.data is 1 Data b = new Data(2); // b.data is 2 b = a.clone(); // b.data and a.data are 1 a.data = 3; // b.data is 1, a.data is 3 Method Parameters and Return ValuesArguments and return values for primitive types are passed by value to and from all Java methods because they are implied assignments, as in C/C++. However, all Java objects are passed by reference. For example, the C/C++ code: // C++ code int foo(int j) { return j+34;} Button *bfoo(Button *b) { if ( b != NULL ) return b; else return new Button(); } or, in C /* C code */ int foo(int j) { return j+34;} Button *bfoo(Button *b) { if ( b != NULL ) return b; else return calloc(sizeof(Button)); } would be written in the Java language: // Java code int foo(int j) { return j+34;} Button bfoo(Button b) { if ( b != null ) return b; else return new Button("Ok"); } EqualityTwo Java primitive types are equal (using the == operator) when they have the same value (e.g., "3==3"). However, two object variables are equal if and only if they refer to the same instantiated object--a "shallow" comparison. For example, void test() { Data a = new Data(1); Data b = new Data(2); Data c = new Data(1); // a==b is FALSE // a==c is FALSE (in C++, this'd be TRUE) Data d = a; Data e = a; // d==e is TRUE, // d,e are referring to same object } To perform a "deep" comparison, the convention is to define a method called equals(). You would rewrite Data as: class Data { public int data = 0; public Data(int d) { data = d; } boolean equals(Data d) { return data == d.data; } } ... Data a = new Data(1); Data b = new Data(1); // a.equals(b) is true!!!!
Magercise
No Pointers!The Java language does not have pointer types nor address arithmetic. Java variables are either primitive types or references to objects. To illustrate the difference between C/C++ and Java semantics, consider the following equivalent code fragments. // C++ code (C code would be similar) Stack *s = new Stack; // point to a new Stack s->push(...); // dereference and access method push() The equivalent Java code is: // Java code Stack s = new Stack(); // internally, consider s to be a (Stack *) s.push(...); // dereference s automatically Garbage CollectionAn automatic garbage collector deallocates memory for objects that are no longer needed by your program, thereby relieving you from the tedious and error-prone task of deallocating your own memory. As a consequence of automatic garbage collection and lack of pointers, a Java object is either null or valid--there is no way to refer to an invalid or stale object (one that has been deallocated). To illustrate the effect of a garbage collector, consider the following C++ function that allocates 1000 objects on the heap via the new operator (a similar C function would allocate memory using calloc/malloc): // C++ code void f() { T *t; for (int i=1; i<=1000; i++) { t = new T; // ack!!!!! } } Every time the loop body is executed, a new instance of class T is instantiated, and t is pointed to it. But what happens to the instance that t used to point to? It's still allocated, but nothing points to it and therefore it's inaccessible. Memory in this state is referred to as "leaked" memory. In the Java language, memory leaks are not an issue. The following Java method causes no ill effects: // Java code void f() { T t; for (int i=1; i<=1000; i++) { t = new T(); } } In Java, each time t is assigned a new reference, the old reference is now available for garbage collection. Note that it isn't immediately freed; it remains allocated until the garbage collector thread is next executed and notices that it can be freed. Put simply, automatic garbage collection reduces programming effort, programming errors, and program complexity.
Magercises
|
Copyright © 1996-1997 MageLang Institute. All Rights Reserved. |