Chapter1 Java Basics
Introduction to Java¶
For C and C++ learners
In my opinion, Java's basic rules are kind of similar to C and C++
Basic Rules¶
- All code in Java must be part of a class. Every Java file must contain a class declaration, all code lives inside a class, even helper functions, global constants, etc.
- We delimit the beginning and end of segments of code with
{}
- All statements in Java must end in a semi-colon(分号)
- For code to run we need
public static void main()
- Before Java variables can be used, they must be declared
- Java variables must have a specific type
- Java variable types can never change
- In Java, types are verified before the code runs! If there are type issues, the code will not compile
Tip
Java has an important features——Static Typing, which gives us a number of important of advantages over languages without static typing:
- Types are checked before the program is even run, allowing developers to catch type errors with ease
- If we write a program and distribute the compiled version, it is guaranteed to be free of any type errors, which makes our code more reliable
- Every variable, parameter, and function has a declared type, making it easier for a programmer to understand and reason about the code
Functions¶
- To declare a function in Java, use
pblic static
(which is similar todef
in Python, but we still need a return type in Java) - All parameters of a function must have a type, and the function itself must have a return type, like
public static int larger(int x,int y)
- All functions must be part of a class, In programming language terminology(术语), a function that is part of a class is called a "method", so all functions in Java are methods
Compilation¶
to run Hello.java
, we'd type the command javac Hello.java
into the terminal, which asks the compiler to compile and generates a file Hello.class
, then we type the command java Hello
for interpreting
Using and Defining Classes¶
Defining and Instantiating Classes¶
Classes can be instantiated, and instances can hold data.
Some key observations and terminology:
- An object in Java is an instance of any class.
- class has its own variables, also known as instance variables or non-static variables. These must be declared inside the class.
- For the method in class which do not have the
static
keyword, we call it instance methods or non-static methods - Members of a class are accessed using dot(
.
) notation
Static vs. Non-Static¶
-
Instance methods, a.k.a. non-static methods
-
Class methods, a.k.a. static methods
Instance methods are actions that can be taken only by a specific instance of a class. Static methods are actions that are taken by the class itself.
The key differences between static and non-static methods are as follows:
- Static methods are invoked(调用) using the class name
- Instance methods are invoked using an instance name
- Static methods can't access "my" instance variables
- Static members are accessed using class name
- Non-static members cannot be invoked using class name
- Static methods must access instance variables via a specific instance
Tip
this
in Java is similar to this
pointer in C++. The most significant difference is that this
in Java is a reference but not pointer(There is no pointer in Java). So if we want to access members or methods using this
, we should use dot notation but not ->
Testing¶
We'll discuss how we can write tests to evaluate code correctness in this lecture. Along the way, we'll also discuss an algorithm for sorting called Selection Sort.
As a totally new way of thinking, we'll start by writing testSort()
first, and only after we've finished the test, we'll move on to writing the actual sorting code.
Ad Hoc Testing¶
To write a test for Sort.sort
, we simply need to create an input, call sort
, and check whether the output of the method is correct. If not, we print out the first mismatch and terminate(终止) the test. For instance, we might create a test class as follows:
public class TestSort{
public static void testSort(){
String[] input = {"i", "have", "an", "egg"};
String[] expected = {"an", "egg", "have", "i"};
Sort.sort(input);
for (int i = 0; i < input.length; i += 1) {
if (!input[i].equals(expected[i])) {
System.out.println("Mismatch in position " + i + ", expected: " + expected + ", but got: " + input[i] + ".");
break;
}
}
}
public static void main(String[] args) {
testSort();
}
}
注意
When we test for equality of two objects, we cannot simply use the ==
operator. The ==
operator compares the literal bits in the memory boxes, in other words, the address.
An annoying fact is that writing such ad hoc tests would be very tedious, as we may write a bunch of different loops and print statements. So in the next section, we'll see how the org.junit
library saves us a lot of work.
JUnit Testing¶
The org.junit
library provides a number of helpful methods and useful capabilities for simplifying the writing of tests. For example, we can replace our simple ad hoc test from above with:
public static void testSort(){
String[] input = {"i", "have", "an", "egg"};
String[] expected = {"an","egg","have","i"};
Sort.sort(input);
org.junit.Assert.assertArrayEquals(expected,input);
}
The code is much simpler and does the same thing.
Selection Sort¶
Selection sort consists of three steps:
- Find the smallest item
- Move it to the front(by swapping)
- Selection sort the remaining N-1 items(without touching the front item), similar to recursive to some extent
References and Recursion¶
Primitive Types¶
There are 8 primitive types in Java: byte, short, int, long, float, double, boolean, char
When we declare a variable of a certain type in Java, things will happen as follows:
- our computer sets aside exactly enough bits to hold a thing of that type
- Java creates an internal table that maps each variable name to a location
- Java does not write anything into the reserved boxes. In other words, there are not default values.
- For safety, Java will not let access a variable which is uninitialized
The Golden Rules of Equals
- y = x copies all the bits from x into y
Reference Types¶
Everything else(different from primitive types), including arrays, is a reference type
When we instantiate an Object using new(e.g. Dog, Walrus, Planet):
- Java first allocates a box of bits for each instance variable of the class and fills them with a default value(e.g. 0, null)
- The constructor then usually fills every such box with some other value
Reference Variable Declaration¶
When we declare a variable of any reference type, Java allocates a box of 64 bits, no matter what type of object. The 64 bit box contains not the data about the object, but instead the address of the object in memory.
As an example, suppose we call:
The first line creates a box of 64 bits. The second line creates a new Walrus, and the address is returned by the new
operator. These bits are then copied into the someWalrus
box according to the GRoE
Parameter Passing¶
We have mentioned The Golden Rule of Equals before, which says b = a copies all the bits from a into b. Passing parameters obeys the same rule: Simply copy the bits to the new scope.(Which is also called pass by value)
Comment
Java vs. C++: Primitive Data Types and Object Assignment¶
Primitive Data Types Assignment¶
For Java:
Assigning a primitive type simply copies its value. Changes to the new variable don't affect the original.
For C++:
Similar to Java, assigning a primitive type simply copies its value. Changes to the new variable don't affect the original.
Object Assignment¶
For Java:
Assigning an object copies its reference(memory address), not the object itself. Both variables point to the same heap-allocated object, so changes affect all references.
For C++:
- Value Passing(default): Assigning an object copies the entire object(via copy constructor), creating a new instance. Changes to the new object don't affect the original.
- Reference/Pointer: Using pointers or references mimics Java's reference passing, where both point to the same object.
What needs to attach attention to is that when we use for-each loop in Java, it is kind of different to that in C++. In C++, we know that the for-each loop is read only, and we will use reference if we want to revise the value, such as for(auto &i : vector)
. But in Java, its for-each loop always iterates over a copy(a copy of the array elements) and can not modify the array directly.