Contents

Java - Java Building Blocks

Objectives:

  • Working with Java Primitive data types and String APIs
  • Declare and initialise variables (including casting and promoting primitive data types)
  • Identify scope of variables
  • Use local variable type inference
  • Describing and Using Objects and Classes
  • Declare and instantiate Java Objects, explain objects’ lifecycles (including creation, dereferencing by reassignment, and garbage collection)
  • Read or write to object fields

Create Objects

Calling Constructors

1
Park p = new Park();

Park is the type, p is the variable name. This gives Java a place to store a reference to the object.

new Park() will create the object.

Two key points for constructor:

  1. Constructor name matches class name.
  2. No return type.

The purpose of a constructor is to initialize fields, although you can put any code in there.

Default constructor

Some classes provide built-in methods that allow you to create new instances without using a constructor or the new keyword.

For the exam, remember that anytime a constructor is used, the new keyword is required.

Executing instance initializer blocks

The code between the braces (sometimes called “inside the braces”) is called a code block.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class Bird {
    public static void main(String[] args) {
        {
            System.out.println("Feathers");
        }
        {
            System.out.println("Snowy");
        }
    }
}

There are four code blocks in this example: a class definition, a method declaration, an inner block, and an instance initializer.

Order of initialization

  1. static fields
  2. static initializer
  3. instance fields
  4. instance initializer
  5. constructor
  6. …..

Understanding Data Types

Java applications contain two types of data: primitive types and reference types.

Using Primitive Types

A primitive is not an object in Java nor does it represent an object.

A primitive is just a single value in memory, such as a number or character.

/java_building_blocks/files/primitives.png

String is not primitive type but object.

short and char are very similar, both are stored as integral types with the same 16-bit length. But short is signed, while char is unsigned, which means char can store more positive numbers.

The compiler allows them to be used interchangeably in some cases, as shown here:

1
2
3
4
5
6
7
short bird = 'd';
char mammal = (short)83;
System.out.println(bird);   // Prints 100
System.out.println(mammal); // Prints S

short reptile = 65535;  // DOES NOT COMPILE
char fish = (short)-1;  // DOES NOT COMPILE

When a number is present in the code, it is called a literal. By default, Java assumes you are defining an int value with a numeric literal. In the following example, the number listed is bigger than what fits in an int.

1
2
3
long max = 3123456789;  // DOES NOT COMPILE
long max = 3123456789L;  // now Java knows it is a long
long max = 3123456789l;  // Better use upper case, beccause lower case l looks like the number 1.

Different based literal

  • Decimal (10 based, digits 0-9). Default
  • Binary (2 based, digits 0-1). Prefix: 0b or 0B, example: 0b1001, 0B0110
  • Octal (8 based, digits 0-7). Prefix: 0, example: 017;
  • Hexadecimal (16 based, digits 0-9 and letters A–F/a–f). Prefix: 0x or 0X, example: 0XF2, 0xeF

Underscore

1
2
3
4
5
6
7
8
int million1 = 1000000;
int million2 = 1_000_000;

double notAtStart = _1000.00; // DOES NOT COMPILE
double notAtEnd = 1000.00_; // DOES NOT COMPILE
double notByDecimal = 1000_.00; // DOES NOT COMPILE
double annoyingButLegal = 1_00_0.0_0;  // Ugly, but compiles
double reallyUgly = 1__________2;      // Also compiles

Using Reference Types

A reference type refers to an object (an instance of a class).

References do not hold the value of the object they refer to. Instead, a reference “points” to an object by storing the memory address where the object is located, a concept referred to as a pointer.

A value is assigned to a reference in one of two ways:

  • A reference can be assigned to another object of the same or compatible type.
  • A reference can be assigned to a new object using the new keyword.

Primitive vs Reference Data Types

  • reference types can be assigned null, while primitive types will give you a compiler error if you attempt to assign them null.
  • reference types can be used to call methods, assuming the reference is not null. Primitives do not have methods declared on them.
  • all the primitive types have lowercase type names, while all classes that come with Java begin with uppercase (standard practice).

Declaring variables

Declaring and initializing variables.

Identify identifiers

An identifier is the name of a variable, method, class, interface, or package.

There are only 4 rules to remember for legal identifiers:

  1. Identifiers must begin with a letter, a $ symbol, or a _ symbol.
  2. Identifiers can include numbers but not start with them.
  3. Since Java 9, a single underscore _ is not allowed as an identifier.
  4. Cannot use the same name as a Java reserved word. Remember that Java is case sensitive, so you can use versions of the keywords that only differ in case. Please don’t, though.

Reserved Keywords /java_building_blocks/files/keywords.png

camelCase and snake_case style.

Declaring multiple variables

1
int i1, i2, i3 = 0;

Initializing variables

local, instance, and class variables.

Creating local variables

A local variable is a variable defined within a constructor, method, or initializer block.

Local variables do not have a default value and must be initialized before use. Otherwise, compile error.

/java_building_blocks/files/localvar.png

Passing constructor and method parameters

