69

Java 14 introduced records feature. Record creates getter with the same name as field, so one would write print(person.name()) for example. But old Java bean convention dictates that one should name this method as getName().

Using both styles in the same code base does not look very nice. Migrating everything to records is not possible, as they are too limited to replace all use-cases.

Is there any official or semi-official guidelines how to name getters and setters after Java 14 in new code?

6
  • 4
    I suspect records are meant to be a different kind of component from standard javabeans, and perhaps it's right for them to follow a different line of conventions. They have different constraints, so they naturally won't fit in many places we find javabeans anyway.
    – ernest_k
    Commented Jan 30, 2020 at 7:46
  • 3
    I think the answer is no. Not yet. Style guides / conventions tend to trail the addition of new language features because it takes time for a consensus to emerge.
    – Stephen C
    Commented Jan 30, 2020 at 7:46
  • 2
    Besides ... records will only be a "preview" feature in Java 14. They won't necessarily make it to the stage of being a permanent language feature.
    – Stephen C
    Commented Jan 30, 2020 at 7:59
  • 1
    Just as a data point: Google's Java uses AutoValue widely at present, which is sort-of records-within-the-constraints-of-the-current-language. It is a reasonably common convention to omit "get" from getters; but some ardently push back (actually, there's a specific point in the FAQ, saying "do either, just be consistent"). YMMV; Google style is but one of many choices. Commented Jan 30, 2020 at 8:17
  • 3
    @AndyTurner I am so excited for Groovy/Kotlin/EL code where I need to write obj.foo().bar.baz().quux! Commented Jan 30, 2020 at 8:29

6 Answers 6

28

Quote from JEP 359:

It is not a goal to declare "war on boilerplate"; in particular, it is not a goal to address the problems of mutable classes using the JavaBean naming conventions.

My understanding, based on the same document is that records are transparent holders for shallowly immutable data.

That being said:

  1. Records are not the place to look for getters/setters syntactical sugar, as they are not meant to replace JavaBeans.
  2. I strongly agree with you that JavaBeans are too verbose. Maybe an additional feature (called beans instead of records) could be implemented - very similar behavior with the records feature but that would permit mutability. In that case, records and beans would not be mutually exclusive.
  3. As it has been mentioned, records are in preview mode. Let's see what the feedback from community would be.

All in all, IMHO they are a step forward... I wrote this example set where you can see a code reduction to ~15% LOC from standard JavaBeans.

Also, note that records behave like normal classes: they can be declared top level or nested, they can be generic, they can implement interfaces (from the same document). You can actually partly simulate JavaBeans (only getters would make sense, though) by extracting an interface containing the getters - however that would be a lot of work and not a really clean solution...

So, based on the logic above, to address your question, no - I didn't see any (semi)official guideline for getters and setters and I don't think that there is a motivation for it right now because, again, records are not a replacement for JavaBeans...

2
  • 1
    Naming conventions are quite difficult to follow sometimes for synthetic code. For example, for te attribute uuid the getter could be getUUID and not getUuid. Commented Mar 28, 2022 at 23:08
  • Excellent answer. Thanks. How does having a get prefix to getters in records make it sound like it is a replacement for beans? It would just make it more consistent with existing conventions that this method is a getter.
    – Khanna111
    Commented Sep 23, 2022 at 19:36
10

The record spec is now "final" as of Java 17 and this naming convention discrepancy has unfortunately not been addressed. I stumbled upon it when attempting to leverage Records as shallow holder classes to implement interfaces part of an existing domain model.

Whilst this isn't as neat a solution as I'd like, Records can have methods, so you could add "legacy" getters to your record, as in the following (contrived but simple) example.

public interface Nameable {
   public String getName();
}

public record Person(String name) implements Nameable {
   public String getName() {
      return name;   // or return name();
   }
}

At least this allows client code to continue to use that tried and tested (over 20 years old) convention, which - let's face it - is used far more than in pure JavaBeans context.

You could say that the language designers have lived up to their remit of "not declaring war on boilerplate"

4
  • 1
    Did you consider naming your component getName if you really need the accessor name to be getName? Commented Jan 8, 2022 at 20:11
  • 10
    IMHO public record Person(String getName) impairs the code's readability; even more so if the field is being referenced the record's method(s). Also, do consider that in the above scenario, we're not discussing mere preference, but the need to retrofit an existing API (Nameable), which one may or may not have the ability to alter...
    – sxc731
    Commented Mar 24, 2022 at 16:49
  • 2
    I am currently also considering naming the field like the getter but I agree there should be a way to change the name of the getter method. On the other side would this make working with foreign records more confusing, since you can't differentiate between getters amd other methods. Commented Oct 22, 2022 at 16:53
  • 4
    Naming the field like the getter is a terrible idea, especially if you want to serialize the record. Then you will have a "getName": "Brad Idea" in your JSON ;)
    – entreprenr
    Commented Jan 5, 2023 at 9:17
