Over a million developers have joined DZone.

On the Proposal for ''Data Classes'' in Java

DZone's Guide to

On the Proposal for ''Data Classes'' in Java

Introducing data classes into Java has been brought into Project Amber. Let's see why that might not be such a great idea and what can be done instead.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

There is a new draft proposal for Java ‘Data Classes’ being worked on in Project Amber — read about it here. In short, I think the main points are:

  • Design intent: clearly and unequivocally express the design intent of a class as a ‘DTO’ (even though the author never mentions DTO)
  • Boilerplate: let the compiler take care of proper implementations of typical DTO operations like equals() and hashCode()
  • Switch statements: the author briefly talks about enabling semantic features around these DTOs, eg. the ability to use them as targets for switch statements

The draft also goes into some specifics like accessors not necessarily following JavaBeans conventions, opt-in mutability, and migration/compatibility concerns, among others.

Let me tell you why I think this proposal is a bad idea.

Design Intent

This is an honorable goal: It will immediately be obvious to a reader what the design intent of a data class is. The reader wouldn’t have to wade through countless lines following the typical getters and setters, equals, hashCode, and toString implementations just to be sure that this class is just a data class. Fine.

To see the problem with this line of thinking, you must first step back and ask yourself: How many DTO-types have I defined in my project and will this new language construct simplify my code considerably? If your answer is “a lot” to both questions, you have a deeper problem that this new construct cannot solve: you may not be thinking in an object-oriented way. Many of the types you’ve defined are merely bags of data and you are most likely programming in an imperative style, not object-oriented as you should be with Java. That is the crux of my argument.

Let’s kill the obvious retort right away: DTO IS an antipattern, but pure OOP is not practical, therefore, there’s no point in judging and getting upset about it.

Yes, DTO is unavoidable sometimes, especially when interfacing with remote APIs (eg. JAX-WS). However, a couple of points:

  1. These should exist at the periphery of your code
  2. They should be encapsulated by your domain model, where operations like equals() and hashCode() truly matter

In essence, you must avoid anemic domain models. DTOs, if present, should only exist at the fringes of your project, and not form the backbone of your whole design philosophy. They should ideally only be present when auto-generated by framework/tools like wsimport and you should never have to touch them.


If you accept the previous argument, then the getter/setter “boilerplate” becomes a non-issue: tools will automatically create them only where you absolutely need them. In regards to the proposal, that leaves us with just the other Object methods of interest: equals() and hashCode(). Here’s what I think:

  • They should be taken out of Object and made into their own interfaces.

  • Not all APIs want or even need all their DTOs to implement equals(), much less hashCode().

Switch Statements

This is cool but, why not switch on any object using Object#equals (or on my proposed Equality interface)? Because of performance reasons? They already reached a compromise on switching on strings. And as an SO user so eloquently put it (source):

...technical obstacles shouldn’t drive language design. If there is no way to compile it to efficient code, it might still get compiled to the equivalent of if … else … clauses, and still have a win on source code brevity.

The Bottom Line

By promoting DTOs to first-class citizenship, novice programmers who don’t know better will feel emboldened to keep abusing the DTO pattern. The other interest group — the implementors of “interface APIs” like Hibernate or jax-ws-ri — will gain some marginal benefit by having their templates reduced by a few lines.

This proposal will overall promote bad design with only marginal benefits.

Why not focus on other, good patterns?

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

java ,design-pattern ,jcp ,dto ,data classes

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}