6 Weeks in Review

This is only the beginning of our sixth week of Java and Object-Oriented Programming, but we have already covered a lot of ground. Today's lesson is going to review the ealier topics. Most of it will hopefully make more sense now that you have better context for understanding it.

Comparing Java to C

By now you have had several weeks of experience in Java. You should have some feel for how it compares to C in terms of:

We have not run a side-by-side speed test of the two languages, however most people generally agree that Java is faster to develop, but C runs faster.

One of the biggest design mistakes that Software Engineers make is to automatically select the language they are most comfortable with for any project. You should instead pick the one that will meet the requirements for the least cost. That is why it is important to understand each language's relative strengths and weaknesses.

Java compiler

Java Virtual Machine

File name conventions

You should be able to answer any of the following question. Hover the mouse over them to see the correct answers.

Every program in Java requires a class

Every program in Java must have a class. That is a design decision that was made by the developers.

Decades later this decision is still controvertial. Some people say that Java takes OOP a step too far by insisting that it be used everywhere. Other people point out that since every program uses OOP, we do not have to worry about learning two different sets of syntax.

The lesson here? People like to argue. Computer scientists especially. Whether you believe that Java uses too many classes or too few, we need to understand how its classes work. Let's take a closer look at our HelloWorld program:

   1   public class HelloWorld {
   2     public static void main(String[] args) {
   3       System.out.println("Hello, World!");
   4     }
   5   }

This seems like a lot of code to print two words. In reality, it is one line of code to print "Hello, World". The remaining lines (1,2,4,&5) are the minimum lines required for any Java program. Let's break them down one at a time:

Primitive Java variables

"Primitive" types are predefined by the language and identified by named keywords. All primitives except for char "signed". Here are are eight primitives:

Type Size in Bits Min Max
byte 8 -128 127
short 16 -32,768 32,767
int 32 -2,147,483,648 2,147,483,647
long 64 -9,223,372,036,854,775,808 9,223,372,036,854,775,807
float 32 1.40e-45 3.40e+38
double 64 4.94e-342 1.80e+308
boolean Undef. false true
char 2 (unsigned) Unicode 0 Unicode 65,535
Data Type Default Value
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
boolean false
char '\u0000'
Any Object (incl. String) null

Conversion from one primitive variable type to another

Explicit conversion: Casting from one type to another.

Explicit conversions are allowable as long as the user specifies them in a cast statement.

Implicit conversions are allowable whenever there is no possible loss of precision.

Explicit Conversion Examples:

    double d = 1.0d;
    float f = (float)d // Explicit conversion (cast); Allowed by compiler

The following example is an implicit cast that fails:

    double d = 1.0d;
    float f = d // Error: possible loss of precision. Implicit cast fails

The following example is an implicit cast that succeeds:

    float f = 1.0f     // Correct definition for a float
    double d = f;      // Implicit conversion allowed; No possible loss of precision

Note that you use the trailing characters in the right column to indicate the type for a numeral. If you do not, then the numeral will default to a type of int or double:

    float a = 1.0f;    // Correct definition for a float
    float a = 1.0d;    // Error: possible loss of precision; Implicit cast from double to float
    float a = 1.0;     // Error: possible loss of precision; Assumes 1.0 is a double
    float a = 1;       // Implicit cast to float succeeds; Assumes 1 is an int

Note that the user is responsible for ensuring precision is not lost during an explicit conversion.

Strings

Strings are a type of class object specified in java.lang.

Strings are not primitive data objects in Java. Note that the word "String" does not highlight like "int" or "float" in most editors.

The complete definition for class String can be found here

Each character us stored in a 16-bit char.

Strings are immutable - once created, they cannot be changed. Wouldn't it be more useful to have a String that can be modified? There are similar classes that can be modified, such as StringBuffer and StringBuilder.

Reserved Keywords

Reserved keywords cannot be used as variable or method names.

They generally show up as a special color in editors.

