6 Java Syntax

Until now, I have concentrated on the object-oriented concepts instead of the Java syntax. I have already introduced some of Java’s syntax by way of previous examples. This section will present a more complete definition of Java’s syntax.

Java’s syntax was deliberately based on C++, which was in turn based on C. Therefore, COBOL programmers sometimes have a harder time understanding Java’s syntax than do C and C++ programmers. Harder is not the same as impossible, however, so I expect you to follow along.

COBOL VS. JAVA SYNTAX

COBOL’s syntax has the benefit of being very simple and somewhat like English. As a result, COBOL programs tend to be longer than programs written in other languages but are often more readable. Significantly, COBOL programmers tend to be pretty good typists.

In contrast, Java’s syntax is much more concise. For example, a single statement can contain many expressions. Another good example of this contrast is the assignment function. In COBOL, the syntax is the wordy (but very clear) MOVE xxx TO yyy. In Java, it is simply yyy = xxx.

Both languages are not, strictly speaking, line oriented. They share the concept of a statement that may span more than one line. Most statements in COBOL can end with a period (.). In Java, all statements must end in a semicolon (;).

COBOL uses verbs such as IF, ELSE, and END-IF, both to test a condition and to group statements that should be performed together as a result of that condition. Java uses the first two verbs (if and else) to test conditions but uses the curly braces ({}) to group conditional statements.

Finally, Java’s syntax encourages the liberal use of objects in a program, whereas performing COBOL subroutine calls and using the results properly can be a little confusing. As a result, Java is much better suited to code-reuse strategies.

But let’s not get ahead of ourselves. Instead, I’ll start at the very beginning.

JAVA STATEMENTS

A Java statement is the equivalent of a sentence in COBOL. A statement is the smallest complete building block in a Java program. A statement can define a variable, perform some logic, or define an interface. Every statement must end in a semicolon.

The simplest statement type is the sort that defines a variable. The syntax for defining a variable is as follows:

Image

I’ve already reviewed Java’s access control options and the data types that are available. I’ve also discussed how variables can be assigned initial values when they are first instantiated.

An identifier is any named program component (such as variables, class names, object names, or class members). Similar to a COBOL name, an identifier can be made up from any alphanumeric characters but must start with an alphabetic character. There are a few differences, some as part of the language definition and some that are simply conventions.

  • Java compilers are case sensitive. The identifier MsgSize is not the same as msgSize.

  • The dash (-) character is not valid in a variable name in many contexts and, therefore, is never used in a Java identifier name. By convention, the underscore (_) character is sometimes used to separate the parts of an identifier name; mixed case can be used for the same purpose.

  • By convention, most identifiers are mixed case, and instance identifiers (variables, objects, members, and so on) begin with an initial lowercase. User-defined types, such as classes, often begin with an initial uppercase. Static class variables and members are normally all uppercase.

  • Valid names cannot start with a numeric character.

Here are some examples of valid identifier names, and what they represent, by convention (based on Sun’s coding conventions found at http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html):

msgSize

// an instance identifier

m_ErrorMsg

// an instance identifier, probably an object identifier

ErrorMsg

// a user-defined type, such as a class name

NO_TEXT_FOUND

// a static CLASS variable

Here are some invalid identifier names:

1instanceVariable

// cannot start with nonalpha

another instance variable

// embedded spaces

COBOL-STYLE

// embedded dashes

public

// reserved word

A Java executable statement performs some part of a class’s algorithm (it is similar to a sentence in COBOL’s procedure division). These statements can contain multiple expressions, all of which will be performed as part of the statement.

This is a simple Java expression that declares a String type object:

String inputMsg

Placing a semicolon at the end makes it a complete Java statement:

String inputMsg;

This is a Java expression that performs the method getErrorMsg() in the object myErrorMsg and passes no parameters:

myErrorMsg.getErrorMsg ()

This expression can be combined with an assignment expression in order to return the result into inputMsg:

inputMsg = myErrorMsg.getErrorMsg ()

Placing a semicolon at the end makes it a complete Java statement:

inputMsg = myErrorMsg.getErrorMsg ();

This is a Java statement that compares inputMsg to another String and performs some logic. Since inputMsg is a String, it has a method called equals(), which accepts a String parameter and returns a boolean true or false. The if construct tests the boolean result of this method and performs the statements in the braces if the result is true:

