Java Fundamentals Tutorial: The java.lang Package

10. The java.lang Package

Exploring the Main Java Library

10.1. Primitive Wrappers

  • The java.lang package includes a class for each Java primitive type:

    • Boolean, Byte, Short, Character, Integer, Float, Long, Double, Void
  • Used for:

    • Storing primitives in Object based collections
    • Parsing/decoding primitives from Strings, for example:

      int value = Integer.parseInt(str);
    • Converting/encoding primitives to Strings
    • Range definitions (e.g. Byte.MAX_VALUE)
    • Toolbox of convenience methods — many of them static (e.g., isLetter(), toLowerCase(), reverseBytes(), isInfinite(), isNaN())

Any object in Java can be assigned to type java.lang.Object. This means that generic collections can be implemented that deal with java.lang.Objects, and not care about the actual types. Unfortunately, this does not work for primitives, because they are not Objects. But with their wrapper classes, primitives can easily move to/from Objects.

For example:

int i = 5;
List list = new LinkedList();
list.add(new Integer(i));
Integer intObj = (Integer) list.get(0);
int j = intObj.intValue();
System.out.println(i == j); // prints true
[Note]Note

Since Java 5, Java supports implicit wrapping/unwrapping of primitives as needed. This compiler-feature is called auto-boxing/auto-unboxing. The following is legal:

Integer j = 5 + 10;
int k = new Integer(5) + new Integer(10);
Float f = new Float(10) * new Float (3);
listOfLongs.add(123123123L);
long l = (Long) listOfLongs.get(0);
[Warning]Warning

This auto-boxing feature can lead to legal but very inefficient code. For example, in the following loop, the index variable is accidentally declared as a Long rather than a long, leading to the creation of a billion extraneous objects compared to using the primitive type:

for (Long i = 0; i <= 1000000000; i++) {
    // This will take a very long time to execute
}

10.2. String and StringBuilder

  • String

    • Automatically created with double quotes
    • Pooled (interned) to save memory
    • Immutable — once created cannot change
    • Concatenated using the expensive + operator
    • Many methods for string manipulation/searching
  • StringBuilder and StringBuffer

    • Mutable — can quickly grow and shrink as needed
    • Few methods modifying the buffer: append(), insert(), delete(), replace()
    • Use toString() if you need to get a String representation of the object’s content
    • StringBuffer is synchronized for thread-safe access in multithreaded applications
    • Use StringBuilder for better performance unless you plan to access the object from multiple threads

In a single-threaded context (as is generally the case), StringBuilder is faster than StringBuffer. But both are 1000+ times faster than repeated String concatenation.

public class StringConcatenationTest {
    public static void main (String args[]) {
        final int count = Integer.parseInt(args[0]);
        String s = "";
        long time = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            s += ".";
        }
        time = System.currentTimeMillis() - time;
        System.out.println(time);
    }
}

public class StringBuilderConcatenationTest {
    public static void main (String args[]) {
        final int count = Integer.parseInt(args[0]);
        StringBuilder sb = new StringBuilder();
        long time = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            sb.append(".");
        }
        sb.trimToSize();
        time = System.currentTimeMillis() - time;
        System.out.println(time);
    }
}

10.3. The Math Class

  • The Math class contains static methods implementing math functions, such as:

    • Trigonometry: sin(), cos(), tan(), etc.
    • Rounding: round(), floor(), ceil(), rint()
    • Logarithmic: log(), log10()
    • Exponentiation/root: sqrt(), cbrt(), pow(), exp()
    • Utility: abs(), min(), max(), random(), hypot(), toDegrees(), toRadians()
  • Match also includes constants for PI and E.

In addition to java.lang.Math, Java ships with java.lang.StrictMath, which has the same functions as Math. What’s different with StrictMath is that its functions produce the same results as certain published algorithms, namely the C-based netlib and "Freely Distributable Math Library".

Java also comes with java.math package which includes:

  • BigDecimal - Immutable arbitrary-precision signed decimal number.
  • BigInteger - Immutable arbitrary-precision integer.

These two classes have their own methods for various operations, including arithmetic and bitwise.

10.4. The System Class

  • The System class provides access to your system and the JVM, including:

    • A context for stdin, stdout, stderr streams
    • Environmental variables and JVM properties
    • System time in milliseconds or nanoseconds
    • Loading external [native] libraries
    • Terminating the JVM
    • Efficient array copying

The java.lang.System class gives access to the JVM system, although it is used most often for printing to stdout:

System.out.println("Hello World");

You should avoid invoking:

  • System.exit(int status) — This method forces termination of all threads in the JVM. According the Sun’s Portability Cookbook:

    System.exit() should be reserved for a catastrophic error exit, or for cases when a program is intended for use as a utility in a command script that may depend on the program’s exit code.

  • System.gc() — There is no guarantee that the JVM will run the garbage collection in response to this method. Let the JVM manage garbage collection.
  • System.runFinalization() - Do not depend on object finalization. It is not guaranteed to run before your application terminates.

System properties give you information about the JVM and the context in which it is running (e.g., the user, present working directory, etc.). Properties should not be used for global variables, but if you do set your own properties, do so in your own namespace. Properties are standardized across platforms.

Environmental variables are system dependent (configured by the shell), so they are generally not portable across platforms.