Java Fundamentals Tutorial: Data Types

3. Data Types

Primitive Data Types in Java

3.1. Declaring and Assigning Variables

  • The syntax for declaring a variable is:

    DataType variableName[ = expression];

  • Examples:

    float j;
    int i = 5 + 3;
  • Java is a strongly typed language

    • Every variable must have an explicit type
    • Expressions assigned to the variable must be a compatible type
  • Local variables (declared within methods) must be declared and initialized before they are used
  • Class and instance variables can be declared anywhere and are initialized to defaults:

    • 0 for numerical typed variables
    • false for boolean variables
    • null for object reference variables

In contrast to a language like C, in Java the local variables do not have to be declared at the beginning of program blocks (defined by curly braces). They can be declared when they need to be used.

public static void main(String[] args) {
    System.out.print("Number of arguments: ");
    int len = args.length;
    System.out.println(len);
}

Multiple variables can be declared on a singe line: int i, j, k;

Multiple variables can be initialized at the same time: i = j = k = 5;

There is an generally accepted naming convention in the Java community to start variable names with a lower-case letter and use a so-called CamelCase (or CamelHump) notation, where the first letter of each subsequent word is capitalized, but the words are joined together (i.e. no dashes or underscores).

3.2. Java Primitive Types

Table 2. Java Primitive Types

TypeSizeRangeDefault*

boolean

1 bit

true or false

false

byte

8 bits

[-128, 127]

0

short

16 bits

[-32,768, 32,767]

0

char

16 bits

['\u0000', '\uffff'] or [0, 65535]

'\u0000'

int

32 bits

[-2,147,483,648 to 2,147,483,647]

0

long

64 bits

[-263, 263-1]

0

float

32 bits

32-bit IEEE 754 floating-point

0.0

double

64 bits

64-bit IEEE 754 floating-point

0.0


* The default value for uninitialized class or instance variables of this type.

Even though Java is a fully object oriented language, for performance reasons it defines eight primitive data types. All of these types also have their respective wrapper classes (for true OO) in the default java.lang package (which we will see later).

In addition to the eight primitive types, there is also a concept of a void type, which is only used for a method return type (i.e. to indicate that nothing is returned).

Examples: 

boolean bln = true; // booleans can only be 'true' or 'false'
byte b = 0x20;      // using hexadecimal notation
short s = 500;      // small integer
char c = 'A';       // must use single quotes to denote characters
char tab = '\t';    // other specials: \n, \r, \f, \b, \\, \', \"
int i = 1000000;    // decimal notation
int j = 0x3FA0B3;   // hexadecimal notation
int k = 0777;       // octal notation
float f = 1.5f;     // trailing 'f' distinguishes from double
long l = 2000000L;  // trailing 'L' distinguishes from int
double pi = 3.141592653589793;  // doubles are higher precision
double large = 1.3e100;     // using the exponent notation

3.3. Conversion Between Types

  • Implicit up-casting: a lower-precision type is automatically converted to a higher precision type if needed:

    int i = 'A';
  • Explicit down-casting: a manual conversion is required if there is a potential for a loss of precision, using the notation: (lowerPrecType) higherPrecValue

    int i = (int) 123.456;

Figure 3. Implicit up-casting of primitive types

../../../static/bookshelf/java_fundamentals_tutorial/images/Primitives.png

[Note]Note

Java has a clear separation between numerical types and booleans. They are not interchangeable. This means that an int cannot be used in place of a boolean expression, for example in an if statement:

int someInteger = 0;

/*
 * This will not compile, because someInteger is not
 * a boolean type (or a boolean expression)
 */

if (someInteger) {
    // Do something
}

// This will compile
if (someInteger != 0) {
    // Do something
}
[Note]Note

Strings are not converted automatically into integers or other primitive data types they may represent. Strings must be parsed:

int myInt = Integer.parseInt(args[0]);

3.4. Declaring Arrays

  • An array is a simple data structure to hold a series of data elements of the same type.
  • Declare an array variable in one of two ways:

    • With [] after the variable type: int[] values;
    • With [] after the variable name: int values[];
  • Arrays can be single- or multi-dimensional.

    • A two dimensional array could be declared with: double values[][];
  • Array elements are integer indexed.

    • Use arrayName.length to get the array length.
    • Elements are indexed from 0 to arrayName.length - 1
    • Access individual elements with arrayName[index]

Examples of array declarations:

String[] args;      // single-dimensional array of String objects
int[] numbers;      // single-dimensional array of ints
byte[] buffer;      // single-dimensional array of bytes
short[][] shorts;   // double-dimensional array of shorts

To get the array length:

int arrayLength = myNums.length;    // 5
int nameLength = name.length;       // 3
int bufLength = buf[2].length;      // 1024

3.5. Creating and Initializing Array Objects

  • Arrays are implemented as objects.
  • You can use the new operator to create an array of an indicated type and length, as in:

    int[] values = new int[10];
    • Elements are initialized automatically to type-appropriate default values.
  • Alternatively, you can use an array initializer to create an array with a set of initial values.

    • The array initializer consists of a sequence of comma-separated expressions of an appropriate type, enclosed within braces. For example:

      int[] values = {5, 4, 3, 2, 1};
    • The array object is sized automatically based on the number of initial values.

Examples of array initializations:

int[] myNums = { 1, 3, 5, 7, 9 };   // 5 elements
char[] name = new char[3];
name[0] = 'T';
name[1] = 'o';
name[2] = 'm';
short[][] matrix = { {1,4,7}, {5,6,3}, {2,8,9} };
byte[][] bufs = new byte[10][1024];

To access an element of an array:

int myNum = myNums[3];      // 7
char firstLetter = name[0]; // 'T'
matrix[1][2] = 0;       // used to be 3

3.6. Modifying Array Size

  • Once created, the size of an array cannot change.

    • If you need to grow an array, you must create a larger array object of the same type, and then copy the elements from the old array to the new array.
    • The System.arraycopy() method is an efficient way to copy the existing elements to the new array. For example:

      int[] values = {5, 4, 3, 2, 1}; // A 5-element int array
      int[] newValues = new int[10];  // A 10-element int array
      
      // Copy all elements from values to newValues
      System.arraycopy(values, 0, newValues, 0, values.length);
      
      // Assign the array back to values
      values = newValues;

In the example above, the values and newValues variables do not actually contain the arrays, they refer to the array objects. We’ll examine this concept more in the Object Oriented module.

3.7. Strings

  • Strings are objects.

    • In Java, strings are instances of the String class.
    • Unlike C/C++, you can’t treat a String directly as an array of chars.
    • There are methods that allow you to create a String from an array of chars, and vice versa.
  • Enclosing a sequence of literal characters within double quotes automatically creates a String object: "this is my string"
  • Strings are immutable

    • Once created, a String cannot be modified.
    • But a String has methods to perform various transformations, each returning a new String object.
  • The String class has many methods, including: length, replace, substring, indexOf, equals, trim, split, toUpperCase, endsWith, etc.

To get the length of a String do:

String s = "my string";
int len = s.length();

To parse a primitive value from a String, do:

boolean b = Boolean.valueOf(s).booleanValue();
byte b = Byte.parseByte(s);
short s = Short.parseShort(s);
char c = s.charAt(0);
int i = Integer.parseInt(s);
float f = Float.parseFloat(s);
long l = Long.parseLong(s);
double d = Double.parseDouble(s);

We will examine the String API later in class.