if (inputMsg.equals ("Any Text")) {
    ...
}

Expressions can be combined into more complex Java statements:

String inputMsg = myErrorMsg.getErrorMsg ();

or this statement:

if (myErrorMsg.msgText.equals ("Any Text")) {
    ...
}

JAVA COMMENTS

Java programmers are expected to place comments in the code. Imagine that! To support this, Java allows for the following comment styles:

In the examples so far, you have used the C++ style comments, since they are line oriented, like COBOL comments:

// This member is available to any class.
     public String msgText;

The C style comments are also sometimes used, especially for multiline comments, but here is a word of caution: This style can cause code to be inadvertently commented out.

/* This member is available to any class.
Its access modifier is public */
     public String msgText;
/* All these lines are comment lines.
     public String msgText;
  Let’s hope your editing environment will make this obvious */

I will discuss Javadoc comments in Chapter 12.

Examples in this book generally use the two forward slashes (//) style of comments declaration.

JAVA OPERATORS

Java provides for the usual arithmetic assignment operators. Most of these are similar to the operators available in COBOL’s COMPUTE statement.

*

Multiplication

/

Division

%

Modulo

+

Addition

Subtraction

=

Assignment

As you would expect, there are precedence standards, and parentheses can be used to override or clarify any precedence conventions.

x = 2 + 7 * 3;      // x = 23
x = (2 + 7) * 3;    // x = 27

The order of precedence is important, but if you have to think about it, you are either writing or reading code that will be hard to maintain. Rather than rely on the order of precedence conventions, always make your intentions explicit by using parentheses.

Unlike COBOL, Java always uses arithmetic symbols instead of words for its math operations. For example, the assignment operator is an equals sign (=) instead of MOVE, or x – y instead of COBOL’s SUBTRACT Y FROM X. Math operations in Java always use a syntax similar to COBOL’s COMPUTE verb.

BINARY ARITHMETIC OPERATIONS

Binary operations (that is, operations involving two operators) come in several types: arithmetic, conditional, relational, assignment, and bitwise. You will explore the various arithmetic operations here.

Integer operations always create a result type of int, unless one of the operands is of type long, in which case the result type is long. If x in the preceding example had been defined as a short, then you would have had to cast the result into a short in order to avoid a compiler error.

short x;
x = (short) (2 + 7 * 3);      // x = 23

Likewise, floating-point operations always create a result of type double unless both operands are of type float. Remember that floating-point constants by default are of type double. Further, the compiler can automatically convert either an integer or a float into a double, but converting a double into either of these requires a cast. Similarly, integers will automatically convert to floats, but floats won’t convert to integers unless you cast them.

int i;
float f;
double d;

d = f + 1.2;                  // OK
f = f + 1.2;                  // not good, cast required
f = (float) (f + 1.2);        // OK
f = f + 1.2F;                 // also OK
i = (int) f;                  // OK, but possible precision loss
f = (float) (d + 1.2);        // OK, but possible precision loss
d = f + i;                    // OK

These conventions for managing numbers are easy to remember if you observe this logic:

  • For integer math, the default type is int.

  • For floating-point math, the default type is double.

  • Smaller types can automatically be converted into larger types.

  • Larger types must be cast into smaller types. There is the possibility of data loss.

  • The size order is double, float, int, short, byte.

Java coders often use a shortcut (assignment with operator) to perform simple math operations on a single variable:

x = x + 7;
x += 7;                      // the same statement

This coding style can take a little getting used to, since one of the source operands (the second x) that would be expected in an algebraic expression is missing. The addition operator (+, in the example) is normally placed to the left of the = sign in this type of complex assignment expression. Each of the math operators (*, /, +, and –) can be combined with an assignment expression (e.g., *=, /=, +=, and –=).

Like C and C++, Java provides for increment and decrement operators (++ and --). These provide a convenient mechanism to increment or decrement a variable.

x = 7;
x++;                // x = 8
x--;                // x = 7

These operators come in two types: the postfix (x++) and the prefix (++x). The difference shows up when the auto increment operators are used in an expression. The prefix operator increments or decrements before presenting the value, and the postfix increments or decrements after presenting the value.

x = 7;
y = 2 * x++;        // y = 14, and x = 8
x = 7;
y = 2 * ++x;       // y = 16, and x = 8

As you can see from the examples, there are subtle differences between postfix and prefix increment operators, especially when used as part of an expression. A number of Java language authorities recommend that these operators not be used as part of an expression, but only as standalone statements in order to avoid confusion on this matter.

x = 7;
x++;              // An increment statement with no ambiguity
y = 2 * x;        // y = 16, and x = 8

Table 6.1 lists the operators available in the Java language in the order in which they are evaluated by the compiler.

TABLE 6.1 RESPONSIBILITIES OF CSIRT DURING THE INCIDENT RESPONSE PROCESS

*Java includes a number of bitwise operations and makes some important distinctions between these operations and boolean logical operations. Since COBOL does not have bitwise operations and most business operations do not require them, the reader is encouraged to explore this concept in other sources.

The special case of assignment and equality as applied to object reference variables warrants attention. An object reference variable is just like any other variable in many ways. But remember that it contains a reference to the object and does not contain the object’s values. Therefore, although two different object reference variables can point to different objects with equal values, they are not the same object. The only way that two object reference variables can be equal is if they point to the same object.

Some examples may help clarify this. Recall that the String data type is not really an intrinsic type, but rather, is a class. Therefore, String variable names are actually object reference variables. Consider this example:

String s1 = new String ("Some text");

Often, the following syntax is used instead of the previous declaration:

String s1 = "Some text";

Suppose the program also includes this statement:

String s2 = "Some other text";

Clearly, s1 and s2 are not equivalent, so this test fails, as you would expect.

if (s1 == s2) {
      ...                 // This code would not execute
}

In addition, the following test will also fail, since s1 and s2 do not contain equivalent text:

if (s1.equals (s2)) {
     ...                  // This code will not execute
}

Now, suppose you have two Strings that contain the same text.

String s1 = new String ("Some text");
String s2 = new String ("Some text");
if (s1 == s2) {
                         // This code will not execute
                         // even though the text contained in these
                         // two Strings are equal. s1 and s2 will
                         // point to different String objects
}

Yet the following test always succeeds since the equals() method in the String class compares the value of the String object with the passed String:

if (s1.equals (s2)) {
     ...                 // This code will execute
}

What is the bottom line? Always use the equals() or compareTo() methods when you want to compare two Strings. Never assume that the String reference variables will compare appropriately, based on the text values in the String.

Get ready for the real weirdness. Object reference variables are variables and, therefore, can be assigned values. Normally, this happened only with the new keyword, as in the following:

String s1 = new String ("Some text");
String s2 = new String ("Some other text");

But it is perfectly legal to set object reference s2 equal to s1:

s2 = s1;

Now, both s2 and s1 point to the same object. (As a matter of fact, the object formerly pointed to by s2 could be unreferenced and will likely be garbage collected or deleted by the system at some point.) This time, the equality test, when applied to the values of the Strings, will succeed even though the initial object pointed to by s2 was different from s1:

if (s1.equals (s2)) {
            ...          // This code would execute
}

The same is true of this test, which compares the object references:

if (s1 == s2) {
            ...          // This code would execute since s1 and s2
            ...          // point to the same object.
}

The only way to modify the text associated with Strings s1 or s2 is to point these reference variables to different String objects. This is normally done by performing some method that returns a String object and assigning the reference variable to that String. String objects themselves are immutable. That means String objects themselves cannot be changed; only the reference variables that point to a String can be changed. For example, if you need another String value in s1, you must create a new String, and point s1 to it.

     String s1 = new String ("Some text");
     String s2 = new String ("Some other text");
// Assign s2 to a new String object.
// This object is the result of the trim() method, which removes leading
//  and trailing spaces.
// String s1 contains no leading or trailing spaces, so the String object
//  returned from trim() will contain the same text as String s1.
     s2 = s1.trim();
     if (s1.equals (s2){
// This code would execute since s1 and s2 contain the same text.
     }

UNDERSTANDING REFERENCE VARIABLES WITH COBOL

It may be useful to revisit the COBOL example to help explain this concept. Recall that the CALLER program defined two instances of MYSUB-CONTROL, as follows:

01 MYSUB1-CONTROL.
      03   MYSUB1-ACTION-SWITCH             PIC X.
           88 MYSUB1-ACTION-INITIALIZE       VALUE "I".
           88 MYSUB1-ACTION-EVALUATE         VALUE "E".
           88 MYSUB1-ACTION-SET-AND-EVALUATE VALUE "S".
           88 MYSUB1-ACTION-GET-CALL-COUNTER VALUE "G".
      03   MSG-TEXT                         PIC X(20).
      03   MSG-SIZE                         PIC 9(8).
      03   MYSUB1-RETURNED-CALL-COUNTER     PIC 9(10).
      03   MYSUB1-PRIVATE-ITEMS             PIC X(20).

01 MYSUB2-CONTROL.
      03  MYSUB2-ACTION-SWITCH             PIC X.
          88 MYSUB2-ACTION-INITIALIZE       VALUE "I".
          88 MYSUB2-ACTION-EVALUATE         VALUE "E".
          88 MYSUB2-ACTION-SET-AND-EVALUATE VALUE "S".
          88 MYSUB2-ACTION-GET-CALL-COUNTER VALUE "G".
      03  MSG-TEXT                         PIC X(20).
      03  MSG-SIZE                         PIC 9(8).
      03  MYSUB2-RETURNED-CALL-COUNTER     PIC 9(10).
      03  MYSUB2-PRIVATE-ITEMS             PIC X(20).

Suppose that the MSG-TEXT items in both MYSUBx-CONTROL areas contained the same text (“Some Text,” for example). In this case, this COBOL code would display a message:

IF MSG-TEXT OF MYSUB1-CONTROL = MSG-TEXT OF MYSUB2-CONTROL
     DISPLAY "MSG-TEXT's are equal".

However, this COBOL code may or may not display a message, depending on the value of the other items in the MYSUBx-CONTROL areas:

IF MYSUB1-CONTROL = MYSUB2-CONTROL
     DISPLAY "MYSUBx-CONTROL's are equal".

When you compare object reference variables (including a String object reference variable) with the == Java operator, it is as if you are comparing two CONTROL areas in COBOL. In order to compare the MSG-TEXT items in the CONTROL areas, you must explicitly compare just those items. Likewise, in order to compare text in a Java String, you must use the equals() method and not compare the object reference variables.

EXERCISES: JAVAS SYNTAX

It’s time to visit the example classes again and try out all these new ideas.

  1. Edit the HelloWorld.java source file in your java4cobol directory with a text editor. You’ll start by deleting the code that experimented with inheritance. Remove the lines after this statement (but remember to leave in the two curly braces at the end of the program):

    // Print the contents of ErrorMsg's String data member directly.
              System.out.println (myErrorMsg.msgText);

  2. Add these Java expressions at the end of the previous statement (before the last two curly braces):

    // Experiment with Java statements.
              String testMsg
              myErrorMsg.getErrorMsg ()

  3. Save these modifications as a text file, and then compile the class in the DOS command window:

    →   javac HelloWorld.java

    You should get an error message indicating that a semicolon is missing.

    Add a semicolon to the end of each of these expressions. Compile this class again. It should now compile successfully.

  4. These two statements simply define a String variable, and execute the getErrorMsg() method in the ErrorMsg class. As written, they are not very useful, since you end up with an empty String variable, and the result of this effort is lost. Add this additional bolded Java code to the statements, making them more useful:

    // Experiment with Java statements.
              String testMsg;
              testMsg = myErrorMsg.getErrorMsg ();

    Compile this class again.

  5. Combine these two statements into one, as follows:

    // Experiment with Java statements.
              String testMsg = myErrorMsg.getErrorMsg ();

    Compile this class again.

  6. Next, you’ll adjust the original statement and make it more complex. Although you are using the if statement in this code (and I won’t explore it in detail until the next chapter), you should be able to follow it fairly easily. Add this additional bolded Java code:

    // Experiment with Java statements.
              String testMsg = myErrorMsg.getErrorMsg ();
              if (myErrorMsg.getErrorMsg ().equals (testMsg)) {
                 System.out.println ("testMsg = ErrorMsg text");
              }

  7. Save, compile, and rerun the HelloWorld application.

    →  javac HelloWorld.java
    →  java HelloWorld

    The output should look like this:

    ...
    testMsg = ErrorMsg text

  8. Next, add this additional bolded Java code:

    // Experiment with Java statements.
              String testMsg = myErrorMsg.getErrorMsg ();
              if (myErrorMsg.getErrorMsg ().equals (testMsg)) {
    // Define a temporary integer variable.
            int i = 5;
              System.out.println ("testMsg = ErrorMsg text");
                  System.out.println ("i = " + i);
               }

  9. Compile and rerun the HelloWorld application. The output should look like this:

    ...
    testMsg = ErrorMsg text
    i = 5

  10. Next, you’ll explore how parentheses can modify the results of a statement. Using a text editor, add these bolded lines to the end of your HelloWorld.java source file.

    int x, y, z;
    x = 3;
    y = 4;

    z = x + 1 * 2;
    System.out.println ("z = " + z);

    Compile and rerun the HelloWorld application. The output should look like this:

    ...
    testMsg = ErrorMsg.text
    i = 5
    z = 5

  11. Add the parentheses as indicated here.

    z = (x + 1) * 2;
    System.out.println ("z = " + z);

    Compile and rerun the HelloWorld application. As you would expect, the value of z is different. The output should look like this:

    testMsg = ErrorMsg text
    i = 5
    z = 8

  12. You’ll explore how to use the Java operators to control evaluations. Add these bolded lines to the end of your HelloWorld java source file:

    // Experiment with operators
              if (((x == y) || (z < x)) && ((z != y) || (x >= 1))) {
                   System.out.println ("Condition is true");
              }
              else {
                   System.out.println ("Condition is not true");
              }

    Compile and rerun the HelloWorld application. The output should look like this:

    ...
    testMsg = ErrorMsg text
    i = 5
    z = 8
    Condition is not true

    Compare the previous Java statements to this COBOL sentence:

    IF  (((X = Y) OR (Z < X)) AND
        ((Z NOT = Y) OR (X NOT < 1)))
        DISPLAY "Condition is true"
    ELSE
        DISPLAY "Condition is not true".

    Notice the liberal use of parentheses in the Java example and the use of curly braces around the if and else code blocks, even though these constructs may not be strictly required.

    What Java operator can you reverse in order to make the “Condition is true” message appear?

  13. I’ll experiment a bit with additional data types. Add these bolded lines to the end of your HelloWorld class:

    // Experiment with additional data types.
    // These data types are automatically converted to the double data type
    // during the comparison.
              double d = 4;
              float f = 4;
              short s = 4;
              if ((d == y) && (d == f) && (d == s)) {
                   System.out.println ("Condition is true");
              }
              else {
                   System.out.println ("Condition is not true");
              }

    Compile and rerun the HelloWorld application. The output should look like this:

    ...
    testMsg = ErrorMsg text
    i = 5
    z = 8
    Condition is not true
    Condition is true

  14. Try a test involving overflow of integer values. Add these bolded lines to the end of your HelloWorld class:

    // Experiment with overflow.
              d *= 536870912;
              y *= 536870912;
              if (d == y) {
                   System.out.println ("Condition is true");
              }
              else {
                   System.out.println ("Condition is not true. d = " + d
                       + " y = " + y);
              }

    Compile and rerun the HelloWorld application. The output should look like this:

    ...
    testMsg = ErrorMsg text
    i = 5
    z = 8
    Condition is not true
    Condition is true
    Condition is not true. d = 2.147483648E9 y = -2147483648

    Java specifies that integer multiplication will not cause an error condition (exception) even if overflow occurs, so be careful with large integer numbers. Notice the way d is printed. Java double numbers are stored in IEEE 754 format, and this is a String representation of this format.

REVIEWING THE EXERCISES

Image

Let’s review the samples you’ve created. Try to relate the sample source statements to the result (that is, the output) each statement creates. If necessary, rerun the samples, or look at the complete source code for this exercise on the CD-ROM. Feel free to experiment by yourself.

  • Java statements must end with a semicolon. A single statement can contain several Java expressions.

  • Java uses parentheses to group expressions in much the same way that COBOL does. Java’s AND, OR, and NOT operators (&&, ||, !) work in much the same way as do their COBOL counterparts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset