What is a Field in Java ?
1. Introduction
Java is an object-oriented programming language which uses “object” concept to group data and methods in a class. A variable defined in a class is called a field. A field is declared by specifying its type and name.
In this example, I will demonstrate:
- Declare a field for the primitive data type, object, and collection
- Add
static,final,transient, and access modifiers to fields - Access fields via Java reflection
- Inherits fields from the parent class
2. Technologies Used
The example code in this article was built and run using:
- Java 11
- Maven 3.3.9
- Eclipse Oxygen
- Junit 4.12
3. Maven Project
In this step, I will create a Java maven project which has two packages:
jcg.zheng.demo.data– this package includes four classes:PrimitiveFields,ObjectFields,CollectionFields, andEnumExample.jcg.zheng.demo.modifier– this package includes four classes:AccessModifiers,InstanceModifiers,RuntimeModifiers, andChildExample.
3.1 Dependencies
I will include Junit in the pom.xml.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jcg.zheng.demo</groupId> <artifactId>java-field-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
3.1.1 Enum Example
In this step, I will create an EnumExample which is used in an ObjectFields class.
EnumExample.java
package jcg.zheng.demo.data;
public enum EnumExample {
GOLD, SILVER;
}
3.2 Field Modifier
Java supports three types of modifiers:
- Access modifiers:
public,protected,private, anddefault - Run-time modifiers:
transientandvolatile - Instance modifiers:
staticandfinal
In this step, I will create three classes to demonstrate how to use these modifiers on fields.
3.2.1 Access Modifier
Java provides four access modifiers:
private– a field with theprivatemodifier can be accessed only inside the same class.default– a field without any access modifier can be accessed inside the class itself and in the same package as this class.public– a field with thepublicmodifier can be accessed from all classes.protected– a field with theprotectedmodifier can be accessed by sub-classes, the same class, and the classes in the same package.
In this step, I will create an AccessModifiers class which has four fields, one for each access modifier.
AccessModifiers.java
package jcg.zheng.demo.modifier;
public class AccessModifiers {
private int intField;
public Long longField;
Integer packageField;
protected String stringField;
public AccessModifiers(final int privateIntField) {
super();
this.intField = privateIntField;
}
@Override
public String toString() {
return "FieldAccessExample [packageField=" + packageField + ", intField=" + intField + ", stringField="
+ stringField + ", longField=" + longField + "]";
}
}
3.2.2 Instance Modifier
Java provides two instance modifiers:
static– a field with thestaticmodifier can be accessed before any objects of its class are created, and without reference to any object. There is only a single copy of static variable created and shared among all the instances of the class.final– a field with thefinalmodifier cannot be assigned again. If afinalvariable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable always refer to the same object.
In this step, I will create an InstanceModifiers which has four static final variables and two final variables.
InstanceModifiers.java
package jcg.zheng.demo.modifier;
import jcg.zheng.demo.data.PrimitiveFields;
public class InstanceModifiers {
public static final String INT_FIELD = "intField";
public static final String LONG_FIELD = "longField";
public static final String PACKAGE_FIELD = "packageField";
public static final String STRING_FIELD = "stringField";
final String field1 = "Fixed Value";
final PrimitiveFields field2 = new PrimitiveFields();
}
3.2.3 Run-time Modifier
Java supports two run-time modifiers:
transient– a field with thetransientmodifier will not be serialized.volatile– a field with thevolatilemodifier does not cache value.
In this step, I will create a RuntimeModifiers which has transient volatile variables and two final variables.
RuntimeModifiers.java
package jcg.zheng.demo.modifier;
import java.io.Serializable;
public class RuntimeModifiers implements Serializable {
private static final long serialVersionUID = 4192336936121085734L;
private String name;
private transient String password;
private static volatile RuntimeModifiers instance;
public static RuntimeModifiers getInstance() {
if (instance == null) {
synchronized (RuntimeModifiers.class) {
if (instance == null) {
instance = new RuntimeModifiers();
}
}
}
return instance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "RuntimeModifierExample [name=" + name + ", password=" + password + "]";
}
}
3.3 Primitive Data Type
Java supports eight primitive data type: char, byte, int, short, long, float, double, and boolean. A primitive data type variable has a default value.
In this step, I will create a PrimitiveFields class which has eight fields, one for each primitive type.
PrimitiveFields.java
package jcg.zheng.demo.data;
public class PrimitiveFields {
private boolean booleanField;
private byte byteField;
private char charField;
private double doubleField;
private float floatField;
private int intField;
private long longField;
private short shortField;
public byte getByteField() {
return byteField;
}
public char getCharField() {
return charField;
}
public double getDoubleField() {
return doubleField;
}
public float getFloatField() {
return floatField;
}
public int getIntField() {
return intField;
}
public long getLongField() {
return longField;
}
public short getShortField() {
return shortField;
}
public boolean isBooleanField() {
return booleanField;
}
public void setBooleanField(boolean booleanField) {
this.booleanField = booleanField;
}
public void setByteField(byte byteField) {
this.byteField = byteField;
}
public void setCharField(char charField) {
this.charField = charField;
}
public void setDoubleField(double doubleField) {
this.doubleField = doubleField;
}
public void setFloatField(float floatField) {
this.floatField = floatField;
}
public void setIntField(int intField) {
this.intField = intField;
}
public void setLongField(long longField) {
this.longField = longField;
}
public void setShortField(short shortField) {
this.shortField = shortField;
}
}
3.4 Object
Java provides java.lang.Object class which is the parent class of all classes.
In this step, I will create an ObjectFields class which has fields belong to object types. It’s a good practice to initialize an object field to avoid the NullPointerException.
ObjectFields.java
package jcg.zheng.demo.data;
public class ObjectFields {
private EnumExample enumField;
private PrimitiveFields objectField;
private String stringField;
public EnumExample getEnumField() {
return enumField;
}
public PrimitiveFields getObjectField() {
return objectField;
}
public String getStringField() {
return stringField;
}
public void setEnumField(EnumExample enumField) {
this.enumField = enumField;
}
public void setObjectField(PrimitiveFields objectField) {
this.objectField = objectField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
}
3.5 Collection
In this step, I will create a CollectionFields class which has collection fields. It’s a good practice to initialize the collection object to avoid the NullPointerException.
CollectionFields.java
package jcg.zheng.demo.data;
import java.util.ArrayList;
import java.util.List;
public class CollectionFields<T> {
private int[] arrayField;
private List<T> listField_initialized = new ArrayList<>();
public void addListField_initialized(T element) {
this.listField_initialized.add(element);
}
public int[] getArrayField() {
return arrayField;
}
public List<T> getListField_initialized() {
return listField_initialized;
}
public void setArrayField(int[] arrayField) {
this.arrayField = arrayField;
}
}
3.6 Inheritance
In this step, I will create a ChildExample class which extends from AccessModifiers. The parent’s protected and public fields are available to the child class.
ChildExample.java
package jcg.zheng.demo.modifier;
public class ChildExample extends AccessModifiers {
private String name;
public ChildExample(final int privateIntField, final String name) {
super(privateIntField);
this.name = name;
}
@Override
public String toString() {
return "ChildExample [name=" + name + ", packageField=" + packageField + ", stringField="
+ stringField + ", longField=" + longField + "]";
}
}
4. JUnit Test
4.1 PrimitiveFieldsTest
In this step, I will create a PrimitiveFieldsTest class to test the primitive data type fields.
PrimitiveFieldsTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import jcg.zheng.demo.data.PrimitiveFields;
/**
* Test the default value for the field with primitive type and the getter and setter
* @author Mary Zheng
*
*/
public class PrimitiveFieldsTest {
private PrimitiveFields testClass = new PrimitiveFields();
@Test
public void test_field_boolean() {
assertFalse(testClass.isBooleanField());
testClass.setBooleanField(true);
assertTrue(testClass.isBooleanField());
}
@Test
public void test_field_char() {
assertEquals('\u0000', testClass.getCharField());
testClass.setCharField('M');
assertEquals('M', testClass.getCharField());
}
@Test
public void test_field_double() {
assertEquals(0.00, testClass.getDoubleField(), 2);
testClass.setDoubleField(34.8);
assertEquals(34.8, testClass.getDoubleField(), 2);
}
@Test
public void test_field_int() {
assertEquals(0, testClass.getIntField());
testClass.setIntField(1);
assertEquals(1, testClass.getIntField());
}
@Test
public void test_field_long() {
assertEquals(0, testClass.getLongField());
testClass.setLongField(100l);
assertEquals(100l, testClass.getLongField());
}
@Test
public void test_field_short() {
assertEquals(0, testClass.getShortField());
testClass.setShortField((short) 1);
assertEquals(1, testClass.getShortField());
}
@Test
public void test_field_byte() {
assertEquals(0, testClass.getByteField());
testClass.setByteField((byte) 1);
assertEquals(1, testClass.getByteField());
}
@Test
public void test_field_float() {
assertEquals(0.00, testClass.getFloatField(), 2);
testClass.setFloatField(34.8f);
assertEquals(34.8, testClass.getFloatField(), 2);
}
}
Execute mvn test -Dtest=PrimitiveFieldsTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.data.PrimitiveFieldsTest Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.13 sec Results : Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
4.2 ObjectFieldsTest
In this step, I will create an ObjectFieldsTest class to initialize and read the object fields.
ObjectFieldsTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import jcg.zheng.demo.data.EnumExample;
import jcg.zheng.demo.data.ObjectFields;
import jcg.zheng.demo.data.PrimitiveFields;
public class ObjectFieldsTest {
private ObjectFields testClass = new ObjectFields();
@Test
public void test_field_enum() {
assertNull(testClass.getEnumField());
testClass.setEnumField(EnumExample.GOLD);
assertEquals(EnumExample.GOLD, testClass.getEnumField());
}
@Test
public void test_field_object() {
assertNull(testClass.getObjectField());
testClass.setObjectField(new PrimitiveFields());
assertEquals(0, testClass.getObjectField().getIntField());
}
@Test
public void test_field_string() {
assertNull(testClass.getStringField());
testClass.setStringField("Mary");
assertEquals("Mary", testClass.getStringField());
}
}
Execute mvn test -Dtest=ObjectFieldsTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.data.ObjectFieldsTest Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.122 sec Results : Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
4.3 CollectionFieldsTest
In this step, I will create a CollectionFieldsTest class to initialize and add an element to a collection field.
CollectionFieldsTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class CollectionFieldsTest {
private CollectionFields testClass = new CollectionFields();
@Test
public void test_field_intArray() {
int[] arrayField = new int[2];
arrayField[0] = 1;
arrayField[1] = 4;
testClass.setArrayField(arrayField);
assertEquals(1, testClass.getArrayField()[0]);
assertEquals(4, testClass.getArrayField()[1]);
}
@Test
public void test_field_list() {
assertTrue(testClass.getListField_initialized().isEmpty());
testClass.addListField_initialized(5);
assertFalse(testClass.getListField_initialized().isEmpty());
assertEquals(5, testClass.getListField_initialized().get(0).intValue());
}
}
Execute mvn test -Dtest=CollectionFieldsTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.data.CollectionFieldsTest Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.119 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
4.4 AccessModifiersTest
In this step, I will create an AccessModifierTest class that has public, protected, private, and default package fields.
AccessModifiodersTest.java
package jcg.zheng.demo.modifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
public class AccessModifiersTest {
private AccessModifiers testClass = new AccessModifiers(3);
@Test
public void child_class_can_access_default_protected_public() {
System.out.println(testClass.toString());
assertNull(testClass.packageField);
assertNull(testClass.longField);
assertNull(testClass.stringField);
testClass.packageField = Integer.valueOf(5);
testClass.stringField = "Mary";
testClass.longField = Long.valueOf(12);
System.out.println(testClass.toString());
assertEquals(5, testClass.packageField.intValue());
assertEquals("Mary", testClass.stringField);
assertEquals(12, testClass.longField.intValue());
}
}
Execute mvn test -Dtest=AccessModifiersTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.modifier.AccessModifiersTest FieldAccessExample [packageField=null, intField=3, stringField=null, longField=null] FieldAccessExample [packageField=5, intField=3, stringField=Mary, longField=12] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.234 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
- line 5, 6: The
privatefields can be accessed within the same class.
4.5 ChildExampleTest
In this step, I will create a ChildExampleTest class which shows the child object inherits the public and protected fields from the parent class.
ChildExampleTest.java
package jcg.zheng.demo.modifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import jcg.zheng.demo.modifier.ChildExample;
public class ChildExampleTest {
private ChildExample testClass = new ChildExample(3, "Test");
@Test
public void child_class_can_access_default_protected_public() {
System.out.println(testClass.toString());
assertNull(testClass.packageField);
assertNull(testClass.stringField);
assertNull(testClass.longField);
testClass.packageField = Integer.valueOf(1);
testClass.stringField = "Zheng";
testClass.longField = Long.valueOf(2);
System.out.println(testClass.toString());
assertEquals(1, testClass.packageField.intValue());
assertEquals("Zheng", testClass.stringField);
assertEquals(2, testClass.longField.intValue());
}
}
Execute mvn test -Dtest=ChildExampleTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.modifier.ChildExampleTest ChildExample [name=Test, packageField=null, stringField=null, longField=null] ChildExample [name=Test, packageField=1, stringField=Zheng, longField=2] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.203 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
4.6 InstanceModifiersTest
In this step, I will create an InstanceModifiersTest class which shows final fields are not assignable.
InstanceModifiersTest.java
package jcg.zheng.demo.modifier;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class InstanceModifiersTest {
private InstanceModifiers testClass = new InstanceModifiers();
@Test
public void test_static() {
assertEquals("intField", InstanceModifiers.INT_FIELD);
assertEquals("longField", InstanceModifiers.LONG_FIELD);
assertEquals("packageField", InstanceModifiers.PACKAGE_FIELD);
assertEquals("stringField", InstanceModifiers.STRING_FIELD);
}
@Test
public void test_final() {
assertEquals("Fixed Value", testClass.field1);
// testClass.field2 = new PrimitiveFields();
}
}
Execute mvn test -Dtest=InstanceModifiersTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.modifier.InstanceModifiersTest Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.164 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
- line 23 : can not re-assign the
finalfield.
4.7 RuntimeModifersTest
In this step, I will create a Junit test to show the transient fields are not serialized.
RuntimeModifiersTest.java
package jcg.zheng.demo.modifier;
import static org.junit.Assert.assertNull;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
public class RuntimeModifiersTest {
private static final String SERIALIZED_FILE_NAME = "transient.ser";
private RuntimeModifiers testClass = RuntimeModifiers.getInstance();
@Test
public void transient_not_serialized() {
serializedObj();
RuntimeModifiers deObj = deserializedObj();
assertNull(deObj.getPassword());
System.out.println(deObj.toString());
}
private void serializedObj() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SERIALIZED_FILE_NAME));
testClass.setName("Mary");
testClass.setPassword("shouldNotSerialized");
oos.writeObject(testClass);
oos.close();
System.out.println(testClass.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
private RuntimeModifiers deserializedObj() {
RuntimeModifiers ret = null;
try {
ObjectInputStream ooi = new ObjectInputStream(new FileInputStream(SERIALIZED_FILE_NAME));
ret = (RuntimeModifiers) ooi.readObject();
ooi.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return ret;
}
}
Execute mvn test -Dtest=RuntimeModifiersTest and capture output here.
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.modifier.RuntimeModifiersTest RuntimeModifierExample [name=Mary, password=shouldNotSerialized] RuntimeModifierExample [name=Mary, password=null] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.217 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
- line 5: The original object’s
passwordhas value - line 6: The
transient passwordis not serialized
5. Access Field via Reflection
In this step, I will create a FieldReflectionDemo to show how to read and write the fields via java.lang.reflect package.
FieldReflectionDemo.java
package jcg.zheng.demo;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import jcg.zheng.demo.data.CollectionFields;
import jcg.zheng.demo.data.EnumExample;
import jcg.zheng.demo.data.ObjectFields;
import jcg.zheng.demo.data.PrimitiveFields;
import jcg.zheng.demo.modifier.AccessModifiers;
import jcg.zheng.demo.modifier.ChildExample;
import jcg.zheng.demo.modifier.InstanceModifiers;
import jcg.zheng.demo.modifier.RuntimeModifiers;
public class FieldReflectionDemo {
public static void main(String[] args) {
displayClassFields(EnumExample.GOLD);
displayClassFields(new PrimitiveFields());
displayClassFields(new ObjectFields());
displayClassFields(new CollectionFields<Integer>());
displayClassFields(new AccessModifiers(3));
displayClassFields(new ChildExample(3, "Test"));
displayClassFields(new InstanceModifiers());
displayClassFields(new RuntimeModifiers());
}
private static void displayClassFields(Object obj) {
try {
Field[] allFields = obj.getClass().getDeclaredFields();
System.out.print("\nClass " + obj.getClass().getName() + " has fields: ");
for (Field f : allFields) {
boolean updated = false;
f.setAccessible(true);
System.out.printf("\n\t %s %s = %s ", Modifier.toString(f.getModifiers()), f.getName(), f.get(obj));
if (InstanceModifiers.INT_FIELD.equalsIgnoreCase(f.getName())) {
f.set(obj, 47);
updated = true;
} else if (InstanceModifiers.PACKAGE_FIELD.equalsIgnoreCase(f.getName())) {
f.set(obj, Integer.valueOf(2));
updated = true;
} else if (InstanceModifiers.STRING_FIELD.equalsIgnoreCase(f.getName())) {
f.set(obj, "Java code geek");
updated = true;
} else if (InstanceModifiers.LONG_FIELD.equalsIgnoreCase(f.getName())) {
f.set(obj, Long.valueOf(1000));
updated = true;
}
if (updated) {
System.out.printf("\n\t *Updated* %s %s = %s ", Modifier.toString(f.getModifiers()), f.getName(),
f.get(obj));
}
}
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
Execute it as a Java application java jcg.zheng.demo.FieldReflectionDemo and capture output here.
Output
c:\MaryZheng\Workspaces\jdk12\java-field-demo\target\classes>java jcg.zheng.demo.FieldReflectionDemo
Class jcg.zheng.demo.data.EnumExample has fields:
public static final GOLD = GOLD
public static final SILVER = SILVER
private static final $VALUES = [Ljcg.zheng.demo.data.EnumExample;@25618e91
Class jcg.zheng.demo.data.PrimitiveFields has fields:
private booleanField = false
private byteField = 0
private charField =
private doubleField = 0.0
private floatField = 0.0
private intField = 0
*Updated* private intField = 47
private longField = 0
*Updated* private longField = 1000
private shortField = 0
Class jcg.zheng.demo.data.ObjectFields has fields:
private enumField = null
private objectField = null
private stringField = null
*Updated* private stringField = Java code geek
Class jcg.zheng.demo.data.CollectionFields has fields:
private arrayField = null
private listField_initialized = []
Class jcg.zheng.demo.modifier.AccessModifiers has fields:
private intField = 3
*Updated* private intField = 47
public longField = null
*Updated* public longField = 1000
packageField = null
*Updated* packageField = 2
protected stringField = null
*Updated* protected stringField = Java code geek
Class jcg.zheng.demo.modifier.ChildExample has fields:
private name = Test
Class jcg.zheng.demo.modifier.InstanceModifiers has fields:
public static final INT_FIELD = intField
public static final LONG_FIELD = longField
public static final PACKAGE_FIELD = packageField
public static final STRING_FIELD = stringField
final field1 = Fixed Value
final field2 = jcg.zheng.demo.data.PrimitiveFields@3ab39c39
Class jcg.zheng.demo.modifier.RuntimeModifiers has fields:
private static final serialVersionUID = 4192336936121085734
private name = null
private transient password = null
private static volatile instance = null- line 14, 16, 22, 28: the
privatefields are updated via reflection - line 30 : the
publicfield is updated via reflection - line 34: the
protectedfield is updated via reflection
6. Summary
In this example, I explained that a field is a building block of a Java object. It is defined by its type and name. I also demonstrated how to use Java modifiers to manage the availability, instance, and runtime behavior.
7. Download the Source Code
This example consists of a Maven project which demonstrates a Field in Java.
You can download the full source code of this example here: What is a Field in Java


Your article is excellent