This guide goes through some of the mechanical elements of writing Java.
This is focused on the syntax and structure of Java code, not on the semantics (behavior) of the code.
This guide is intended to be applicable throughout the duration of the course, so it is not expected that you'll be able to understand every single bit of it all at once.
For example, while the meaning of a comma (,
) in Java code is discussed, we won't be seeing commas until later in the course.
Java code must be written in plain text, which is true of most programming languages.
Text editors (e.g., jGrasp, emacs
, vi
, vim
, Sublime Text, Atom, ...) will give you plain text straight out of the box.
Word processors (e.g., Microsoft Word, Google Docs) generally don't give you plain text out of the box, and if you use these you'll need to explicitly have them save as plain text.
Text editors are meant for writing things that can be read by both humans and computers, including code.
This is why text editors are based around plain text: the text itself should be as simple as possible in structure to facilitate easy reading for both parties.
Word processors are meant for writing things for humans.
This is why word processors generally don't use plain text: they want to add in extra formatting which makes things easier for humans to read, but more difficult for a computer to understand.
For example, word processors will try to make explicit left and right double quotes (i.e., “ ”), whereas text editors will use the same double quote character either way (i.e., "
).
Beyond plain vs. formatted text, text editors generally better understand the syntax of programming languages. This means that text editors can do things like highlight your code and even automatically structure it. These features make code easier to read and write on a text editor. Word processors, in contrast, lack these features. In fact, a particularly aggressive word processor may try to “autocorrect” something which is syntactically valid (but strange-looking) into something invalid (but better-looking). With this in mind, word processors are altogether the wrong tools with which to edit code.
The part of your code which actually runs is divided into expressions and statements. In being executable, both expressions and statements do something. However, expressions and statements differ in exactly what they produce.
Expressions do something, and then produce some sort of value as a result.
This is no different from the sort of mathematical expressions you're used to, such as 2 + 3
.
Mathematically, the expression 2 + 3
states to add 2
and 3
together, and the produced result of the expression is 5
.
Java expressions work in the exact same way, and the nomenclature of “expression” comes from the same source.
In fact, 2 + 3
, in addition to being a valid mathematical expression which produces 5
, is also a valid Java expression which produces 5
.
Statements, like expressions, instruct the computer to do something. However, unlike expressions, statements do not produce values as results, at least not directly. For example, consider the following Java statement:
System.out.println("Hello, world!");
The statement above is valid Java code which tells the computer to display Hello, world!
on the screen somewhere.
In this way, the statement does something.
However, the statement doesn't actually produce any direct result.
We can't try to grab the result produced from the statement, because there simply isn't one.
Overall, statements are directives which have no real response.
A non-exhaustive list of the available types in Java follows:
int
: Fixed-size integers.
The largest possible integer is 231-1, and the smallest possible integer is -231.
Attempts to derive integers outside of that range will result in incorrect values (specifically overflow).
In this class, we won't worry about integer overflow.
boolean
: Representation of Boolean values, which represent truth values.
There are only two possible values: true
and false
.
double
: An (occasionally highly) approximate, fixed-size representation of real numbers.
char
: Represents a single character.
For example, 'a'
is a single character which holds the letter 'a', 'b'
is a single character which holds the letter 'b', and so on.
String
: Holds text, which consists of an ordered sequence of characters.
Unlike the previous types, this is a reference type (String
is a class).
When specifying a particular String
, a pair of double quotes ("
) are used.
For example, "Hello!"
denotes a String
object that holds the text “Hello!”.
Somewhat confusingly, 'a'
and "a"
are separate entites; 'a'
represents a single character (char
) value holding the letter 'a', and "a"
represents a reference to a string which contains only the letter 'a'.
Compared to natural languages, Java has quite a bit of punctuation. Two non-comprehensive lists of punctuation follow. These lists are divided into punctuation marks which are standalone, and punctuation marks which work in pairs.
Semicolon (;
): Indicates the end of a statement, and all statements must be ended with semicolon.
For example, note the semicolons in the following code:
System.out.println("This"); System.out.println("demonstrates"); System.out.println("semicolons");
Comma (,
): Separates items in a list, including the input paramters to a method call.
For example, the following Java snippet calls the method named someMethod
with the parameters 1
, 2
, and 3
, in that order:
someMethod(1, 2, 3);
Period (.
): Separates the name of an object or class from a member of that object or class.
For example, consider the familiar:
System.out.println("Hello, world!");
In the above snippet, the first period separates the System
class from the member of that class named out
.
out
is itself an object.
With this in mind, the second period separates the out
object from its member println
.
Arithmetic operators (+
, -
, *
, /
, %
): indicate to perform some mathematical operation over two values.
For example, 1 + 2
indicates to add 1
and 2
together, and 3 + 4 + 5
indicates to add 3
, 4
, and 5
together.
Multiplication is represented by *
, and integer division by /
.
The %
operator gets the remainder of its two operands (for example, 5 % 3
produces 2, which is the remainder from 5 / 3
).
Java understands the usual PEMDAS ordering, wherein multiplication and division have higher precedence than addition and subtraction, and parenthesized expressions have the highest precedence.
For example, consider the following Java expression:
2 + 4 * 5
The above Java expression is equivalent to the following Java expression, which explicitly uses parentheses to denote the order in which expressions should be evaluated:
2 + (4 * 5)
Assignment (=
): Assigns the value of an expression into a variable.
For example, consider the following Java code:
x = 5;
The above Java snippet assigns the value 5
into the variable named x
.
Note that 5
itself is an expression which produces the value 5
.
Comparison operators (==
, !=
, >
, >=
, <
, <=
): Performs an arithmetic comparison of two values, producing a Boolean value (either true
if the comparison holds, or false
if it doesn't).
A brief description of each follows:
==
: Produce true
if the two values are equal.
For example, 5 == 5
will produce true
, and 5 == 6
will produce false
.
!=
: Produce true
if the two values are not equal.
For example, 5 != 5
will produce false
, and 5 != 6
will produce true
.
>
: Produce true
if the first value is strictly greater than the second value.
For example, 5 > 4
will produce true
, and 5 > 5
will produce false
.
>=
: Produce true
if the first value is greater than or equal to the second value.
For example, both 5 >= 4
and 5 >= 5
will produce true
, and 4 >= 5
will produce false
.
<
: Produce true
if the first value is strictly less than the second value.
For example, 4 < 5
produces true
, whereas 5 < 4
produces false
.
<=
: Produce true
if the first value is less than or equal to the second value.
For example, both 4 <= 5
and 5 <= 5
produce true
, but 6 <= 5
produces false
.
Logical operators (&&
, ||
, !
): Perform operations on Boolean values, yielding new Boolean values.
A brief description of each follows:
&&
: Produce true
if both input values are true
, else produce false
.
For example, true && true
produces true
, whereas true && false
produces false
.
||
: Produce false
if both input values are false
, else produce true
.
For example, false || false
produces false
, whereas false || true
produces true
.
!
: Negate the given Boolean value, resulting in the opposite Boolean value.
For example, !true
produces false
, and !false
produces true
.
"
): Represents a reference to a String
value.
For example, "Foo"
represents a reference to a String
which holds the text “Foo”.
'
): Used to indicate a single character.
For example, 'a'
is a single character which holds the letter 'a', 'b'
is a single character which holds the letter 'b', and so on.
()
): These have three separate uses, which are context-sensitive.
These uses are detailed below:
(1 + 2) * 7
, Java will evaluate 1 + 2
first, thanks to the parentheses around 1 + 2
.
foo()
calls a method named “foo
” without passing any parameters, and bar(1)
calls a method named “bar
”, passing the parameter 1
.
Delineate the parameters to a method/constructor definition: parenthesis have to be used as part of method definitions. For example, consider the following snippet:
public void foo() { // some code here }
The snippet above defines a method named “foo”, which does not take any parameters.
Curly braces ({}
): These are used to define the bodies of methods and class definitions.
For example, consider the following snippet:
public class Foo { public static void main(String[] args) { // some code here } }
In the snippet above, the outermost set of curly braces delineates a class definition, where the class' name is “Foo
”.
The innermost set of curly braces encapsulates the body of the method named “main
”.
[]
): Used for defining and accessing arrays.
For example, int[] myArray = ...
defines a variable named “myArray” which holds a reference to an array of int
.
The notation myArray[7]
accesses the seventh element of the “myArray” array.
Comments allow for programmers to embed messages to each other directly in the source code itself. Comments are completely ignored by the compiler; comments are purely for humans reading each other's code. Comments are useful for helping other programmers understand the purpose and high-level meaning behind your code. To better understand this, consider the following code:
f = c * (9 / 5) + 32;
While the above snippet is unambiguous, it's completely unclear why it's doing what it's doing, or what it's trying to accomplish. The only apparent information is that there is some arithmetic computation being performed. Now observe the same snippet with an appropriate comment:
// convert Celsius (c) to Fahrenheit (f) f = c * (9 / 5) + 32;
With the above comment in play, it becomes much more clear as to what the above snippet is doing: it is converting temperature in Celsius to Fahrenheit, using a standard formula.
There are two types of comments: end-of-line comments, and block comments. Each of these is described below.
End-of-line comments: The comment in the snippet above is an end-of-line comment.
End-of-line comments begin with //
.
As the name suggests, everything after //
on the same line is considered a comment.
Block comments: Unlike end-of-line comments, block comments can span multiple lines.
Block comments begin with /*
, and end with */
.
To see a block comment in action, consider the following code:
x = 5; /* This is a block comment. * This comment is still going. * Aaaaand we're done on the next line. */ y = 6;
In the snippet above, everything between the /*
and */
is a comment.
Additionally, the comment above was aligned so that the two endpoints visually overlapped vertically, and an asterisk (*
) was put at the beginning of each new line to visually help show that each of these lines was part of the same block comment.
To be clear, such niceties are not required by the compiler, though they can greatly help improve readability by other programmers.
Since comments are intended for other programmers anyway, it is good practice to go through this extra bit of formatting.
Proper indentation is important for readability of your code. For example, consider the following poorly indented code:
public class Foo { public static void main(String[] args) { if (3 < 2) { System.out.println("yup"); } else { System.out.println("nope"); } } }
While the compiler will accept the above code, this is very difficult for a human to read.
Generally, whenever curly braces ({}
) are used to delineate some sort of body of code, this code should be indented one level in order to make it clear which bits of code match to which body.
To see how this can improve readability, consider the same snippet of code below, now properly indented:
public class Foo { public static void main(String[] args) { if (3 < 2) { System.out.println("yup"); } else { System.out.println("nope"); } } }
In the above snippet, it is much clearer exactly which code is the body of the “main
” method, which code is underneath each branch of the if
, and so on.
While the above code “looks” the same to the compiler as the previous poorly-formatted snippet, this is much more appealing (and easy to read) to the human eye.