Java 11 Developer Certification - Read or Write to Object fields

December 03, 2020

What we are covering in this lesson

  1. Type of fields in a class
  2. Default values for the fields
  3. The this keyword
  4. Valid/Invalid uses of this keyword
  5. Code Examples

Type of fields in a class

We have already in the previous section that static and non-static fields are assigned default values, whereas local variables are not.

We will now have a look at the different types of fields we can have in a Java class.

static fields

  • Also known as class variables
  • There will be exist only one bucket for a static field
  • This placeholder bucket will be associated with the class and NOT the objects of that type

non-static fields

  • Also knows as instance variables
  • Every instantiated object has its own placeholder or area for that data

final fields

  • Both static and non-static fields, can be declared final.
  • The final field can be declared with no assigned value (blank). But, only if an associated initializer sets it:

    • A blank final class variable requires a static initializer of the class, to set the variable in which it’s declared. Otherwise, a compile time error occurs.
    • A blank final instance variable must have a value at the end of every constructor of the class in which it’s declared. Otherwise, a compile time error occurs.

transient fields

  • Transient fields won’t get serialised or persisted.
  • Such fields are useful when we are transferring data over network and using the concepts of serialization and deserialization.

volatile fields

  • The Java Memory Model ensures that all threads see a consistent value for variables which are declared volatile.

Default values for the fields

As we have seen in the previous sections, the the instance and class fields are initialized to the below default values

  • boolean defaults to false
  • primitive numeric fields default to a representation of 0 appropriate to that type
  • an object reference defaults to null

One more important to note is that the final fields are not initialised to default values and must be set in an initialization statement of some sort. Once set, the final field values cannot be changed.

The this keyword

this is a keyword in Java, which has the following meanings:

  • this is a reference variable and you can assign it to other reference variables, but you cannot assign any other value to this, including null.
  • this is a qualifier that can be used to access any instance variables on the current objects.
  • It is considered best practise to use this when accessing instance variables in Java.
  • The this() is a call to the current object’s no args constructor.
  • If there are other constructors defined for that class, we can call the appropriate constructor using this (not the constructor name) and passing the appropriate parameters that match with the constructor we were trying to call.

We will have a look at the code level for this in the below sections.

Valid/Invalid uses of this keyword

Below are the valid uses of this keyword

Valid Uses of this keyword Example
Access attributed in non-static methods on the current instance String getName() { return this.name; }
Call another constructor (with or without parameter) this(); this(3); this("MaxCode");
Inside Constructors, but it should always be the first statement within constructor test() { this("MaxCode"); System.out.println("Inside no arg constructor"); }
Inside Initializer { this.name = "MaxCode"; }
Assigning variable to this Object o = this;
return this from a parameter Object returnObj() {return this;}

Now that we have looked at the valid ones, lets have a look at some of the invalid uses of this keyword and where this should be avoided

Invalid Uses of this keyword Example
Cannot access instance attributes using this in static method static void updateName() { this.name = this.name + "New"; }
Inside constructors but at a wrong place (this should always be the first statement inside constructor) test() { System.out.println("Inside no arg constructor"); this("MaxCode"); }
Cannot use this in static initializer static { this.name = "MaxCode"; }
Cannot set the value of this, as Java assigns the value of this automatically, when the class is instantiated. this = null; this = myObj;

Code Examples

Now we will have a look at the code examples which would help us understand how to use static and non static fields, and various ways to refer to these fields.

package maxCode.online.Initializers;

class SuperClass {
	static String name;
	String instanceName;

	SuperClass(String name, String instanceName) {
		// Refer to static field using Class name with dot operator
		SuperClass.name = name;

		// Refer to non-static field using this reference with
		// dot operator
		this.instanceName = instanceName;
	}

	public String toString() {
		return "name: " + SuperClass.name + ", instanceName: " + this.instanceName;
	}
}

public class StaticFieldSamples {
	public static void main(String[] args) {
		SuperClass a, b, c;

		// Create objects and print in same statement
		System.out.println(a = new SuperClass("A", "One"));
		System.out.println(b = new SuperClass("B", "Two"));
		System.out.println(c = new SuperClass("C", "Three"));
		System.out.println("-------------------------------");

		// Review state of objects after all 3 have been created
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
	}
}

Output

name: A, instanceName: One
name: B, instanceName: Two
name: C, instanceName: Three
-------------------------------
name: C, instanceName: One
name: C, instanceName: Two
name: C, instanceName: Three

In the above code, we have a new class SuperClass, a static variable name and an instance variable instanceName. We are then referring a static field using the class name SuperClass.name and referring the instance variable using this.instanceName.

The main method instantiates the SuperClass passing various arguments and then printing the same. The output clearly shows that the static variable name has the same value for all the instances whereas the instance variable instanceName has different values for each instance.

Now lets look at the final fields from code perspective

package maxCode.online.Initializers;

class Constants {
	// Final static class variables are considered constants.
	// There is one reference to them (static)
	// they cannot be altered (final)
	final static String ONE = "final static field ONE = one";
	final static String TWO = "final static field TWO = two";

	// below code will give Compile error if static intitializer removed
	final static String THREE;

	static {
		THREE = "final static field THREE = three";
	}
}

public class FinalFields {
	// You can create final instance variables that are not static
	final String FOUR;

	// initializer sets final field four
	{
		FOUR = "final field FOUR = four";
		// FIVE = "final field FIVE = five";
	}

	final String FIVE;

	// constructor sets final field five
	FinalFields() {
		FIVE = "final field FIVE = five";
	}

	// new constructor takes an argument
	FinalFields(String value) {
		FIVE = "final field FIVE = " + value;
	}

	public static void main(String[] args) {
		// Access and print the constants.
		System.out.println(Constants.ONE);
		System.out.println(Constants.TWO);
		System.out.println(Constants.THREE);

		System.out.println((new FinalFields()));

		System.out.println("----------------------------");
		System.out.println((new FinalFields("six")));
	}

	public String toString() {
		return FOUR + "\n" + FIVE;
	}
}

Output

final static field ONE = one
final static field TWO = two
final static field THREE = three
final field FOUR = four
final field FIVE = five
----------------------------
final field FOUR = four
final field FIVE = six

Constants class has three static final fields, ONE and TWO are initialized in declaration but THREE is initialized in a static initializer. The static field FIVE is initialized in a constructor. So we have initialized a static field in all possible ways. One thing to note here is that while initializing a static field in a constructor, it should be initialized in all the contructors, otherwise we get a compilation error, stating the variable might not have been initialized. Also, we cannot set the value in initializer as well as constructor. So if we uncomment the line in the initializer, it will throw a compiler error, stating the variable might already have been assigned to.

So to summarize what we have discussed in this section

  • Access fields (static, instance, final), both within a class that defines the fields optionally using the this qualifier, and outside using the reference name with the dot operator.
  • The fields are accessible outside the class because of their access modifier.
  • We haven’t discussed transient or volatile fields, except to know their meaning and that they are valid modifiers.

Thats all in this section, see you in the next one!