Primitives vs Objects in Java
Are there truly any non-null issues when using primitives instead of Objects?
Join the DZone community and get the full member experience.
Join For FreeDisclaimer — in this article, I am presenting what I've found, hoping to gain some real-life feedback on the perspectives noted below. I am certainly not an expert on the aspects discussed in this article. Instead, I would enjoy hearing your feedback in the comments.
On a recent Java API project, I found myself creating entity and DTO objects to fuel a RESTful API consumed by JavaScript-based clients.
As an example, let's assume the following table and attributes were created in my SampleEntity
class:
@Data
@Entity
public class SampleEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long someId;
private Integer someInteger;
private Boolean isAcive;
private String someString
private List<Object> someObject;
public SampleEntity() {}
}
On the DTO side, I created an object similar to what was listed below:
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class SampleDto {
private Long someId;
private Integer someInteger;
private Boolean isActive;
private String someString;
private List<Long> someObjectIds;
public SampleDto() {}
}
In the actual example, the DTO is a slimmed-down version of the Entity object. To keep the payload lean and only utilize what the client needs to do render the necessary data, for this example, the DTO returns a list of Long (ids) for the Objects that exist with the Entity class.
When the code went through the PR process, I was asked to change the Long
, Integer
, and Boolean
objects to long
, int,
and boolean
primitives. The reason I was given this was because of the smaller memory use in using primitives over objects.
Seemed Like a Good Idea
I found this article on baeldung.com.
At first glance, it appeared to be a valid rationale, since the memory usage difference is noticeable. With thousands of clients using the application, that difference could wind up relating to performance.
Here is a diagram from the article:
In this case, none of the values would ever have null values, so I wasn't going to have to worry about handling that scenario.
Stack V. Heap
However, when I started looking deeper, I noticed there is a difference between stack and heap memory allocation, mostly after reading this page from stackoverflow.com.
It appears that primitives are always stored on the stack, where Objects are stored on the heap and pulled into the stack when needed by the JVM for processing. As a result, if my entire application utilized primitives (where possible) for every entity, DTO, services, repositories, etc., it seems as if I might have an issue with such much of the stack memory being allocated.
I understand there is garbage collection with the JVM, but is it enough to keep up with this approach, especially with larger-scale applications being utilized by thousands (or tens of thousands) of users concurrently?
null != -1
Another challenge with the primitive approach is that null is not an option.
As I noted in the case above, the someId
, someInteger
, or isActive
attributes could not be null based upon the database design. If there were, I would avoid switching from an Object to a primitive to avoid making assumptions when something is null.
As an example, if the long
value is used to handle the record ID in the database. It is *probably* okay to set the value to -1 when there is not currently a value. Remember, null values can exist when you initially create a new record in your client. Before the request is persisted, the value is likely null.
Going with the -1 approach, somewhere you would need to look for the -1 and convert that to null so that the value of -1 is not stored in the database. Seems like just using the Object makes a lot more sense than having everyone in the development stream remember this rule, right?
Conclusion
When designing and developing applications, I always want to make sure I am taking the right approach in providing a solution. Like everything else, I want to do the right thing.
My approach was questioned via a PR, which led to some research, which then led to this article — with a hope to gain feedback from other developers who have already allocated time and energy to the primitive vs. Object option.
At the end of the PR, I did convert the Objects to primitives, but only when there wasn't a driving reason (like null values) to avoid making the change.
I am very interested in hearing your feedback!
Opinions expressed by DZone contributors are their own.
Comments