Java Programming/Java Foundations
From Wikibooks, the open-content textbooks collection
Contents |
[edit] Foundations
[edit] Lexical Elements
[edit] Source Text
Java source files consist of Unicode text files. Most Java program text consists of ASCII characters. Identifiers may contain Unicode characters, so that Π (which is the Greek Capital Letter Pi) is a valid Java identifier. Pi may also be represented as the Unicode escape sequence \u03A0
. Thus, the following is a valid declaration and assigmnent:
double \u03A0 = Math.PI;
Unicode escape sequence may appear anywhere in a Java source file (including inside identifiers, comments, and string literals.) Unicode escape sequences consist of
- a backslash '
\
' (ASCII character 92, hex 0x5c), - one or more '
u
' characters (ASCII 117, hex 0x75), and - four hexidecimal digits (the characters '
0
' though '9
' or 'a
' through 'f
' or 'A
' through 'F
').
The reason you can use more than one u character is to provide for reversibility of saving to ASCII -- when saving, non-ASCII characters become Unicode escapes, and existing escapes (the one the user typed in) get one extra 'u
'. Later, when the file is reopened, escapes with more than one 'u
' remain escapes (with one fewer 'u
'), while those with a single 'u
' become Unicode characters again.
[edit] Comments
Comments are described in Comments.
[edit] Character Literals
Character literals consist of a single quote character ('
) (ASCII 39, hex 0x27), a single character, and a close quote ('
), such as 'w'
. Instead of a character, you can also use one of the escapes described below, but again there must be exactly one.
[edit] String Literals
String literals consist of the double quote character ("
) (ASCII 34, hex 0x22), zero or more characters (including Unicode characters), followed by a terminating double quote character ("
), such as
"Ceci est une string."
Within string and character literals, the backslash character can be used to escape special characters, such as Unicode escape sequences, or the following special characters:
\b
Backspace (ASCII 8, hex 0x08)\t
TAB (ASCII 9, hex 0x09)\0
the NUL character (ASCII 0, hex 0x00)\n
newline (ASCII 10, hex 0x0a)\r
carriage control (ASCII 13, hex 0xd)\"
double quote (ASCII 34, hex 0x22)\'
single quote (ASCII 39, hex 0x27)\\
backslash (ASCII 92, hex 0x5c)
String literals may not contain unescaped newline or linefeed characters. However, the Java compiler will evaluate compile time expressions, so the following String expression results in a string with three lines of text:
String text = "This is a String literal\n" + "which spans not one and not two\n" + "but three lines of text.\n";
[edit] Identifiers
Identifiers consist of a Java letter followed by zero or more digits or Java letters. Java letters are alphabetic (non digit) characters such as the ASCII values a through z, A through Z, the underscore '_' or dollar sign '$' characters, or other Unicode letter characters.
[edit] Numbers
In Java, you may enter numbers in several formats:
- As decimal numbers such as
1995
. Negative decimal numbers such as-42
are actually expressions consisting of the integer literal with the unary negation operation-
. - As octal number, rytetryusing a leading
0
(zero) digit and one or more additional octal digits (digits between0
and7
), such as077
. Octal numbers may evaluate to negative numbers; for example037777777770
is actually the decimal value -8. - As a hexadecimal number, using the form
0x
(or0X
) followed by one or more hexadecimal digits (digits from0
to9
,a
tof
orA
toF
). Like octal numbers, hexadecimal literals may represent negative numbers. For example, 0xCAFEBABEL is the long integer 3405691582
In addition, if an integer literal has a letter el suffix (either the character l
or the character L
), it denotes a long integer rather than a standard integer. For example, 3405691582L
is a long integer literal. Long integers are 8 bytes in length as opposed to the standard 4 bytes for int. It is best practice to use the suffix L
instead of l
to avoid confusion with the digit 1
(one) which looks like l
in many fonts: 200l
≠ 2001
.
Floating point numbers are expressed as decimal fractions or as exponential notation. Floating point numbers consist of:
- an optional leading
+
or-
sign (indicating a positive or negative value, the default being positive if no sign exists) - one of the following number formats
- integer digits
- integer digits
.
- integer digits
.
integer digits .
integer digits
- an optional exponent of the form
- the exponent indicator
e
orE
- an optional exponent sign
+
or-
(the default being a positive exponent) - an integer exponent value
- the exponent indicator
- an optional floating point suffix:
- either
f
orF
indicating a single precision (4 bytes) floating point number, or d
orD
indicating the number is a double precision floating point number.
- either
Floating point literals are double precision (8 bytes) by default; thus the f
or F
suffix is optional.
Examples of floating point numbers:
5.0
5d
-0.5
10f
3.14159e0
2.718281828459045D
1.0e-6D
[edit] Keywords
The following are keywords in Java and may not be used as identifiers:
abstract |
continue |
for |
new |
switch |
assert |
default |
if |
package |
synchronized |
boolean |
do |
goto |
private |
this |
break |
double |
implements |
protected |
throw |
byte |
else |
import |
public |
throws |
case |
enum |
instanceof |
return |
transient |
catch |
extends |
int |
short |
try |
char |
final |
interface |
static |
void |
class |
finally |
long |
strictfp |
volatile |
const |
float |
native |
super |
while |
In addition, the identifiers null
, true
, and false
denote literal values and may not be used as identifiers.
[edit] Primitive Data Types
Java, like C++, comes with many built-in data types. These are usually referred to as primitives. Below is a quick overview of all the basic types that Java supports.
- int - A 32-bit signed integer. This can hold any "whole number" ranging from − 231 to 231 − 1
- byte - An 8-bit signed integer. This can hold any "whole number" ranging from -128 to 127.
- short - A 16-bit signed integer. Shorts can hold "whole numbers" from -32,768 to 32,767.
- long - A 64-bit signed integer. It holds the highest precision of all integer types and can hold numbers ranging from − 263 to 263 − 1.
- float - A 32-bit signed floating-point number. This is the basic floating-point decimal number. A float can hold any number from 2 − 149 to (2 − 2 − 23) * 2127 but can only hold about seven decimals of precision.
- double - A 64-bit signed floating-point number. It's able to hold numbers ranging from − 1.7 * 10 − 308 to 1.7 * 10308 with 15 digits of precision.
- char - A 16-bit char holds a Unicode character in memory. chars are unsigned integer values.
- boolean - A datatype for logical operations. Its value is one of the literals true or false.
[edit] Objects and Classes
When you write a program in Java you are creating a model of some part of the world. Objects are what makes up the model. Classes are the templates from which Objects are created. You create objects from classes using the new keyword. An object is called an instance of a class.
The outer wrapping of a class looks like this:
public class NameOfClass { }
All methods, constructors and fields are defined in the inner part of the class; between the braces.
public class NameOfClass { fields constructors methods }
The order in which you define them does not matter and it is up to your personal preference. That is, you can define methods and/or constructors before you define any fields, or even interleave them.
[edit] Members
All methods and variables are known as members.
[edit] Visibility
Members can have four levels of visibility. The keyword indicating the level of visibility is added before the type and name of the member. Example:
protected String someVariable; public void someMethod(){ //some code }
- private - only instances of this class, and any inner classes it may have, can access this member
- protected - this class, any inner classes, all the classes in the same package and classes extending this class that are declared in other packages can use this member
- default (no keyword) - only classes within the same package can use this member
- public - any class can use this member
A general guideline for visibilities is to only make a member as visible as it needs to be. Don't make a member public if it only needs to be private.
[edit] Encapsulation
Generally, it is best to make data private or protected. Access to the data is controlled by mutator and accessor methods. This lets the programmer control access to data, allowing him/her to check for and handle invalid data.
Example:
private String name; public String getName() //This is an accessor method because it accesses data from the object { return name; } public boolean setName(String newName) //This is a mutator method because it changes data in the object { if (!isValid(newName)) return false; name = newName; return true; }
In the example, the setName method will only change the value of name if the new name is valid (the example assumes that a method called isValid exists). Because setName is conditionally changing name, it is wise to return a boolean to let the program know if the change was successful.
It should be noted that providing accessor and mutator methods for a field does violate encapsulation, even in a controlled way, and should be avoided unless there is a good reason for making the field visible.
[edit] Methods
Methods are how we communicate with objects. When we invoke or call a method we are asking the object to carry out a task. We can say methods implement the behaviour of objects. All methods have a name and a return type. If the method returns nothing, the keyword void is used.
[edit] Returning data
The return statement returns a value from a method. Any method that doesn't return void must have a return statement. More than one return statement can exist in a method, but at least one must be reachable. Example:
public double fahrenheitToCelsius(double c){ return (c - 32.0) * 5.0 / 9.0; }
public boolean isPositive(int x){ if (x > 0){ return true; } return false; }
This method has two return statements. Note that once a return statement is reached, the program leaves the method.
To break out of a void method, the return statement is also used.
public void useless(int x){ int i = 0; while (true){ i++; if (i == x) return; } }
However, the return statement is not required (such as in the method fahrenheitToCelsius) and, for some methods, the returned data isn't necessary.
Data returned from a method can be used as a variable. For example:
if (isPositive(y)) { //do something }
boolean y = isPositive(3);
In most cases, the returned data is necessary. The following statement is legal Java code, but as the returned value is not assigned to a variable it is lost, and the statement achieves nothing.
isPositive(3);
[edit] Overloading
Methods can be overloaded. This means that multiple methods can exist with the same name, but must have different signatures. A method's signature is comprised of the method's name and the type and order of the method's parameters. Example:
class Talker(){ public String reply(String s1, String s2){ return "You said:"+s1+" and then you said:"+s2; } public String reply(int i){ return "You sent a number, it was:"+i; } }
When the client code calls the reply method, the compiler decides which of the overloaded methods will be called, based on the parameters that were used in the call. Example:
Talker t = new Talker(); String gotBack = t.reply(4);
Here the compiler can determine that the method required is the one in the Talker class (because the type of t is Talker) which expects a single integer parameter. In this case the second reply method will be called - and gotBack will get the value "You sent a number, it was 4".
Constructors can also be overloaded. Example:
class Person(){ private String name; private boolean married; public Person(String name){ this.name=name; /** now do other setup stuff **/ } public Person(String name, boolean married){ this(name); this.married=married; } }
A programmer constructing a Person instance now has the option of creating one with both name and marital status, or just name alone. The example above also demonstrates the this syntax which causes one constructor to call another - reducing code repetition.
public void example1() {...} public int example1() {...}
These methods cannot co-exist because they have the same signature (remember, return type is not part of the signature)
public void example2(int x) {...} public void example2(int y) {...}
These methods cannot co-exist because the names of the parameters are not part of the signature.
private void example3() {...} public void example3() {...}
These methods cannot co-exist because the visibility of the methods are not part of the signature.
public String example4(int x) {...} public String example4() {...}
These methods can co-exist, because they have different method signatures.
[edit] Constructors
Constructors are a special type of method that sets up each object when it is first created. The name of the method must be the name of the class and there is no return type
Example:
public class SomeClass{ int someValue; public SomeClass(){ someValue = 0; } public SomeClass(int startingValue){ someValue = startingValue; } ... }
In this example, there are two constructors. One creates the object and initializes someValue to 0 the other constructor initialzes someValue to the value of the parameter startingValue.
[edit] Fields
[edit] Scope
All variables in Java have scope. Variables only exist inside the block they are defined in. For example
public class SomeClass { int age; public void foo(){ for (int x = 0; x < 10; x++){ int i = x + 1; int j = i * i; } } public void donothing(){ int k = 7; } }
Age is accessible to all methods inside SomeClass.
The Java compiler is smart, and doesn't recreate i and j each time the loop executes. However, the variables i and j no longer "exist" after the loop finishes executing. Likewise, the variable k can only be used inside donothing().
[edit] Instance Fields
Data for an object is stored in fields, also known as instance variables. Fields are defined outside constructors and methods. The data, which is unique to each instantiation of the class lasts for the lifetime of an object; they maintain the state of an object.
Everytime an object is created, each field will have space to store its values.
Example:
public class NameOfClass { private int length; constructors methods }
In this example a field has been defined with the name length
and the type int
. The key word private
is the field's access modifier.
[edit] Static Fields
Data for a class is stored in static fields. Just like fields, static fields are defined outside constructors and methods as well. Unlike regular fields however only one copy of the field's value is stored, which is shared between all instances of the class. Static fields are intialized the first time an instance of the class is created.
Example:
public class Employee { private static int nextID = 0; private int myID = nextID++; // constructors... public int getID() { return myID; } // other methods... }
In this case, each Employee has a unique ID, stored in the field myID. To ensure that no employee has the same ID, a static field is used to store the next ID to assign.
Employee a = new Employee(); Employee b = new Employee(); Employee c = new Employee(); System.out.println(a.getID()); System.out.println(b.getID()); System.out.println(c.getID());
The output of the code segment will be
0 1 2
Keep in mind that while non-static members can access static members, static members cannot access non-static members unless they do so through a reference to an instance.