Java POJO and Java Bean Example
1. Introduction
POJO stands for a Plain Old Java Object. It’s a term coined by Martin Fowler, Rebecca Parsons, and Josh MacKenzie while preparing for a conference in September 2000. POJO is an ordinary Java object which doesn’t tie to any framework or external reference. It has no naming rule for its methods nor data members.
Java Bean is a Java object which meets Java Bean Conventions:
- Properties must set as
privateand expose via getters/setter. - The getter and setter must name as
getX(isXforboolean) andsetXconvention. - Must have a public default no-argument constructor
- Must implement
java.io.serializableinterface
In this example, I will demonstrate the following items in a Maven project.
- Define a POJO class
- Define a Java Bean class
- Create a POJO object via Reflection
- Create a Java Bean object via Reflection
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
- Apache Commons BeanUtils 1.9.3
3. Maven Project
3.1 Dependencies
I will include Junit and commons-beanutils 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-pojo-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> <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> </dependencies> </project>
3.2 POJO
I will create a POJODemo class which represents a POJO and includes:
- six fields naming from
field1tofield6with various access modifiers toStringto return aStringvalue of the object- constructor to build an object with the
field1value
POJODemo.java
package jcg.zheng.demo.data;
import java.util.ArrayList;
import java.util.List;
public class POJODemo {
private int field1;
public Long field2;
Integer field3;
protected String field4;
public List<String> field5 = new ArrayList<>();
public boolean field6;
public POJODemo(final int field1) {
super();
this.field1 = field1;
}
@Override
public String toString() {
return "POJODemo [field1=" + field1 + ", field2=" + field2 + ", field3=" + field3 + ", field4=" + field4
+ ", field5=" + field5 + ", field6=" + field6 + "]";
}
public Integer getField3() {
return field3;
}
public void setField3(Integer field3) {
this.field3 = field3;
}
}
3.3 Java Bean
I will create a JavaBeanDemo class which has the same six fields as the POJODemo class but satisfies the Java Bean conventions:
- has a public default constructor
- all properties have a
privateaccess modifier - all properties have getX (isX) and setX
- implements
Serializableinterface
JavaBeanDemo.java
package jcg.zheng.demo.data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class JavaBeanDemo implements Serializable {
private static final long serialVersionUID = 1L;
private int field1;
private Long field2;
private Integer field3;
private String field4;
private List<String> field5 = new ArrayList<>();
private boolean field6;
public JavaBeanDemo() {
super();
}
public int getField1() {
return field1;
}
public Long getField2() {
return field2;
}
public Integer getField3() {
return field3;
}
public String getField4() {
return field4;
}
public List<String> getField5() {
return field5;
}
public boolean isField6() {
return field6;
}
public void setField1(int field1) {
this.field1 = field1;
}
public void setField2(Long field2) {
this.field2 = field2;
}
public void setField3(Integer field3) {
this.field3 = field3;
}
public void setField4(String field4) {
this.field4 = field4;
}
public void setField5(List<String> field5) {
this.field5 = field5;
}
public void setField6(boolean field6) {
this.field6 = field6;
}
@Override
public String toString() {
return "JavaBeanDemo [field1=" + field1 + ", field2=" + field2 + ", field3=" + field3 + ", field4=" + field4
+ ", field5=" + field5 + ", field6=" + field6 + "]";
}
}
You can also check our Java Bean example for further knowledge.
3.4 PlayingCard
I will create a PlayingCard class which is a POJO with:
- two
Stringdata members –faceValueandsuit - constructor to build an object with both
faceValueandsuit toStringmethod to return aStringvalue of the object
PlayingCard.java
package jcg.zheng.demo.data;
public class PlayingCard {
private String faceValue;
private String suit;
public PlayingCard(String suit, String faceValue) {
super();
this.suit = suit;
this.faceValue = faceValue;
}
@Override
public String toString() {
return "Card [suit=" + suit + ", faceValue=" + faceValue + "]";
}
}
3.5 PlayingCard Bean
I will create a PlayingCardBean class which is a Java Bean and has the same data members as PlayingCard.
PlayingCardBean.java
package jcg.zheng.demo.data;
import java.io.Serializable;
public class PlayingCardBean implements Serializable {
private static final long serialVersionUID = 1L;
private String faceValue;
private String suit;
public PlayingCardBean() {
super();
}
public PlayingCardBean(String suit, String faceValue) {
super();
this.suit = suit;
this.faceValue = faceValue;
}
public String getFaceValue() {
return faceValue;
}
public String getSuit() {
return suit;
}
public void setFaceValue(String faceValue) {
this.faceValue = faceValue;
}
public void setSuit(String suit) {
this.suit = suit;
}
@Override
public String toString() {
return "Card [suit=" + suit + ", faceValue=" + faceValue + "]";
}
}
3.6 ReflectionService
In this step, I will create a ReflectionService class which has three methods:
createInstanceViaDefaultConstructor– creates an object via a given class’s default constructor.- createInstanceviaConstructorWithInt – creates an object via a given class’s constructor which takes one int argument.
- displayAllFields – displays all fields for a given class and set one of the fields –
field2with 4.
ReflectionService.java
package jcg.zheng.demo;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class ReflectionService {
public Object createInstanceviaDefaultConstructor(String objClassName) {
Object object = null;
try {
object = Class.forName(objClassName).getDeclaredConstructor().newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
}
return object;
}
public Object createInstanceViaConstructorWithInt(String objClassName, int intF) {
Object object = null;
try {
object = Class.forName(objClassName).getDeclaredConstructor(int.class).newInstance(intF);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
}
return object;
}
public void displayAllFields(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] allFields = obj.getClass().getDeclaredFields();
System.out.print("\nClass " + obj.getClass().getName() + " has declared fields: ");
for (Field f : allFields) {
System.out.printf("\n\t %s %s ", Modifier.toString(f.getModifiers()), f.getName());
if( "field2".equalsIgnoreCase(f.getName())) {
f.setAccessible(true);
f.set(obj, 4l);
}
}
}
}
4. JUnit Test
4.1 POJO Test
I will create POJODemoTest which includes four tests:
create_via_reflection_with_default_constructor–POJODemohas no default constructor, so it cannot create an instance with the no-argument constructor- create_via_reflection_with_int_constructor – POJODemo has a constructor that takes an int argument, so it can be used to create an instance via reflection.
- displayAllFields – displays all the fields via reflection and set its field2 value to 4.
- test_BeanUtils_copyProperties – Apache BeanUtils.copyProperties only works for the properties which meet getter and setter format.
POJODemoTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import jcg.zheng.demo.ReflectionService;
public class POJODemoTest {
private static final String POJO_DEMO = "jcg.zheng.demo.data.POJODemo";
private POJODemo testClass = new POJODemo(3);
private Object objectFromReflection;
private ReflectionService reflectionDao = new ReflectionService();
@Test
public void create_via_reflection_with_default_constructor() {
objectFromReflection = reflectionDao.createInstanceviaDefaultConstructor(POJO_DEMO);
assertNull(objectFromReflection);
}
@Test
public void create_via_reflection_with_int_constructor() {
objectFromReflection = reflectionDao.createInstanceViaConstructorWithInt(POJO_DEMO, 4);
assertNotNull(objectFromReflection);
}
@Test
public void displayAllFields() throws IllegalArgumentException, IllegalAccessException {
reflectionDao.displayAllFields(testClass);
assertEquals(4, testClass.field2.intValue());
}
@Test
public void test_BeanUtils_copyProperties() throws IllegalAccessException, InvocationTargetException {
testClass.field2 = 100l;
testClass.field3 = 123;
testClass.field4 = "Mary";
testClass.field6 = true;
POJODemo dest = new POJODemo(4);
BeanUtils.copyProperties(dest, testClass);
System.out.println(dest);
// Did not copy any properties at all
assertTrue(dest.toString().contains("field1=4"));
assertTrue(dest.toString().contains("field2=null"));
assertTrue(dest.toString().contains("field3=123"));
assertTrue(dest.toString().contains("field4=null"));
assertTrue(dest.toString().contains("field5=[]"));
assertTrue(dest.toString().contains("field6=false"));
assertEquals(dest.getField3().intValue(), testClass.getField3().intValue());
}
}
Junit output
Running jcg.zheng.demo.data.POJODemoTest
POJODemo [field1=4, field2=null, field3=123, field4=null, field5=[], field6=false]
Class jcg.zheng.demo.data.POJODemo has declared fields:
private field1
public field2
field3
protected field4
public field5
public field6 Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.02 sec
Results :
Tests run: 8, Failures: 0, Errors: 0, Skipped: 04.2 Java Bean Test
I will create JavaBeanTest to test the following:
create_via_reflection_with_default_constructor–JavaBeanDemohas a default constructor, so it can create an instance with the no-argument constructordisplayAllFields– displays all the fields via reflection and set itsfield2value to 4.test_BeanUtils_copyProperties– ApacheBeanUtils.copyPropertiesworks for the Java Bean properties
JavaBeanDemoTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import jcg.zheng.demo.ReflectionService;
public class JavaBeanDemoTest {
private static final String BEAN_DEMO = "jcg.zheng.demo.data.JavaBeanDemo";
private JavaBeanDemo testClass = new JavaBeanDemo();
private Object objectFromReflection;
private ReflectionService reflectionDao = new ReflectionService();
@Test
public void create_via_reflection_default_constructor() {
objectFromReflection = reflectionDao.createInstanceviaDefaultConstructor(BEAN_DEMO);
assertNotNull(objectFromReflection);
}
@Test
public void getDeclaredFields() throws IllegalArgumentException, IllegalAccessException {
reflectionDao.displayAllFields(testClass);
assertEquals(4, testClass.getField2().intValue());
}
@Test
public void test_copyProperties() throws IllegalAccessException, InvocationTargetException {
testClass.setField2(100l);
testClass.setField3(123);
testClass.setField4("Mary");
testClass.setField6(true);
testClass.setField1(3);
JavaBeanDemo dest = new JavaBeanDemo();
BeanUtils.copyProperties(dest, testClass);
System.out.println(dest);
assertEquals(3, dest.getField1());
assertEquals(100, dest.getField2().intValue());
assertEquals(123, dest.getField3().intValue());
assertEquals("Mary", dest.getField4());
assertTrue(dest.isField6());
}
}
Junit Output
Running jcg.zheng.demo.data.JavaBeanDemoTest
Class jcg.zheng.demo.data.JavaBeanDemo has declared fields:
private static final serialVersionUID
private field1
private field2
private field3
private field4
private field5
private field6 JavaBeanDemo [field1=3, field2=100, field3=123, field4=Mary, field5=[], field6=true]
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.257 sec4.3 Bean Disadvantage Test
I will create a BeanDisadvantageTest class which demonstrates that the object’s state is updated by the bean’s setter when it should be the same during its life cycle. For a PlayingCard object, its face value and suit should not be changed. But setters enable other processes to update them, which sometimes causes confusion or problem. This is one of drawback about the Java Bean.
BeanDisadvantageTest.java
package jcg.zheng.demo.data;
import static org.junit.Assert.*;
import org.junit.Test;
public class BeanDisadvantageTest {
@Test
public void javabean_state_changes_by_setter() {
PlayingCard aceSpadePojo = new PlayingCard("Spade", "A");
assertEquals("Card [suit=Spade, faceValue=A]", aceSpadePojo.toString());
PlayingCardBean aceSpadeBean = new PlayingCardBean("Spade", "A");
aceSpadeBean.setSuit("Club");
aceSpadeBean.setFaceValue("1");
// OOPS. the variable aceSpadeBean now changed to Club 1
assertEquals("Card [suit=Club, faceValue=1]", aceSpadeBean.toString());
}
}
Junit Output
Running jcg.zheng.demo.data.BeanDisadvantageTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.165 sec
5. Summary
As you saw in this example, Java Bean is a subset of POJO. They both can be created via Java reflection. Here are the major differences between them:
| POJO | Java Bean | |
| Description | A normal Java object which meets Java programming language specification | A subset of POJO which meets Java Beans specification |
| Used By | Any application. e.g. Spring framework uses it widely. All Spring Beans are POJO | A builder tool which creates an instance via a toolbox. Apache commons BeanUtils |
| Disadvantage | NA | Default constructor and public setter can change the object state when it should be immutable. |
6. Download the Source Code
You can download the full source code of this example here: Java POJO and Java Bean Example

