Java Building Blocks

Creating Objects

Calling constructors

When you use a constructor

Park p = new Park();

First you declare the type you’re declaring Park and give the variable a name p. This gives a place to store a reference to an object.

Then you write new Park(); to actually create the object .

Structure of a constructor
  • Its name matches the name of the class
  • It has no return type
public class Meerkat {
	public Meerkat() { // this is a constructor
	}

	public void Meerkat() {
	// this is a method with a Capital letter. It will compile
	// 	but this is no constructor.
	}
}

The purpose of a constructor is to initialize fields but you may also do this when they’re declared.

public class Meerkat {
	int numLegs = 4; // initialize on declaration
	String name;

	public Meerkat() {
		name = "Ramón" // initialize on constructor
	}
}

The compiler automatically gives a do nothing constructor.

Executing Instance Initializer Blocks

The code between braces {} is calle a code block. Sometimes they’re inside a method, but other times they’re outside a method. These are called instance initializers.

// at this example we have 4 code blocks.
public class Meerkat {
	public static void main(String...args) {
// this is NOT an instance initializer, as this is inside a method
		{ System.out.println("oh noes!"); }
	}

	// this is an instance initializer
	{ System.out.println("oh noes!"); }
}

Following Orders of Initialization

  1. Fields and instance initializer blocks are run in the order in which they appear in the file
  2. The constructor runs last. After all fields and instance initializer blocks have run.
public class Meerkat {
	private String name = "Jorge";
	{ System.out.println("setting field"); }

	public Meerkat() {
		name = "Ramón";
		System.out.println("setting constructor");
	}

	public static void main(String...args) {
		System.out.println("starting program");
		Meerkat meerkat = new Meerkat();
		System.out.println(meerkat.name);
	}
}

This will print

starting program
setting field
setting constructor
Ramón

You can’t refer to a variable that’s not been initialized

public class Meerkat {
	{ System.out.println(name); } // THIS WON'T COMPILE
	private String name = "Jorge";
}

Understanding Data Types

Java has 2 data types: primitives and references.

Primitive Types

A primitive is not an Object nor does it represent a value. A primitive is just a single value in memory, such as a number or a char.

The exam assumes you’re well versed in these eight primitive types, their sizes and what they’re able to store.

(do not memorize)

keyword type example
boolean true or false true
byte 8-bit integral value 123
short 16-bit iv 123
int 32-bit iv 123
long 64-bit iv 123L
float 32-bit floating-point 1234.56f
double 64-bit floating-point 123.456
char 16-bit unicode value ‘a’

String is not a primitive.

  • Float and double are used for floating-point (decimal) values. Float also requires the letter f following.
  • Byte, short, int and long are used for numbers without decimal points.
  • Each numeric type uses as many bits as the previous type.
  • All of the numeric types are signed in Java.
  • All of the numeric types are signed in Java. f.e. byte ranges from -128 to 127 (don’t forget 0!).

Short & Char

short and char are closely related. Both are stored as integral types with 16-bit length.

The difference is that short is signed (positive and negative values) while char is unsigned, which means its range is positive, including 0. Char may also hold higher values than short but cannot hold negative values.

The compiler allows them to be used interchangeably in some cases

// this compiles
short bird = 'd'
char mammal = (short) 83;

println(bird); // prints 100
println(mammal); // prints S

This comes with restrictions though. If you try to set a value outside the range of short or char, the compiler will report an error.

 // both would compile if they were swapped.
 short reptile = 6553; // DOES NOT COMPILE
 char fish = (short) -1; // DOES NOT COMPILE

Writting literals

When a number is presented in code, it’s called a literal. By default, java expects you to define an int value.

long max = 3123456789; // does not compile
long max 3123456789L; // compiles
Other bases
  • Octal (digits 0-7) uses the number 0 as a prefix - 017
  • Hexadecimal (digits 0-9 and letters A-F/a-f) uses 0x or 0X as a prefix. This is case-insensitive - 0xFF is the same as 0XfF
  • Binary (digits 0-1) uses the number 0 followed by b or B as prefix - 0b10 or 0B10
Literals and underscores

You can have underscores in numbers to make them easier to read

// both are valid
int million1 = 1000000;
int million2 = 1_000_000;

You can add _ anywhere except at the beginning of a literal, the end, right before a decimal point, or right after a decimal point. You can also place multiple underscores together.

double notAtStart = _1000.00; // doesn't compile
double notAtEnd = 1000.00_; // doesn't compile
double notByDecimal = 1000_.00; // doesn't compile

double annoyingButLegal = 1_00_0.0_0; // compiles
double dontDoThis = 1________2; // compiles

Reference types

References do not hold the value of the object they refer to. Instead, they point to an object by storing the memory address where the object is located. This is called a pointer. Java does not allow you to see what the physical memory address is. You can only use the reference to the object.

