Java SE 8 Documentation
Exercises

Hello World!

Implement the classical "Hello world" program in Java.

/**
 * A "Hello world" program.
 */

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Note that the name of the source file must match the name of the public class inside. That is, if the name of the file is Foo.java, there must be a class named Foo that is described by the public class Foo definition.

Printing to the Console

Like in other languages, there are many ways to print messages to the console, through the java.lang.System class:

  • Standard input: System.in.
  • Standard output: System.out.
  • Standard error: System.err.
  • The printed messages may contain the following control characters (represented as escape sequences), such as \r, \n, \t, \b, and so on.
  • The System class has further helper functions, for example System.exit().

Environment Variables

In order to compile and run Java programs, the environment must be set properly.

In case of Windows, launch the command line, with the help of the key combination Windows + R for example. After that, the PATH environment variable shall be modified:

$ PATH=%PATH%;"C:\Program Files\Java\jdk1.8.0_77\bin"
$ echo %PATH%
...;C:\Program Files\Java\jdk1.8.0_77\bin

So the following shall work:

$ javac -version
javac 1.8.0_77

In case of GNU/Linux and UNIX system, the same has to be done, but the actual syntax highly depends on the shell used. In the ideal case, the package manager of the operating system distribution will take care of this on the installation of the JDK.

Compiling Java Programs

Programs can be compiled with the help of javac (as in "Java compiler").

$ javac HelloWorld.java

If the program to be compiled has compile-time errors, the compiler is going to report this:

