These notes present the basics of Java in outline form. They only discuss the ways in which Java differs from C++. If something is not discussed, such as for loops, if-then-else statements, or constructors, it is because they are identical in both C++ and Java.
I. Java's built-in types 1. boolean -- true/false 2. byte -- 8 bit integer 3. char -- character 4. double -- double precision floating point number 5. float -- single precision floating point number 6. int -- integer 7. long -- long integer 8. short -- short integer II. The String class--String is a built-in class that replaces C++'s char * strings A. Strings are immutable--once they are created, their contents cannot be changed Example: String a = "Hello"; a = a.concat(" World"); In this example, the concatenation operation creates a completely new string to hold "Hello World" and then makes a point to the new string. The old string object remains unaltered with its contents still being "Hello". Since no other variables point to it, it is eventually garbage collected. B. Strings should be compared using a string's equals method. Example: String token; String day = "Wednesday"; ... if (token.equals("+")) ... else if (token.equals(day)) ... C. Use a StringBuffer object if you want to modify/edit a string III. Scope rules 1. A variable may be declared within a. a class b. a method c. a block 2. A variable may not be declared anywhere outside a class (i.e., there are no global variables in Java) 3. A variable that is declared within a block cannot have the same name as a variable in an enclosing block or method. This rule is different from C/C++ where a variable may have any name when it is declared within a block. Example: The following code will cause the Java compiler to generate an error message because j is declared both in the body of the method and in the body of the for loop: int countPositive(int [] a) { int count = 0; int i, j; for (i = 0; i < a.length; i++) { int j = a[i]; if (j > 0) count++; } j = a.length - count; System.out.println("number of negatives = " + j); return count; } IV. Arrays: They are objects, not primitive types 1. Must be explicitly allocated using the new operator 2. The declaration uses empty brackets since the size of the array is not known until it is allocated. a. The brackets can be either after the type name or after the variable name e.g., int a []; int [] b; int c [] = new int[6]; int [] d = new int[10]; b. You can also provide a set of items to initialize an array, in which case new is not required: String weekdays [] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; 3. The length field returns the number of elements e.g., System.out.println(c.length) will print 6 4. Multi-dimensional arrays are arrays of arrays e.g., int a [][] = new int[4][5]; int b [][] = new int[4][]; b[0] = new int[5]; b[1] = new int[4]; ... V. Type conversions 1. Java automatically performs a type conversion if the conversion does not entail a loss of precision. For example, Java will convert an int to a double: int a; double b; b = a; // okay because there is no loss of precision 2. Java will generate an error message if the type conversion would entail a loss of precision: a = b; // not okay because the fractional portion will be lost when // b's value is assigned to a a. In C++ such a conversion will only generate a warning message 3. The programmer may explicitly downcast (also called narrowing) one type to a less precise type, in which case Java will perform a pre-defined narrowing operation: a = (int) b; // okay. Java will truncate the fractional part of b's // value and assign it to a VI. Classes A. Variables whose types are classes cannot be allocated on the stack. In other words, Java does not allow value objects. All objects are allocated from the heap by calling new. 1. Java does not have a concept of pointers. When you create an object and assign the result to a variable, Java does indeed assign a pointer to the object to the variable, but you do not have access to the pointer like you do in C++ (e.g., in C++ you can increment or decrement a pointer). 2. All member accesses are performed via the dot (.) operator 3. When an assignment statement such as a = b is executed, a is made to point to the same object to which b points. If a modifies a member of this object, then b will also appear to change. For example: Stack a; Stack b = new Stack(); b.push(3); a = b; a.push(5); // b's stack now contains both 3 and 5 a. this treatment is different than in C++ where a would receive a copy of b's object because a and b would both be value objects. In C++, a's stack would contain 3 and 5 after the push operation but b's stack would only contain 3. 4. The == operator compares pointers, not the contents of two objects. We say that the == operator performs a shallow comparison, rather than a deep comparison. This comparision of pointers is why you need to use a string's equals method to compare the values of two strings. B. Declaration of instance variables in a class: Unlike C++, you may assign a default value to a variable when it is declared. Java will assign this value to the variable before the object's constructor is called. Example: class Stack { int size = 10; int top = 0; ... } To accomplish the same type of initialization in C++ you would have to ensure that every constructor explicitly performed this initialization or called a method that performed this initialization. C. Initialization blocks: You can use an unnamed block, called an initialization block, to perform initialization actions on a class's members, before the constructor is called. 1. If you create an initialization block, then it will also be called when an object is first created 2. The code in the initialization block is executed after the default values are assigned to variables but before the constructor is called 3. Example: class Calender { String daysOfTheWeek [] = new String[7]; { // this is just an example. A better way to initialize // the array would be to list the members when you // declare the array int i; daysOfTheWeek[0] = "Sunday"; daysOfTheWeek[1] = "Monday"; ... daysOfTheWeek[6] = "Saturday"; } D. Static keyword: declares a variable to be a class member. 1. A static variable is essentially a global variable for that class and all instances of that class share its value. 2. There is only one copy of the variable and it is stored with the class rather than with an instance Example: static String color = "red"; E. static blocks: static blocks are similar to initialization blocks but are proceeded by the keyword static 1. they are called when the class is first loaded and can be used to initialize static members 2. this treatment differs from C++ in which a static member must be declared and initialized in a .cpp file as well as being declared in a .h file. F. Finalize method: replaces C++'s destructor and is only needed to release non-Java resources, such as a file handle 1. signature: void finalize() {...} 2. is called by the garbage collector when the object is finally destroyed 3. cannot count on when it will be called because you cannot count on when the object will be garbage collected a. if you need to ensure that a final set of actions is performed on an object, create your own method and then call it when you are ready to release the object b. do not call finalize yourself since it will also get called by the garbage collector. Doing so may cause your program to try to release the same set of resources twice, and the second time you won't own them anymore. Trying to release resources you don't own could create unpredictable results. G. Parameter passing 1. Java uses pass-by-value, not pass-by-reference 2. Can return objects since they're allocated off the heap 3. Passing a reference to an object allows the method to modify the contents of the object. This may seem like a contradiction to the pass-by-value dictum but if you think about it, it makes sense. The reference value (i.e., pointer value) gets copied, and hence the parameter has a pointer to the same object as the argument 4. C++ uses both pass-by-value and pass-by-reference a. Place an ampersand (&) after the type in a parameter declaration to make the parameter a reference parameter: void swap(int &a, int &b) { int temp = a; a = b; b = temp; } actual call: swap(x, y); b. When C++ sees a reference parameter, it passes a pointer to the argument rather than a copy of the argument to the method. i. When you assign a value to a reference parameter, the value is assigned to the argument's memory location, thus modifying the original argument ii. When you access a reference parameter on the right side of an assignment statement, C++ return's the current value at the argument's memory location c. Reference parameters were introduced into C++ to reduce the need to explicitly pass addresses of arguments to methods and to explicitly dereference parameters in methods. Compare how swap must be implement and called using the pass-by-value method as compared to the pass-by-reference method: void swap(*int a, int *b) { int temp = *a; *a = *b; *b = temp; } actual call: swap(&x, &y) As you can see, there are many more opportunities to introduce an error when you have to explicitly take the address of arguments and dereference parameters. d. Unfortunately, in practice reference parameters are confusing to use and the designers of Java decided to do away with them. Note however that because of the way Java copies reference values to parameters, Java really is doing a form of pass-by-reference for objects. H. Nested classes: Classes can be nested inside a Java class just as in C++ 1. A nested class has access to all the members and methods of its enclosing class 2. An instance of a nested class is associated with the instance of the class which creates it. A nested class cannot be created independently of its outer class e.g., class foo { ... public class goo { ... } } foo.goo a = new foo.goo() will fail because a goo can only be created by an instance of a foo a. The java compiler creates a foo$x.class for goo where x is a number I. Final keyword: Java's way of creating a constant 1. Memory for the final keyword is shared by all instances so you do not have to declare them static. VII. Inheritance A. You create a subclass using the extend keyword B. Access Modifiers 1. public 2. protected 3. private C. Constructors 1. use super to call the superclass constructor 2. super must be the first statement in a constructor 3. if super is omitted then the superclass's default 0-argument constructor is called 4. constructors are called in order of derivation, from superclass to subclass 5. super can be used to access any member of a superclass. It is commonly used to access the superclass's method when you are overriding it in the subclass. D. All methods are virtual by default 1. Use the final keyword to prevent a method from being overridden 2. abstract methods with no method body can be created by prefixing the method name with the abstract keyword 3. classes that contain abstract methods must be declared abstract themselves a. subclasses must be declared abstract if they fail to define an abstract method that they inherit from an abstract superclass E. Object class: Implicit superclass for any class that is not defined to extend another class--all objects can be cast to Object