A value is assigned to a reference in two ways:

  • A reference can be assigned to a new object using the new keyword.
  • A reference can be assigned to another object of the same (or compatible) type.
// new references
today = new java.util.Date();
greeting = new String("How are you?");
Distinguishing between Primitives and Reference types

Reference types can be assigned null, meanwhile primitives will throw a compile error. Primitives do not have methods. REMEMBER: String is not primitive.

String s = null; // COMPILES
Integer value = null; // COMPILES
int value = null; // COMPILE ERROR

Declaring values

A variable is a name for a piece of memory that stores data. To declare it you state the variable type along with giving it a name. To initialize a variable you just type it’s name followed by an equal sign.

String zooName; // variable declaration
zooName = "Zoos are bad"; // variable initialization
String zooName = "Don't go to zoos"; // both at the same time

Identifying identifiers

  • Identifiers must begin by a letter, $ or _
  • Identifiers can hold numbers, but not start by a number
  • Since Java9, a single underscore _ is not a valid identifier
  • You cannot use reserved keywords
// these are legal examples
long okidentifier;
float $OK2Identifier;
boolean _alsoOK1d3ntifi3r;
char __SStillOkbutKnotsonice$;

// these are NOT legal
int 3DPointClass; // identifiers cannot begin with a number
byte hollywood@vine; // @ is not a letter, digit, $ or _
String *$coffee; // * is not a letter, digit, $ or _
double public; // public is a reserved word
short _; // a single underscore is not allowed

Never start a class by $, as the compiler uses this symbol for some files.

snake_case

Snake case is valid, but CamelCase is prefered.

thisIsValid();
this_is_also_valid();

Declaring Multiple Variables

You can also declare and initialize multiple variables per statement as long as they’re all the same type.

void sanFence() {
	String s1, s2; // 2 vars declared
	String s3 = "yes", s4 = "no"; // 2 vars initialized
	int i1, i2, i3 = 0; // 3 declared, 1 initialized!
	int num, String value; // DOES NOT COMPILE
}

more examples

boolean b1, b2; // legal
String s1 = "1", s2; // legal
double d1, double d2; // not legal because of second "double"
int i1; int i2; // legal
int i3; i4; // not legal because i4 hasn't any type

Initializing variables

Creating local variables

A local variable is defined inside a constructor, method or initializer block. They do not have a default value and must be initialized before used.

public void findAnswer(boolean check) {
	int answer;
	int otherAnswer;
	int branch;
	if(check) {
		branch = 1;
		answer = 1;
	} else {
		answer = 2;
	}
	System.out.println(answer);
	System.out.println(branch); // DOES NOT COMPILE
}

Defining Instance and Class Variables

An instance variable or field is a value defined within a specific instance of an object.
A class variable is one defined on the class level and shared among all its instances. They use the static keyword.

Default values

You don’t need to initialize instance and class variables. They’re automatically given a default value.

Var type Default Value
boolean false
byte, short, int, long 0
float, double 0.0
char ‘/u0000’ (NUL)
Objects null

Introducing var

Starting in Java 10, there’s the option to use var (local variable type inference) instead of the type for local variables under certain conditions.

public void whatTypeAmI() {
	var name = "Carlos";
	var size = 7;
}

This is only valid for local variables.

public class varKeyword {
	var something = "Hello"; // DOES NOT COMPILE!
}

Type inference of var

When you type var, you’re telling the compiler to determine the type for you. It’s type cannot change at runtime.

public void reassignment() {
	var number = 7;
	number = 4;
	number = "five"; // DOES NOT COMPILE
}
// this compiles
public void break() {
	var silly =
		1;
}

To use var the compiler looks just at the line of the declaration. Since they’re not assigned values when defined, the compiler does not know what to do with them.

public void doesThisCompile(boolean check) {
	var question:
	question = 1; // DOES NOT COMPILE
	var answer;
	if(check) {
		answer = 3;
	} else {
		answer = 4;
	}
	System.out.println(answer);
}

Java does not allow var in multiple variable declarations nor a null declaration

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

After it’s already been initialized, var may hold null depending on the underlying type.

var str = "myData";
str = null; // compiles

var number = 4;
number = null; // DOES NOT COMPILE

But var can be initiallized to null if the type is specified

var o = (String) null; // compiles

This does not compile as as var is only valid for local variables. Not parameters. Be aware of vars used at constructors, method parameters or instance variables.

public int addition(var a, var b) {
	return a + b; // DOES NOT COMPILE. Only local variables, not params.
}

The following code compiles, as var is not a keyword and naming a local variable “var” is legal. But it cannot be used to define a class, interface or Enum (but you can use Var).

package var;