$ javac HelloWorldBad.java
HelloWorldBad.java:1: error: class, interface, or enum expected
public HelloWorldBad {
       ^
HelloWorldBad.java:2: error: class, interface, or enum expected
    public static void main(String[] args) {
                  ^
HelloWorldBad.java:4: error: class, interface, or enum expected
    }
    ^
3 errors

where the problematic source code was the following:

public HelloWorldBad {
    public static void main(String[] args) {
         return 0;
    }
}

Running Java Programs

Depending on the result of a successful compilation, zero or more files are generated with the extension .class (containing byte codes). Those files could be run by the Java Virtual Machine (JVM for short), which is the java program.

$ java HelloWorld
Hello World!

Remark. The java program can only run .class files that has a public static main() method (see the example source code above).

Consider the following program, where there is no main() method:

public class HelloWorldWrong {}

That is going to build without any errors:

$ javac HelloWorldWrong.java

But the resulting program will not run:

$ java HelloWorldWrong
Error: Main method not found in class HelloWorldWrong, please define the main method as:
   public static void main(String[] args)

Generating Documentation for Java Programs

Note that it is possible to generate an API documentation for the classes from the comments placed in the source code by the javadoc tool. All it needs is to add comments with a special syntax.

$ javadoc HelloWorld.java
Loading source file HelloWorld.java...
Constructing Javadoc information...
Standard Doclet version 1.8.0_77
Building tree for all the packages and classes...
Generating /HelloWorld.html...
Generating /package-frame.html...
Generating /package-summary.html...
Generating /package-tree.html...
Generating /constant-values.html...
Building index for all the packages and classes...
Generating /overview-tree.html...
Generating /index-all.html...
Generating /deprecated-list.html...
Building index for all classes...
Generating /allclasses-frame.html...
Generating /allclasses-noframe.html...
Generating /index.html...
Generating /help-doc.html...

Generic Java Programming Conventions

package java.foo; // top-level domain (TLD), lowercase characters

/**
 * Class description.
 *
 * @version  0.1.0
 * @author   Mr. T
 */
public class Bar extends Baz {

    /** One-line comment for classVar1. */
    public int classVar1;

    /**
     * classVar2 that has a multi-line
     * description.
     */
    private static String classVar2;

    /**
     * Comment for a constructor.
     */
    public Bar() {
        // ...
    }

    /**
     * Comment for a method.
     */
    public void doSomething() {
        // ...
    }

    /**
     * Another comment for a method.
     *
     * @param someParam some parameter
     * @return some valule
     */
    public int returnSomeValue(Object someParam) {
        // ...
    }

    /**
     * Boolean method.
     */
    public boolean isSomething() {
       // ...
    }
}

Convetions regarding naming and structuring source files:

  • Class name = file name, starts with an uppercase letter.
  • Package nem = directory name, starts with a lowercase letter, can be nested.

Remark. Try to avoid using national character in both file names and program identifiers, although Java makes it possible.

Types

The language has the following primitive types, for example: byte, short, int, long, float, double, char, boolean. All those have a type-specific default value (e.g. 0 for int, false for boolean). Such values can be given with octal (int octVal = 01), hexadecimal (byte hexVal = 0xff), or scientific (double d = 1.23e4) notations.

All the other types are described object classes, and primitive values could be wrapped into objects (such as java.lang.Byte, java.lang.Short, java.lang.Integer, and so on) on demand. Furthermore, the related operations are implemented as static methods for the corresponding wrapper object classes.

Conversion between types:

  • Expanding conversion, which is automatically allowed by the compiler.
  • Narrowing conversion, which may be requested by coercion (byte b = (byte) 300).

Conversion with text:

  • Texts can be represented by the java.lang.String class.
  • Turning numbers to text: String s = "" + 1;
  • Turning text to numbers: Integer.parseInt("1"), Double.parseDouble("2.0"), etc.

Control Structures

The language contains many imperative control structures, which are all statements. Some of the categories of those can be found below. In addition to that, the language supports building blocks of statements as well. Blocks are delimited by { and } symbols.

if, else

if ( /* first condition */ ) {
    // when the first condition is true
} else
if ( /* second condition */ ) {
    // when the second condition is true
} else
if ( /* third condition */ ) {
    // when the third condition is true
} else {
    // otherwise
}

switch

The switch statement can be used for building multi-way branches, but the branching is not done by a logical condition but an enumerated value. That is why values of the following types are allowed in this structure: byte, short, char, int or their respective wrapper classes (Byte, Short, Character, Integer).

int month = 8;

switch (month) {
    case 1:  System.out.println("Jan"); break;
    case 2:  System.out.println("Feb"); break;
    case 3:  System.out.println("Mar"); break;
    case 4:
    case 5:
    case 6:  System.out.println("Apr, May or Jun"); break;
    default: System.out.println("Other month"); break;
}

for, while, do

while ( /* Boolean condition */ ) {
    // loop body
}
do {
    // loop body
} while ( /* Boolean condition */ );
for (/* initialization */; /* stop condition */; /* stepping */) {
    // loop body
}
for (;;) {  // infinite loop
    // loop body
}
for (String a : args) {  // for arrays and other traversable data structures
    // loop body
}

break, continue, return

The break statement could be used for leaving blocks, for example quitting loop bodies. On breaks, the control is passed to the first statement after the loop.

for (;;) {
    if (false)
        break;
}

The continue statement could be used for skipping the rest of the loop body. So when it is used, the loop is restarted and the control goes to the evaluation of the stop condition.

for (int i = 0; i < 10; ++i) {
    if (i < 9)
        continue;
    System.out.println("i = " + i);
}

Remark. There is a keyword reserved for goto, but it cannot be used. However, both break and continue may be parametrized by labels.

The return statement could be used for returning from subprograms (that is methods). If there is a value to be returned, it can be specified here.

static void main(String args) {
    if (args.length == 0)
        return;
    System.out.println("Never reached.");
}

static int succ(int i) {
    return (i + 1);
}

Real Numbers

On application of real numbers (that is, the float and double types), care must be taken -- not only in the Java language, but in any other language in general. The reason for that is that real numbers on computers are only approximations, that could be either represented as fixed-point numbers or floating-point numbers.

  • For fixed-point representation, the sign, the integral and the fractional parts are stored on a predetermined number of bits, independently of the actual value. In result, this may come with a large amount of informatio loss, but that is quite fast.

  • For floating-point representation, values are stored in a normalized form, which basically follows this formula:

    (-1)^s \cdot m \cdot b^e

where s is the sign b is the base of the normalized form, 0 \leq |m|  \leq b is the mantissa, and e is the exponent. The base is usually two or ten.

Examples of numeric errors due to these representations:

System.out.println(0.2 + 0.2 + 0.2 + 0.2 + 0.2);  // minor numeric error: 1.0
System.out.println(0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f); // 1.0000001
System.out.println(0.1f + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d); // 1.000000001490116

The == Operator

Due to the previously explained nature of real numbers, it is not recommended at all to directly compare them, especially in stop condition of loops.

Consider the following:

System.out.println(0.3 == 0.1d + 0.1d + 0.1d);

or:

for (double d = 0.0; d != 0.3; d += 0.1) {
    // That is going to be an infinite loop.
}

This deficiency could be alleviated by setting a margin for numeric errors. That is, two real numbers are considered equal if their distance is smaller than a given (constant) \epsilon value.

double delta = 1.0E-5;  // error margin (epsilon)
double d1    = 0.3
double d2    = 0.1 + 0.1 + 0.1;

if (Math.abs(d1 - d2) < delta) {
    System.out.println("d1 == d2");
}

Remark. The abs() method is a member of the java.lang.Math class, where additional mathematical functions could be found.

Overflows and Underflows

Due to the limits in machine representation of numbers, every number type is assigned a minimal and a maximal value (such as Integer.MIN_VALUE and Integer.MAX_VALUE). On passing any of those value, underflow or overflow will happen, which often leads to hard-to-detect mistakes.

double big = 1.0e307 * 2000 / 2000;
System.out.println(big == 1.0e307);

When the number is multiplied, the interval covered by the double type is surpassed and the result is going to be Infinity. After dividing this value, not the original number is going to be restored.

Similarly to this, it may easily happen that adding up to numbers, like d_1 and d_2, will not make any difference, so the mathematical expectation of d_1 + d_2 \gt d_1 will not be satisfied.

System.out.println(1234.0d + 1.0e-13d == 1234.0d);

So when a real number is printed to the console, the displayed value may be the same as it would be approximated by the given representation.

System.out.println(0.1d);  // Value to be displayed: 0.1

however note that:

System.out.println(0.1 == 0.099999999999999998); // false
System.out.println(0.1 == 0.099999999999999999); // true
System.out.println(0.1 == 0.100000000000000001); // true

The approximated value can be only displayed by a special class:

// Value to be displayed: 0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal(0.1));

Arrays

Every T type there can be [] suffix added, that is, an array of such values could be built up. Arrays are also like objects, henceforth they could be accessed through references and they have attributes (or properties). As a consequence of that, arrays always know about their sizes, and they have to be instantiated before use.

int[] array1 = new int[5];
int array2[];
int array3[] = { 1, 2, 3, 4, 5 };

for (int i = 0; i < array3.length; ++i) {
    System.out.println(array3[i]);
}

Multi-dimensional arrays could be also created by the repeated use of the [] symbol. On instantiation, the first dimension must be always specified.

Compare:

int[][] multidim = new int[5][5];

or

int[][] multidim = new int[5][];

for (int i = 0; i < multidim.length; i++) {
    multidim[i] = new int[i + 1];
}

Operators

Operators from the C language may be used in the language: ==, !=, &&, ||, +, -, *, /, %, ++, --, +=, -=, *=, /=, ?:, stb.

The result type of the operators will be always the one with more elements, but int at minimum, for example:

double d = 1 / 2;  // result: 0.0
byte b = 1 + 2;    // that needs an explicit coercion

Prefix and Postfix Operators

The ++ operator may be used both as prefix and postfix one, but that changes the semantics accordingly as well.

int i = 0;
System.out.println(i++); // print, increase: "0"
System.out.println(++i); // increase, print: "2"

What is going to be the result of that (cf. C++)?

int i = 0;
System.out.println("" + i++ + ++i); // In C++, that is architecture-dependent.

What is going to be the resut of that?

int i=0;

i=i++;
i=i++;
i=++i;
System.out.println(i);

Comparison of Objects

Objects may be always compared with the equals() method. The == operator implements comparison by reference only.

For example, texts shall be compared in the following fashion:

boolean b1 = "a" == "a";       // That might be false!
boolean b2 = "a".equals("a");  // That shall always give true.

Comparison Operators in Conditions

When expressions are compared in branching conditions, try to place the constants to the left side.

boolean b = false;

if (true == b) {
    // ...
}

Exercises

  • Write a program that prints all the integers from 1 to 100. In addition to that, numbers divisble by three shall be replaced with Fizz, numbers divisible by five shall be replaced with Buzz, finally numbers divisible by both three and five shall be replaced with FizzBuzz.

  • Write a program that implements conversion between temperature degrees. Read a number and a character from the standard input: if the character is c, the number must be interpreted as a value given in Celsius, so it shall be translated to Fahrenheit. The following formula could be used for that:

    C = \frac{(F - 32) \cdot 5}{9}

    In any other case, the value shall be translated from Fahrenheit to Celsius.

  • Implement a minimalistic calculator running in the command line. Read an operator, followed by its operands, calculate the result, and print it to the standard output. The following operators shall be supported: addition (+), subtraction (-), multiplication (*), and division (/). In any other case, issue an error message, and restart reading the information.

  • Write a program that decides if the input integer is a perfect number. Integers are called perfect, if they equal to the sum of their divisors (modulo the number itself). The first four such integers are 6, 28, 496, and 8128.

  • Extend the previous solution by first reading the limits of an interval for checking perfect numbers, where only the count of such values shall be reported. If no such numbers are found there, display the message of "There are no perfect numbers in the specified interval".

  • Write a program that generates the elements of the Collatz sequence. The sequence can be computed by the following formula:

    a_n = \left\{\begin{array}{ll}\frac{1}{2} \cdot a_{n - 1} & \text{if } a_{n - 1} \text{ mod }\ 2\ =\ 0\\ 3 \cdot a_{n - 1} + 1 & \text{if } a_{n - 1} \text{ mod }\ 2\ \neq\ 0\end{array}\right.}

    The program first ask for the value of N, where N < 100. Depending on that, display the elements from a_0 = N to a_i = 1.

Related sources
Front page
Back