CS 621 Session 3

(Chapter 3 in Van der Linden's book)

Identifiers, Keywords and Types

Java uses  Unicode  for representing characters internally. It is possible to represent a Unicode character directly by using \uxxxx.
This will make it easier to write international versions of software.

Identifiers can be any length in Java. They must start with a letter, underscore or dollar sign.
Non-ascii characters can be used in names, for instance:
 miáéíóúña

There are two types of comments
 /*
  Comments as in C
 */
or
 // Comments as in C++

There is also javadoc, the tool that was mentioned previously that works in conjunction with the compiler to produce web pages that document a particular project.
Comments of the form
 /**
    *
    */
are extracted by javadoc and associated with the closest class, attribute or method that follows.

The keywords in Java can be classified by their use:
 

The primitive types

 

Name Range of values Purpose
boolean false, true
int -2,147,483,648 to 2,147,483,647 4-byte integers - 32 bits
long -263  to 263-1 8-byte integers - 64 bits
byte -128 to 127 1-byte integers - 8 bits
short -32,768 to 32,767 2-byte integers - 16 bits
double -1.7E308 to 1.7E308 14-15 figures of accuracy 64-bits floating point numbers - IEEE 754 standard
float -3.4E38 to 3.4E38 6-7 figures of accuracy 32-bits floating point numbers - IEEE 754 standard
char Unicode values between 0 and 65,535 Unicode characters 'a' (single quotes)

Strings


String is a standard Java class. It is easier to use than the arrays of characters terminated with '\0' used in C.

A string literal is surrounded by double quotes "This is a string.".

A String is an object.

Strings can be instantiated in two different ways:
 String cat = new String("Garfield");
or one can use this shortcut:
 String cat = "Garfield";

Strings can be concatenated by using the + operator (this is called operator overloading, the operator is used for an additional purpose).

The Object class has a toString() method. Everything is derived from Object, so any class will have a method toString() available. The regular version of toString() is not very friendly, but it is possible to override it when one writes a class.

If one needs to compare two strings, it is better to use the equals method available in String.
  if  (s1.equals(s2))
            ...
It is possible to find the length of a String by using the method length()

(Chapter 5 in Van der Linden´s book)
 

Names

An identifier is just a sequence of letters and digits that don't match a keyword or the literals "true", "false" or "null".
A name can be prefixed with any number of further identifiers to pinpoint the name space from which it comes.
An identifier is the simplest form of a name.

The general case of a name would be:
 package1.package2.packageN.Class1.Class2.ClassM.memberN

For example:
 java.lang.System.out.println("Hello world!");

java contains several packages.
java.lang is one of those packages.
java.lang.System is a class in the java.lang package.
java.lang.System contains a field called out, an object of the class PrintStream.
println is a method of the class PrintStream.

Using these prefixes will allows us to distinguish among several identifiers or methods with the same name from different packages.

Java accepts the same name for a method, an attribute or a label. They are kept in separate name spaces.
It is a common custom in the OOP community to use verbs for methods, nouns that start with lower case for attributes (variables) or instances and nouns that start with upper case for Classes.

It is possible to forward reference an identifier in Java.
Example:
    class Fruit {
        void foo() { grams = 22; } // grams not declared yet
        int grams;
    }
 

Expressions in Java

 

 
Expression Example
a literal 245
this object reference this
a field access banana.grams
a method call banana.getName()
an object creation new Fruit("Kiwi",10)
an array creation new int [29]
an array access myArray[i][j]
any expression connected by operators banana.grams * 1000
any expression in parenthesis ( banana.grams * 1000 )

The evaluation of an expression will yield:

An expression can appear on the left or the right side of an assignment. The left side of an assignment indicates where the right side of the assignment will be stored.

Java is a strong typed language. The type of an expression will be evaluated either at compile time or at run time.

Arrays


Arrays are objects in Java. Array types are reference types in Java, an array variables is really a a reference to an array.

The subscripts always start at zero.

Array indexes are checked at runtime. If a subscript tries to access an element outside the bounds of its array, it causes an exception.

Arrays are allocated with the "new" operator. They are allocated on the heap, never on the stack.

One of the attributes of an array is its length. So it is possible to access it:
 a.length

When declaring an array, one does not specify its size:
 int carrot [];

Before one references an entry in this array, one should create the array with new or make it point to an existing array.

Depending on the kind of elements that will be stored in the array, one may obtain

Examples:
carrot = new int [256]; // creates 256 int
carrot[11] = 29;           // valid

or

Vegetable carrot[] = new Vegetable[256]; // Creates 256 references to Vegetables
carrot[11].grams = 32;                              // Invalid, carrot[11] contains null at this time. A null pointer exception occurs

To be able to use the array carrots, one needs to allocate objects for each of the references:

for(int i=0;i<carrot.length;i++)
{
    carrot[i] = new Fruit();
}
 

Initializing an Array:


It is possible to create an initialize an array at the same time:
Examples:
    byte b[] = {0, 1, 2, 3, 4};
    String wkdays[] = new String[] {"Mon","Tue","Wed","Thu","Fri"};

Arrays of Arrays

Java has arrays of arrays.
They are declared in this way:
    int matrix [] [];
Again, it is necessary to use new to allocate them:
    matrix = new int [rows][columns];

It is possible to use initialization with multidimensional arrays.
Example:
    int smallMat [][] = new int [] [] { {0, 1, 2},
                                                      {3, 4, 5},
                                                      {6, 7, 8}};

In declarations, the brackets can be placed before or after the name of the array:
Example:
 int a [];
 int [] b;
Both forms are valid.

This flexibility is useful when one is declaring a method that is returning an array.

    int [] myMethod ()   // We state that myMethod returns an array of integers
    {
        return new int[10];
    }

Because arrays are objects, they are never allocated in the stack. They are allocated from the heap.

Operators

Operations are evaluated left-to-right
 
Symbol Operation Precedence 
Highest number -> highest precedence
Associativity
++ -- pre-increment, pre-decrement 16 right
++ -- post-increment, post-decrement 15 left
~ flip the bits of an integer 14 right
! logical not (reverse a boolean) 14 right
- + arithmetic negation, plus 14 right
(typename) type conversion 13 right
* / % multiplicative operators 12 left
- + additive operators 11 left
<< >> >>> left and right bitwise shift 10 left
instanceof < <= 
> >=
relational operators 9 left
== != equality operators 8 left
& bitwise and 7 left
^ bitwise exclusive or 6 left
| bitwise inclusive or 5 left
&& conditional and 4 left
|| conditional or 3 left
? : conditional operator 2 right
= *= /= %= += -=
<<= >>= >>>=
&= ^= |=
assignment operators 1 right

Precedence says that some operations bind more tightly than others:
Given a + b * c
The multiplication will be performed before the addition, because multiplication has a higher precedence than addition.

Associativity is the tie breaker for deciding the binding when we have several operators of equal precedence.
Given a * b * c
How should this be interpreted?
Because multiplication has left associativity, it should be interpreted as (a*b)*c