Relying on default field initialisation - is bad programming style? [closed]
Asked Answered
I

3

20

I was given a link to the official oracle documentation: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

where it is said:

Default Values

It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style.

I want to emphasis this part:

Relying on such default values, however, is generally considered bad programming style.

But, oh boy, this is, I would say, a fundamental part of the language specification knowing that instance variables have default values. Why on earth this is a bad programming practice if it is widely used even in Java SE libraries source code?

Insectile answered 18/10, 2019 at 14:18 Comment(6)
Huh. I never knew that statement was in there. I actually consider it good practice to rely on them. private int count = 0; is code that does nothing, and code that does nothing is clutter. It’s like importing classes from java.lang, or declaring a class with extends Object.Influx
... or having a public abstract method in an interface.Impedance
what's wrong with public abstract?Casals
A piece of the puzzle may come from C++. It's a popular language, and its handling of default initialization versus zero initialization is a continuous source of bugs. In C++, it's a straight up bad idea to rely on the defaults in all but the most exceptional cases. That may have leaked into Java culturally.Jaynejaynell
@JohnKeates - My Java's a bit rusty, but private methods in an interface would make no sense, and abstract is implied.Circumbendibus
@ScottSmith excellent points.Casals
T
7

The quoted text is:

"Relying on such default values, however, is generally considered bad programming style."

Cynically: "it is generally considered that" is often a way of saying that the author hasn't tried to find an authoritative source for the statement being presented.

In this case the assertion is clearly questionable. Evidence: 5 out of 5 Java Style Guides sampled do NOT say anything about whether you should or should relying on default values:

(Note, my methodology for sampling was to look at the first 5 distinct Google search hits for "java style guide". Then I searched each document for "default". This is not a thorough analysis, but it serves to make my point.)


OK. So does it really aid readability of Java code?

This is debatable.

On one hand, a novice Java programmer who hasn't learned about default initialization may be baffled about where the zeros or nulls are coming from. But if they bother to look for an explicit initialization and find there isn't one, that should be sufficient to cause them to read a tutorial or book to find out about default initialization. (You would hope!)

On the other hand, we don't normally expect novice Java programmers to be maintaining production code-bases. For an experienced Java programmer a redundant initialization does not improve readability. It is (at best) noise.

To my mind, the only thing that is achieved by a redundant initialization of a field is to signal to a future reader of your code that you have thought about the the initial value. (As @GhostCat expressed it, default initialization does not communicate intent.)

But conversely if I was that reader, I would not necessarily trust the thinking of the code author. So the value of this "signal" is also questionable.


What about reliability?

In Java it makes no difference. The JLS specifies that default initialization does occur for fields. And conversely, for local variables it is a compilation error to try to use a variable that has not been definitely initialized.

In short, the runtime behavior of a variable that is not explicitly initialized is entirely predictable.

By contrast in languages like C or C++ where variables may not be initialized, the behavior is unspecified, and can lead to crashes, and differences in behavior on different platforms. The case for always explicitly initializing variables is much stronger here.


What about performance?

It should make no difference. The JIT compiler should be able to treat a redundant initialization and default initialization as the same.

Truck answered 19/10, 2019 at 3:11 Comment(0)
S
20

Simple: relying on default values does not communicate intent.

Did you really want that field to start with 0, or did you forget to assign a value?!

And of course, a null reference is half of the two things you need to run into a nullpointer exception.

Finally, using defaults implies that you have non final fields. Which you avoid where possible.

The only counter argument is: why write down things that you don't have to? But I think the listed disadvantages trumpet that, thus assigning 0 to a field explicitly is better than leaving it to the compiler.

Shellashellac answered 18/10, 2019 at 14:24 Comment(2)
i.e. re: not communicating intent - What if "Manny the maintainer" is looking at your code and doesn't know what the default for a specific data type is. He's assuming it's 0 when it's really NULL and that's the entire bug on a === check(or whatever the equivalent equality check for value&type is in java, equals()?). Hours of searching (for an inexperienced programmer) could be the result of something so simple. P.S. trying to play devil's advocate. I say use the defaults all day(even though I never do) and get smarter people(or at least higher attention to detail) to maintain your code.Hypersensitive
@Hypersensitive when mannie the maintainer does know so little about Java, then he has no business touching real world Java code. But I agree to the underlying notion. It makes things harder for newbies.Shellashellac
H
12

Why on earth this is a bad programming practice

The idea is if you rely on a default value, then it's not immediately clear to anyone reading the code if you deliberately left it as the default value, or you simply forgot to assign it.

...if it is widely used even in Java SE libraries source code??

The Java source code isn't really something you should rely on as an example of exemplary coding practice. There's many cases where such rules are violated (sometimes intentionally for minor performance improvements, and sometimes accidentally or because accepted style has changed over the years.)

Hesperidium answered 18/10, 2019 at 14:24 Comment(2)
This is probably right, though I don’t agree with it.Influx
@Influx As much as I tend to agree with the claim that relying on default values is sub-optimal, I was careful to phrase it in a neutral way for that reason. Code quality is subjective, and I'm well aware this is by no means a universally held view.Hesperidium
T
7

The quoted text is:

"Relying on such default values, however, is generally considered bad programming style."

Cynically: "it is generally considered that" is often a way of saying that the author hasn't tried to find an authoritative source for the statement being presented.

In this case the assertion is clearly questionable. Evidence: 5 out of 5 Java Style Guides sampled do NOT say anything about whether you should or should relying on default values:

(Note, my methodology for sampling was to look at the first 5 distinct Google search hits for "java style guide". Then I searched each document for "default". This is not a thorough analysis, but it serves to make my point.)


OK. So does it really aid readability of Java code?

This is debatable.

On one hand, a novice Java programmer who hasn't learned about default initialization may be baffled about where the zeros or nulls are coming from. But if they bother to look for an explicit initialization and find there isn't one, that should be sufficient to cause them to read a tutorial or book to find out about default initialization. (You would hope!)

On the other hand, we don't normally expect novice Java programmers to be maintaining production code-bases. For an experienced Java programmer a redundant initialization does not improve readability. It is (at best) noise.

To my mind, the only thing that is achieved by a redundant initialization of a field is to signal to a future reader of your code that you have thought about the the initial value. (As @GhostCat expressed it, default initialization does not communicate intent.)

But conversely if I was that reader, I would not necessarily trust the thinking of the code author. So the value of this "signal" is also questionable.


What about reliability?

In Java it makes no difference. The JLS specifies that default initialization does occur for fields. And conversely, for local variables it is a compilation error to try to use a variable that has not been definitely initialized.

In short, the runtime behavior of a variable that is not explicitly initialized is entirely predictable.

By contrast in languages like C or C++ where variables may not be initialized, the behavior is unspecified, and can lead to crashes, and differences in behavior on different platforms. The case for always explicitly initializing variables is much stronger here.


What about performance?

It should make no difference. The JIT compiler should be able to treat a redundant initialization and default initialization as the same.

Truck answered 19/10, 2019 at 3:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.