Contents |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We want to launch our first program
/* Multi-line comment: The "Hello World" example. */ public class HelloWorld { public static void main (String args[]) { System.out.println("Hello World"); // Comment } }
expand. First, the individual lines will be explained.
public class HelloWorld
{...
}
|
Introduces the definition of a class . A Java program consists of a number of classes. The class containing `main` must be public . The Java file must have the same name as the public class declared within it, in this case, ` HelloWorld.java` . |
public static void main (String args[])
{...
}
|
Definition of a subroutine named `main` . This subroutine is automatically started by the Java interpreter because of its name and the specific arguments it has. It must also be public and static . The `main` subroutine in this example does not return a result (` void` ) and does not use its parameters ( `args[]` strings ). Subroutines will be explained in detail later. For now, we'll stick with main . |
System.out.println("Hello World");
|
Calling the subroutine `println` in the `System.out` object
. This subroutine can print the
string
"Hello World", passed as a parameter , to the command line. |
... // Comment |
A line comment. Ignored by the compiler. |
/* ... */ |
Multi-line comment. The compiler ignores everything between /* and */ |
For now, we can read the lines
public class Test
{
public static void main (String args[])
{
...
}
}
Consider this as a framework. The three dots ... are replaced by the relevant program parts. In the example above, text was simply output here.
We now want to modify this program. To do this, we copy the file HelloWorld.java to Test.java .
copy HelloWorld.java Test.java
(or cp for Unix) and modify the contents of Test.java . To do this, we open this file in our favorite editor and enter the following text.
public class Test
{
public static void main (String args[])
{
int n;
n = 3*4;
System.out.println(n);
}
}
This calculates the product of the numbers 3 and 4, which is 12, stores the result in a variable, and outputs the value of the variable. Note that the class name has also changed and now matches the name of the file Test.java . To test the example, type the following in DOS:
javac Test.java Java test
The output should
12
This example includes the following new language elements.
int n; |
Declaration of a variable named n . The variable is stored on the stack and is only available locally within the subroutine `main` . It is no longer available after the subroutine finishes. Since our program also finishes at that point, this is irrelevant. The variable is of type int (integer, i.e., whole number). It can take values from -2,147,483,648 to 2,147,483,647 . The general form of variable declaration is: data type variable name; In this case, the data type is int and the variable name is n . |
n = 3*4; |
This is an assignment. The value resulting from the calculation of the expression 3*4 is assigned to n . This expression is of type int , since it is an operation on two int constants. |
Naturally, the type of an expression is determined by the type of its operands. In this case, both constants, 3 and 4, are of type int , and therefore so is the result 3*4. This general rule always holds true.
Rule: The type of operands determines the type of result.
The following elementary data types exist . The table lists the Java name of each data type, examples of constants of that data type, and the possible values that variables of that data type can take.
|
Data type |
constants |
Value set |
|---|---|---|
|
short |
|
-2^15 ... 2^15-1 |
|
int |
3, -3, 0, 0x3FF (hexadecimal), 0377 (octal) |
-2^31 ... 2^31-1 |
|
long |
3l, -30000000000l |
-2^63 ... 2^63-1 |
|
float |
|
approximately a 6-digit mantissa and a two-digit exponent. |
|
double |
3.1415, 1e20, 1e-10, -1E10 |
Approximately 16-digit decimal mantissa and 3-digit exponent. |
|
byte |
|
0 ... 2^8-1=255. Normal storage unit. |
|
char |
'A', 'a', ' ', '\t', '\n', '\xFE', '\u0121' |
Simple single characters, special characters with \ , Unicode characters. |
|
boolean |
true, false |
True or false. |
The type of constants, such as 3 and 4 , is determined by their notation. For numbers without a decimal point, it is ` int` ; for numbers with a decimal point , it is `double` , e.g., 3.4 , -1.55 , or 1.5e10 . Long constants have an appended `l` .
An expression remains of type int as long as it does not contain any double values.
Attention! The expression 1/3 results in 0 , since it is calculated as an integer.
If you want to obtain 0.333... as the result, you can write 1.0/3 . In this case, the first operative part is a double, and therefore so is the result. Of course, 1.0/3.0 also works , or as we will see below, (double)1/3 .
Now we can calculate a more complicated expression.
public class Test
{
public static void main (String args[])
{
double x = 1.5, y;
y = 1+x+x*x/2+x*x*x/6+x*x*x*x/24;
System.out.println("y = " + y);
}
}
It is therefore possible to declare multiple variables on a single line and assign values to them simultaneously. If a variable is not assigned a value, it cannot be used. The compiler will flag this as an error.
Furthermore, the variable x is used here as an operand in expressions. So far, we have only used constants in expressions.
It's also interesting to see how 1 + x + ... is calculated. 1 is a constant of type int , but x is a variable of type double . Here, the result is determined by the higher-order type of the operands, in this case, double . Naturally, the sum of multiple addends is calculated from left to right. Java follows the order of operations (multiplication and division before addition and subtraction ) and also takes parentheses into account . The exponentiation must be calculated using Math.pow(x,y) .
Note the addition of a string and a double variable in the output. Here, the double value is first converted to a string, and then the two strings are concatenated. We will explain this in more detail below .
The program produces the following output
y = 4.3984375
What happens when an expression of a lower type is stored in a variable of a higher type? In this case, the conversion is automatic. Conversely, the reverse will result in a compiler error message.
Rule: Automatic conversions are only allowed if the target can accept the value in any case .
int n = 3; long l = n; // automatic conversion
Conversely, a type cast is necessary.
long l = 20000; int n = (int)l; // type cast from long to int
This allows data types to be converted into one another as desired. The programmer is responsible for any errors.
public class Test
{
public static void main (String args[])
{
long c = 1000000000000l; // the l is necessary!
System.out.println(c); // prints the correct value
System.out.println((int)c); // prints -727379968
}
}
No runtime error is generated in the event of an overflow . However, division by zero or similar errors generate an arithmetic exception . We will postpone discussing exceptions and their handling for now.
For the arithmetic data types (all except boolean ), the usual operators + , - , * , /, and % (modulo) are defined. The result is always of the same type. Therefore
int n=3;
System.out.println(n/4); // prints 0
The order of operations is strictly defined, but corresponds to the usual convention ("multiplication and division before addition and subtraction", and consideration of parentheses).
System.out.println((3.0+7.0)/(4.0*5.0+80.0)); // prints 0.1 System.out.println((3.0+7)/(4*5+8)); // prints 0.1 System.out.println((double)(3+7)/(4*5+8)); // also prints 0.1 System.out.println((3+7)/(4*5+80)); // but prints 0 !!!
Comparisons of numbers yield true or false of type boolean . The comparisons are < , <= (less than or equal to), > , >= , == (equal to), != (not equal to). Example:
double x=3; System.out.println(1/x >= 0.3); // prints true
Boolean expressions are combined with && (and) and || (or). They are reversed with ! (not).
We will need such Boolean expressions later, especially for controlling the flow of programs, for example for conditional jumps and instructions.
Furthermore, there are several special bitwise operators for numbers, namely | (or), & (and) , ^ (either/or), and ~ (bitwise complement, NOT). In addition, there are operators that shift bitwise right and left, namely >> (shift right, where negative numbers remain negative), << , and >>> (shift right with padding of zeros). For example, n<<2 corresponds to multiplying n by 4. These operators are only relevant when dealing with numbers in the binary system.
There are also the operators ++ and -- , which can be used before and after the integer. These operators increment or decrement an integer value by 1. ++n does this before the use of n, and n++ after. These operators can also be used as statements. Example:
int i=1; i++; System.out.println(i); // prints 2.
It is debatable whether it wouldn't be better to write i=i+1 , which is clearer and therefore less error-prone. However, i++ was translated by earlier compilers into code that executed faster, so this notation has become established.
Furthermore, combinations of operators and = exist. Example
int i = 1; i += 2; System.out.println(i); // prints 3.
The question here is whether i=i+2 is not clearer, and yet executed just as quickly.
Strings are not actually elementary data types but behave like classes. However, since they are crucial for non-mathematical examples, we will discuss them here. We will examine strings in more detail later .
We have already used string constants . Such constants are enclosed in quotation marks . Example
String s="This is a test string.";
The most important arithmetic operation with strings is addition (+). This addition appends two strings to each other. You can also add elementary data types to strings. These values are then first converted into a string representation. This allows you to annotate numerical outputs.
double pi = Math.PI;
System.out.println("Pi squared is " + (pi*pi));
First, pi*pi is calculated, then this value is converted into a string, and finally...
Pi squared is 9.869604401089358
Java outputs all relevant digits , thus revealing computational inaccuracies that are rounded down when outputting with other languages, even though they exist internally. If you want to format to a specific number of digits, you must use Java's formatting routines in `String.format` , which we will discuss later.
Here is another example that outputs the letter which has the code 67.
public class Test
{
public static void main (String args[])
{
int n = 67;
System.out.println(
"The letter number " + n + " is " +(char)n);
}
}
The value 'n' is treated once as an int value and once as a char value, and accordingly converted into a string differently. The result is...
The letter number 67 is C
Hexadecimal numbers can be entered as 0xff , which stands for 255.
The mathematical functions are defined statically in the Math class . Therefore, they are called as in the following example:
System.out.println(Math.exp(1)); // Prints the value of e
Before we explain classes in more detail, this should simply be understood as a way of writing down mathematical functions.
The usual functions abs , sin , cos , exp , log , asin , acos , and sqrt are defined. In addition, there are two-variable functions such as pow (calculates x^y ), atan2 (calculates the angle between x and y), max , and min . All these functions must be called with the prefix Math .
In addition, there are the functions `floor` and `ceil` , which round down and up, respectively, to the nearest integer. The `round` function rounds to the nearest integer but returns a `long` value.
Finally, the function `random` generates a random number between 0 and 1.
It is also possible to perform multiple assignments simultaneously.
int n,m; n = m = 3;
This is because an assignment like m=3 actually has a result (namely 3 ), which is then used by n= . Normally, this result is discarded. It's possible to use the result in other cases, but this usually leads to poorly readable code.
For example, it is not immediately clear how
double a; double y = Math.sin(a = Math.PI/4));
It actually works. In contrast, it reads...
double a=Math.PI/4; double y=Math.sin(a);
significantly lighter.
Solutions (please try them yourself first!).