class IntWrapper {

    // default constructor
    public IntWrapper() {
        value = 0;
    }

    // just another constructor
    public IntWrapper(int value) {
        this.value = value;
    }

    // non-static member function allows to operate on member variables of the current (this) object (note that this function is NOT static)
    void increment() {
        this.value++;
    }

    public int value;
}

public class CallBy {

    // functions called from a static context (e.g. main) must also be declared static
    static void increment(long i) {
        // call-by-value
        i += 1; // i++
    }

    static long decrement(long i) {
        // call-by-value
        i--;
        return i;
    }

    static void increment(IntWrapper intWrapper) {
        // call-by-reference
        if (intWrapper != null) { /* todo handle NullPointer here ... */}
        intWrapper.value += 1;
    }

    public static void main(String[] args) {
        // primitive Datentypen:
        long l; // 8 byte = 64 bit
        int i; // 4 byte = 32 bit
        float f; // 4 byte = 32 bit
        double d; // 8 byte = 64 bit
        l = 42;
        System.out.println(l);
        increment(l);
        System.out.println(l);
        l = decrement(l);
        System.out.println(l);

        IntWrapper intWrapper = new IntWrapper(12);
        System.out.println(intWrapper.value);
        increment(intWrapper);
        System.out.println(intWrapper.value);
        new IntWrapper(); // call default constructor and directly discard new object
    }
}