java date cdate fasttime_Implementing Values With Immutable Classes

Implementing Values With Immutable Classes

DZone’s Guide to

Implementing Values With Immutable Classes

Dive into thread safety, value objects, primitive types, and immutable classes as we explore some recommended practices.

Mar. 06, 18 ·

Java Zone

Free Resource

Join the DZone community and get the full member experience.

Build vs Buy a Data Quality Solution: Which is Best for You? Gain insights on a hybrid approach. Download white paper now!

Classes representing values should have the same properties as primitive types. Primitive types represent basic values like int or char in Java. Primitive types have no identity and are immutable.

In the following, we will see that those two properties are also useful for classes representing properties.

No Identity

Two values are equal if they have the same external visible state: For example, if you have two variables (a and b) with the value 5, they are equal:

int a = 5;

int b = 5;

a == b // true

Immutable

Values are immutable. If you a modify a value, it becomes a new value. In the following example, we modify the variable a, which leads to a new value b. a and b are not equal.

A Value Class

Now let us look at a class representing a value with those two properties, the java.time.Instant class. This class represents an instant in time. Let us first look at the field declaration of this class:

package java.time;

public final class Instant

{

private final long seconds;

private final int nanos;

// static fields and methods omitted

}

Declaring the field final makes this class immutable. Declaring a field as final (as the two fields in the example, lines 5 and 6) lets the compiler check that the fields are not modified after the constructor of the class was called. Note that final is a field modifier. It makes the field itself immutable, not the object the field references. So the type of the final field must also be immutable or a primitive type like in the example.

Next, let us look at the equal method to see how equality is implemented for this class:

public boolean equals(Object otherInstant) {

if (this == otherInstant) {

return true;

}

if (otherInstant instanceof Instant) {

Instant other = (Instant) otherInstant;

return this.seconds == other.seconds &&

this.nanos == other.nanos;

}

return false;

}

As we see, two Instant objects are equal if their external visible state is equal.

Immutability Using an Identity

Now let us look at a class that is immutable but uses its identity for equality — the Object class. The Object class is useful when you only need an identity but no state, like in the following example, from the JDK 9 java.util.concurrent.CopyOnWriteArrayList, where we need the identity as a monitor for synchronization:

public class CopyOnWriteArrayList

{

final transient Object lock = new Object()

public boolean add(E e) {

synchronized (lock) {

// other statements omitted

}

}

}

To represent a value of a class with identity is not useful.

No Identity but Mutable

The following shows a mutable value class, the java.util.Date class:

public class Date

{

private transient BaseCalendar.Date cdate;

private transient long fastTime;

public void setTime(long time) {

fastTime = time;

cdate = null;

}

public boolean equals(Object obj) {

return obj instanceof Date && getTime() == ((Date) obj).getTime();

}

public long getTime() {

return getTimeImpl();

}

private final long getTimeImpl() {

if (cdate != null && !cdate.isNormalized()) {

normalize();

}

return fastTime;

}

// static fields and other methods omitted

}

The two fields (cdate and fastTime) are not final and can be changed by the setTime method, making the class mutable. The equals method checks the externally visible state for equality. While it is possible to implement values with mutable classes, immutable classes are easier to use.

Advantages of Immutable Value Classes

Immutable classes cannot change their state. This property is useful in specific scenarios in single-threaded programs, for example when you use them as keys in hash maps. And it makes writing multi-threaded programs much easier.

Immutable classes do not change their value in the middle of an operation without using synchronized blocks. By avoiding synchronization blocks, you avoid deadlocks. And since you are always working with an unchangeable, consistent state you avoid race conditions.

Usage of Identity

While it is still possible to access the identity of a value object, it is probably an error. For example, the use of == instead of equals is probably incorrect:

Integer a = new Integer(5);

Integer b = new Integer(5);

a.equals(b) // true

a == b

You probably expect true when you compare two Integers of value 5, so the use of == is incorrect. The following methods are using the identity of the object and should be avoided when using value classes:

synchronized statement

System.identityHashCode

Object.notify and wait

The Future: JEP 169, Value Objects

Implementing values using classes requires more memory than their primitive counterparts. A solution to this problem is implemented by Java Enhancement Proposal 169, Value Objects . It will allow you to create value classes with similar memory characteristics as primitive types.

The idea is to implement a new operator (lockPermanently), which converts an object into a new state with memory consumption similar to a primitive type. Using an operation that requires the identity of the value object like == or synchronized on such a locked object will be forbidden.

Conclusion and What Is Next

Primitive types represent basic values. Primitive types are immutable and have no identity. We have seen how to implement classes with the same properties. The usage of the identity of a value class, while still possible, is probably an error. Making value classes immutable makes them easier to use, especially for thread safe software.

In the next blog post, we will look at one type of value classes, messages, to write thread safe software. In the meantime, if you want to test whether your application is thread-safe, try vmlens for free. I would be glad to hear from you if you use value classes in your application.

Build vs Buy a Data Quality Solution: Which is Best for You? Maintaining high quality data is essential for operational efficiency, meaningful analytics and good long-term customer relationships. But, when dealing with multiple sources of data, data quality becomes complex, so you need to know when you should build a custom data quality tools effort over canned solutions. Download our whitepaper for more insights into a hybrid approach.

DOWNLOAD

Topics:

java , immutability , concurrent , value objects , thread safety , tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

注意:本文来自DZone。本站无法对本文内容的真实性、完整性、及时性、原创性提供任何保证,请您自行验证核实并承担相关的风险与后果!

CoLaBug.com遵循[CC BY-SA 4.0]分享并保持客观立场,本站不承担此类作品侵权行为的直接责任及连带责任。您有版权、意见、投诉等问题,请通过[eMail]联系我们处理,如需商业授权请联系原作者/原网站。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值