public class Var {
	public void var() {
		var var = "Var";
	}
	public void Var() {
		Var var = new Var();
	}
}
public class var { // DOES NOT COMPILE
	public var() {
	}
}
Var rules
  1. Is used as a local variable inside at constructor, method or initializer block
  2. Cannot be used as constructor / method parameters, instance / class variables
  3. A var is always initialized on the same line it’s declared
  4. Its vale may change, but its 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. It can be used as an identifier except for class, interface or enum name.

Managing variable scope

Here there’re 2 local variables. Method parameters are also local variables as they have a local scope.

public void eat(int piecesOfCheese) {
	int bitesOfCheese = 1;
}

Limiting scope

local variables can never have a scope larger than the method they’re declared at.

public void eatIfHungry(boolean hungry) {
	if(hungry) {
		int bitesOfCheese = 1;
	}
	System.out.println(bitesOfCheese); // DOES NOT COMPIlE
}

(!) look for exams to practice variable scope identification (!)

Destroying objects

The JVM takes care automatically of this for you. Java has a garbage collector that looks for objects that aren’t needed anymore. All your Java Objecs are stored in your program memory’s heap. The heap (or free store), represents a large pool of unused memory allocated to your Java application.

Understanding Garbage Collection

It refers to the process of automatically freeing memory on the heap by deleting objects that are no longer reachable.

Eligible for garbage collection

This refers to an object’s state of no longer bein accessible in a program and therefore able to be garbage collected. They won’t be immediately be collected. When they’ll be is out of your control.

Calling System.gc();

Java includes the built-in System.gc(); method to help support garbage collection. This merely suggests that the JVM kick-off garbage collection. The JVM is free to ignore the requests.

Shortly before a program runs out of memory and throws a OutOfMemoryError the JVM will try to perform GC but it’s not guaranteed to success.

Tracing Eligibility

An object is no longer reachable when

  • The object no longer has any references pointing to it
  • All references to the object have gone out of scope

Objects vs references!

Do not confuse objects with references.

Reference: variable that has a name and can be used to access the contents of an object. It can be assigned to another reference, passed to or returned from a method. All references have the same size.

Object: It sits on the heap without a name. You have no way to access it except from a reference. An object cannot be passed to or returned from a method. It’s the object that gets garbaged collected. Not the reference.

finalize()

(This is out of scope)
Java allows to implement a method called finalize(). This method can run 0 or 1 time, but it cannot run twice.

Summary

Constructors create Java objects. A constructor is a method, matching the class name and omitting the return type. When an object is instantiated, fields and blocks of code are initialized first. Then the constructor is run.

Primitive types are the basic building blocks of java. They’re assembled into reference types. Reference types can have methods and be assigned to null. Numeric literals are allowed to contain underscores _ as long as they don’t start or end the literal and are not next to a decimal point.

Declaring a variable involves stating the data type and giving the variable a name. Variables that represent fields in a class are automatically given default values during object instantiation. Local variables must be specifically initialized before they can be used. Identifiers may contain letters, numbers, $ or _. Identifiers may not begin with numbers.

Local variables may use the var keyword instead of the actual type. When using var, the type is set once at compile time and does not change.

Scope refer to that portion of code where a variable can be accessed. There are three kinds of variables in Java depending on their scope: instance variables, class variables and local variables. Local variables are declared within a constructor, method or initializer block.

Garbage collection is responsible for removing objects from memory when they can never be used again. An object becomes eligible for garbage collection when there are no more references to it or its references have all gone out of scope.

Exam essentials

Be able to recognize a constructor. A constructor has the same name as the class. It looks like a method without a return type.

Be able to identify legal and illegal declarations and initialization. Multiple variables can be declared and initialized in the same statement when they share a type. Local variables require an explicit initialization; others use the default value for that type. Identifiers may contain letters, numbers, $ , or _ , although they may not begin with numbers. Also, you cannot define an identifier that is just a single underscore character _ . Numeric literals may contain underscores between two digits, such as 1000 , but not in other places, such as _100.0_ . Numeric literals can begin with 1–9 , 0 , 0x , 0X , 0b , and 0B , with the latter four indicating a change of numeric base.

Be able to use var correctly. A var is used for a local variable inside a constructor, a method, or an initializer block. It cannot be used for constructor parameters, method parameters, instance variables, or class variables. A var is initialized on the same line where it is declared, and while it can change value, it cannot change type. A var cannot be initialized with a null value without a type, nor can it be used in multiple variable declara- tions. Finally, var is not a reserved word in Java and can be used as a variable name.

Be able to determine where variables go into and out of scope. All variables go into scope when they are declared. Local variables go out of scope when the block they are declared in ends. Instance variables go out of scope when the object is eligible for garbage collection. Class variables remain in scope as long as the program is running.

Know how to identify when an object is eligible for garbage collection. Draw a diagram to keep track of references and objects as you trace the code. When no arrows point to a box (object), it is eligible for garbage collection.