3

I figured I'd address one tacit assumption: that the style guides we have now actually recommend Bean style getters and setters.

None of the style guides I found actually recommend it. One of them remarks that people are divided on the issue. Thus, if you use the convention foo() and foo(newValue), you would be consistent with readily available style guides.

Guides

Google Java Style Guide does show some getField methods, but the actual guidance doesn't mention them.

Brown borrows from Google, same.

Cornell says:

However, a convention in Java is that a function that yields the value of a field (say title) is the name of the field preceded by "get". People are of two minds on this; not everyone thinks it's a good idea. The name "title" could also be used.

Java Conventions same as Google.

Eydean borrows heavily from Google and Sun, same as Google.

Twitter borrows from Google, same as Google.

And lastly, the Java Beans Spec lays out exactly how you name getters and setters to be compatible with Beans in §8.3.1:

Simple properties By default, we use design patterns to locate properties by looking for methods of the form:

public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);

If we discover a matching pair of “get<PropertyName>” and “set<PropertyName>” methods that take and return the same type, then we regard these methods as defining a read-write property whose name will be “<propertyName>”. We will use the “get<PropertyName>” method to get the property value and the “set<PropertyName>” method to set the property value. The pair of methods may be located either in the same class or one may be in a base class and the other may be in a derived class.

And even if you completely disregard this:

§ 8.6 A Java Bean can also explicitly specify which properties, events, and methods it supports by providing a class that implements the BeanInfo interface.

1
  • Nobody mentioned style guides? This style is extraordinarily widespread in Java code regardless of what any style guide says. Commented Jul 29 at 15:57
2

I stumbled up this when researching naming conventions for my project. Looking at the "recent" additions to the std lib (e.g. Path, FileSystem, HttpRequest, ...) the only more-or-less "pattern" I could detect was that .prop() implies direct, unmodified access to the field value, and thus existance of the field with that very type.

Whereas "getXXX" conveys that you cannot/should not assume the existence of a field. This property might be calculated, direct field access or read-only wrapped (e.g. List.copyOf) or converted.

So my conclusion is: if you want to communicate "structure" or enforce the precence of fields use .prop(). In all other cases stick to getXXX as it is more flexible (implementers can be entity classes, records or service classes.

Btw: I am aware that there are big offenders to this logic even in the jdk. e.g. BigDecimal that's why I focused on more recent additions.

0
0

Seeing Java move in the right direction warms my heart a bit.

"Get" is possibly the worst verb to get overly abused in programming. In programming it used to always mean no state change, while in English it can also mean "to become" which is state change. See, even I used it as a state change in the beginning of this paragraph (right before the word "overly").

Kent Beck has got this right as early as 1996 in his "Smalltalk best practice patterns" book:

Provide a method that returns the value of the variable. Give it the same name as the variable.

-3

In Java records, object fields must be private and final. So there is just one kind of getter and one kind of setter possible.

In Java classes, object fields may be private or public. In the latter type of field, one can get or set them simply by adding a period and the field name, e.g.

 Employee emp = new Employee(); // Nullary constructor
 emp.name = "John Schmidt";     // Setter
 . . . 
 . . . 
 if (emp.name != "Buddy")       // Getter
 {
    emp.bonus = 100.00;
 }

Non-private fields are used a lot in Android apps to save memory and time extracting data. But there's no reason not to use them in Java where it's safe to do so.

Now, if you change away from the usual way in Java classes to something like that used in record types, e.g.

String name = emp.name();  // New getter convention for private field

you have a serious risk of confusion by code readers who might misinterpret this as a non-private object field.

And if you change the record getter to what is used in Java objects, i.e.

obj.getField()

then there is a risk of confusion by coder reviewers and possibly a compiler may treat it as a Java object, depending on execution decision criteria.

In short, it's a different type of object to the normal Java class or enum. Its accessors indicate this new type unambiguously. That's how I see it anyhow. Maybe someone on the Java development committee may be able to enlighten us further.

2
  • You noticed that fields and methods are in different namespaces? Commented Jun 1, 2020 at 9:02
  • Even if you read code with a mouse hovering over the field of view (and I don't and doubt if you do either, buddy) this wouldn't immediately jump up at you. Eclipse just uses little colored squares and circles to signify namespaces. IntelliJ is even sparer by default. But I suppose you have configured it to show this essential info.
    – Trunk
    Commented Jun 1, 2020 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.