Variables passed to a constructor or method are called constructor parameters or method parameters, respectively. These parameters are local variables that have been pre-initialized.

1
2
3
4
5
6
public void findAnswer(boolean check) {}

public void checkAnswer() {
   boolean value;
   findAnswer(value);  // DOES NOT COMPILE
}

Define instance and class variables

An instance variable, often called a field, is a value defined within a specific instance of an object.

A class variable (static) is one that is defined on the class level and shared among all instances of the class.

Instance and class variables do not require you to initialize them, they have default value.

null for an object and 0/false for a primitive. (for char, the default value is ‘\u0000’ -> NUL)

Introduce var

Starting in Java 10, you have the option of using the keyword var instead of the type for local variables under certain conditions. To use this feature, you just type var instead of the primitive or reference type. Example:

1
2
3
4
public void whatTypeAmI() {
   var name = "Hello";
   var size = 7;
}

The formal name of this feature is local variable type inference, so it only works for local variables.

1
2
3
 public class VarKeyword {
   var tricky = "Hello"; // DOES NOT COMPILE
}

When you type var, you are instructing the compiler to determine the type for you. but the type of var can’t change at runtime.

1
2
3
var apples = (short)10;
apples = (byte)5;
apples = 1_000_000;  // DOES NOT COMPILE

Example

Using var, declaration and initialization of a local variable should be in a single statement.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public void doesThisCompile(boolean check) {
     var question;
     question = 1;
     var answer;
     if (check) {
        answer = 2;
     } else {
        answer = 3;
     }
     System.out.println(answer);
}

var does not support multiple variable declaration.

1
var a = 2, b = 3;  // DOES NOT COMPILE

While a var cannot be initialized with a null value without a type, it can be assigned a null value after it is declared.

1
2
3
4
5
var n = null;      // DOES NOT COMPILE
var m = "myData";
m = null;
var num = 4;
num = null;   // DOES NOT COMPILE

a var can be initialized to a null value if the type is specified.

1
var n = (String)null;

var cannot be used in constructors, method parameters, or instance, class variables.

1
2
3
public int addition(var a, var b) {  // DOES NOT COMPILE
   return a + b;
}

The following example is legal:

1
2
3
4
5
6
7
8
9
package var;
public class Var {
   public void var() {
      var var = "var";
   }
   public void Var() {
      Var var = new Var();
   }
}

While var is not a reserved word and allowed to be used as an identifier, it is considered a reserved type name. A reserved type name means it cannot be used to define a type, such as a class, interface, or enum.

1
2
3
4
public class var {  // DOES NOT COMPILE
   public var() {
   }
}

Rules of using var

  1. A var is used as a local variable in a constructor, method, or initializer block.
  2. A var cannot be used in constructor parameters, method parameters, instance variables, or class variables.
  3. A var is always initialized on the same line (or statement) where it is declared.
  4. The value of a var can change, but the type cannot.
  5. A var cannot be initialized with a null value without a type.
  6. A var is not permitted in a multiple-variable declaration.
  7. A var is a reserved type name but not a reserved word, meaning it can be used as an identifier except as a class, interface, or enum name.

Managing Variable Scope

  • Local variables: In scope from declaration to end of block
  • Instance variables: In scope from declaration until object eligible for garbage collection
  • Class variables: In scope from declaration until program ends

A constructor can access all instance variables. An instance method can access all instance variables.

Destroying Objects

All Java objects are stored in your program memory’s heap. The heap, which is also referred to as the free store, represents a large pool of unused memory allocated to your Java application

Failure to properly handle garbage collection can lead to catastrophic performance and security problems: out of memory, and security issue.

Understanding Garbage Collection

Garbage collection refers to the process of automatically freeing memory on the heap by deleting objects that are no longer reachable in your program.

Eligible for Garbage Collection

As a developer, the most interesting part of garbage collection is determining when the memory belonging to an object can be reclaimed.

In Java and other languages, eligible for garbage collection refers to an object’s state of no longer being accessible in a program and therefore able to be garbage collected.

An object that’s eligible for garbage collection will not be immediately garbage collected, and it is not under your control.

As a programmer, the most important thing you can do to limit out-of- memory problems is to make sure objects are eligible for garbage collection once they are no longer needed. It is the JVM’s responsibility to actually perform the garbage collection.

Calling System.gc()

System.gc() helps support garbage collection that can be called at any time. but it does not guarantee anything, becuase JVM is free to ignore the request.

It is never guaranteed to be called by the JVM. — shortly before a program runs out of memory and throws an OutOfMemoryError , the JVM will try to perform garbage collection, but it’s not guaranteed to succeed.

Tracking Eligibility

An object will remain on the heap until it is no longer reachable. An object is no longer reachable when one of two situations occurs:

  1. The object no longer has any references pointing to it.
  2. All references to the object have gone out of scope (local variables in method out of the method scope).

finalize()

the garbage collector would call the finalize() method once. If the garbage collector didn’t run, there was no call to finalize() . If the garbage collector failed to collect the object and tried again later, there was no second call to finalize() .

finalize() can run zero or one times. It cannot run twice.