Take a look at the following lines. Which ones compile?

      float a = 1.0f;        // Compiles as expected
      float int = 1.0f;      // Does not compile - 'int' is reserved, cannot be used as a variable name
      float String = 1.0f;   // Compiles; 'String' is now a variable of type float with value == 1.0f

Arrays

An array is a collection of Objects or primitives. The size of an array must be specified when it is created:

    int[] intArray1 = new int[10];
    int[] intArray2;
    intArray1[5] = 99;      // Compiles, since intArray1 has a size of 10.
    intArray2[5] = 99;      // Error: intArray2 is a null pointer. Needs a call to 'new' to use a pointer.

The immutable size of Arrays can be a problem. If you need an array whose size changes while the program runs, try the ArrayList.

Arrays can be multi-dimensional:

    int[][] x = new int[10][20];
    int[][][][][] y = new int[10][20][30][40][50];
    x[0][0] = 1;
    y[0][0][0][0][0] = 1;	

Custom Classes

The code below shows you how to create and use a class:

    class Point {
        float x, y;
        public Point(float a, float b) {
            x = a;
            y = b
        }
    }
    ...
    Point p = new Point(1.0f, 2.0f);

A class variable is actually a pointer. It defaults to a value of 'null' unless you create an object with new and point the pointer to it. The following line will fail:

    Point p;
    p.x = 3.0f;    // p is a null pointer. There is no Point object allocated.

Pass-by-Value vs. Pass-by-Reference

There are two ways of passing a variable to a method in most languages: by 'Value' and by 'Reference'.

Java always uses 'Pass-by-Value'. But (why is there always an exception?) sometimes methods act like they are Pass-by-Reference.

Primitive data types use 'pass-by-value'. This makes a copy of the data. If the method changes the copy, that does not change the original variable.

Objects also use 'pass-by-value', BUT only the pointer gets passed by value. Since the pointer points to the original data object, a method may modify the original data. However, the method may not change the original pointer.

The result is behavior that sometimes looks like pass-by-reference, and sometimes like pass-by-value. It is easier to understand with an example:

Consider the following code:

   
	public class Point {
		float x, y;
		public Point(float a, float b) {
			x = a;
			y = b;
		}
	}
	...
	public class Pass {
		// Does not change the value of the original int
		public static void testPrimitive(int i) {
			i = 99;
		}
		// Changes the value of the original Point.
		public static void testObject1(Point p) {
			p.x = 99.0f;
		}
		// Does not change the value of the original String
		public static void testObject2(String s) {
			s = "Goodbye";
		}
		public static void main(String[] args) {
			int int1 = 0;
			System.out.println("Before: int1: " + int1);
			testPrimitive(int1);
			System.out.println("After:  int1: " + int1);

			Point point1 = new Point(0,0);
			System.out.println("Before: point1.x: " + point1.x);
			testObject1(point1);
			System.out.println("After:  point1.x: " + point1.x);

			String mystr = "Hello";
			System.out.println("Before: mystr: " + mystr);
			testObject2(mystr);
			System.out.println("After:  mystr: " + mystr);
		}
	}

Here is the output:

	Before: point1.x: 0.0
	After:  point1.x: 99.0
	Before: int1: 0
	After:  int1: 0
	Before: mystr: Hello
	After:  mystr: Hello

The best way to understand this is to compile a few examples and experiment for yourself.

Like ideas in computer science, this one is controversial. Try Googling "Java pass by reference" if you want to read online arguments full of abusive language on this topic.

Format for 6-week exam

This is a three-part exam:

  1. Written portion. Closed book, no electronics. Short answer, multiple-choice, True/False, writing small code examples from scratch with no reference.
  2. Written portion. Closed book, no electronics. Debugging code and modifying code samples.
  3. Practical programming exercise. Using lab workstation. Open book, Internet search engines are available. You can use the Internet, the only restrictions are that you cannot log into any website or service, and you cannot post messages anywhere. This is to prevent communication with programmers or other students. You can browse to any page that does not require a login or password, and you can read any page as long as you do not send any messages.