Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

71%
+3 −0
Q&A What are the disadvantages of using static methods in Java?

Is it better to use static method? I don't like to think of static (or any other language feature/mechanism) in terms of bad/worse and good/better (although I do that too, I constantly try to ...

posted 3y ago by hkotsubo‭

Answer
#1: Initial revision by user avatar hkotsubo‭ · 2021-09-20T16:49:00Z (over 3 years ago)
> *Is it better to use static method?*

I don't like to think of `static` (or any other language feature/mechanism) in terms of bad/worse and good/better (although I do that too, I constantly try to avoid it).

What I usually try/prefer to do is to understand how something works, why it exists, the pros and cons of using it, and then decide when it does or doesn't make sense to use it (for the so-called "OO languages", my understanding is that "many" times `static` is not the proper solution, but my answer to questions like this is usually "*it depends*").

---
The other answers are - correctly - pointing situations where `static` doesn't apply, either because it's not the best option (prevents polymorphism, inheritance, etc), or because it's the wrong mechanism to use (a `static` method can't access instance fields, so you can't "do OOP" at all). I'm not repeating all their explanation and examples (just mention some of them when pertinent).

The point of this answer is to claim that `static` is not "evil". It has its uses, and the most important thing IMO is to understand how it works and when to use (or avoid) it.

Obviously if you want to "do OOP" (access instance variables/methods), you can't use `static`, as the other answers explained. But in this case, it's more than a simple recomendation: it's a constraint imposed by the way the language works. If you declare any stuff `static`, it won't be an instance's stuff. If you want to "go OOP", you have no choice: those stuff must **not** be `static`.

But what if that stuff is not related to any instance at all? It's not uncommon to have private auxiliary methods that do some specific task not related to an instance. BTW, we can find lots of examples in the JDK source code. Ex: in `java.time.LocalDate` class, the [current implementation of `withYear` method](https://github.com/openjdk/jdk/blob/jdk-17+35/src/java.base/share/classes/java/time/LocalDate.java#L1081) (which is an instance method) calls the `resolvePreviousValid` method:

```java
public LocalDate withYear(int year) {
    if (this.year == year) {
        return this;
    }
    YEAR.checkValidValue(year);
    return resolvePreviousValid(year, month, day);
}
```

But [the `resolvePreviousValid` method is `static`](https://github.com/openjdk/jdk/blob/jdk-17+35/src/java.base/share/classes/java/time/LocalDate.java#L476): it does some stuff with the `year`, `month` and `day` values, but those stuff don't depend on any instance state, and the method was made `static`. I don't know who decided that, or why this was made, but IMO it makes clear (for anyone who'll have to read and/or maintain this code) that this method doesn't rely on instance fields and I don't see a big problem with it being `static`. Of course it has the cons mentioned in [another answer](https://software.codidact.com/posts/284243/284245#answer-284245) (`static` reduces testability, etc), but it's a `private` method, and therefore not good a candidate for automated tests.

Could the `resolvePreviousValid` method be non-static? Of course it could, and I admit that in this case it doesn't make much difference: the `LocalDate` class is `final` after all (it can't be extended), so the "_`static` prevents inheritance_" argument doesn't apply here as well, therefore it *seems* to be a matter of "style": they make it clear that the method doesn't depend on any specific instance, sacrificing testability, inheritability and other stuff that *probably* they didn't think of as a priority for this method (to me, a fair trade-off).

---
Another example found in the JDK is the [`java.lang.Math` class](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Math.html). It has no public constructor, and all the public methods are `static`. IMO, it makes sense, because this class has no internal state (what fields would a `Math` instance have?) and all the mathematical functions (such as `abs`, `floor`, `sqrt`, etc) simply perform some operations/calculations that are independent of any internal state, thus having an instance is not necessary.

Would it be worth to require an instance to be created? Such as:

```java
Math m = new Math(); // Would it make sense to be like this?
double result = m.sqrt(x);
double f = m.floor(result);
```

I don't think so. Why create a `Math` instance, when `Math.sqrt(x)` and `Math.floor(x)` would do the job? Considering that all these methods are "self-contained" and don't depend on any internal state of the `Math` instance (if such instance were created), I don't think they should be made non-static just for the sake of "best practices"[^1], or because "this is not OOP"[^2].

  [^1]: I see "best practices" more as guidelines, instead of set-in-stone laws that you must always follow no matter what.
  [^2]: Many things made in OOP languages are actually "imperative with classes", but I digress.

One could also argue that utility classes (such as `StringUtils`, `DateUtils`, `WhateverUtils`, that I've seen in basically all projects I've worked on) have static methods due to the language's "limitations": everything must be inside a class and you can't change native classes.

For example, in Ruby and JavaScript you can add methods to existing classes (even native ones). Example in JavaScript:

```javascript
String.prototype.whatever = function(...args) {
    // do whatever you want with args
    // use "this" to refer to the string instance
}

// use the newly created method on any string
'abc'.whatever(args);
```

In C# you can create [extension methods](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods), which is similar (although not exactly the same, as it's only a syntatic sugar), but they're implemented with... `static` methods!

Java doesn't have such features, and the "best" alternative is to create utilitary classes with static methods. Using the JavaScript example above, in Java it'd be like this:

```java
public class StringUtils {
    public static String whatever(String s, Object ...args) {
        // do something with "s" and args...
        return result;
    }
}

... // use the class
String result = StringUtils.whatever("abc", 1, 2);
```

Would it be worth changing this class to require the creation of an instance? Such as:

```java
StringUtils utils = new StringUtils();
String result = utils.whatever("abc", 1, 2);
```

Unless the `whatever` method needs to access the internal state of the `StringUtils` instance, there's no benefits in doing so. Just "follow the best practices", or "make correct OO code" (whatever that means, because [nobody agrees on what it is](https://wiki.c2.com/?NobodyAgreesOnWhatOoIs)) is not enough to justify that, IMHO.

`static` is not "evil". You should use when it makes sense (or when there's not a better alternative).

---
Just to provide another example, consider [Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods). In Java, you can find many examples in the native API, such as `Optional.of`, `Calendar.getInstance`, `Collections.unmodifiableList`, and so on. All are implemented as `static` methods. Could they be implemented in a different way, maybe by having factory classes (such as `f = new CollectionsFactory(); f.unmodifiableList()`)? Yes, they could, but I can see the convenience of having those implemented as `static` methods.

That's a good use case for `static` methods, IMO. Making those non-static would bring little to no benefits (unless you *really need* testability, inheritance, polymorphism, etc). I'm not saying that `static` is always justified, nor that non-static must be avoided. I'm saying that, knowing how `static` works, you can make better choices when coding: do you need to access instance fields/methods? So they *must* be non-static. The method doesn't access any internal state, or it's an utilitary class? It's a good candidate for `static`. But I *need* those to be testable, and/or inheritable, and/or polymorphic. Then make them non-static. No, I don't need those things, and the class is actually `final` (can't be subclassed), the method is `private` and/or so specific to this class that [it won't be used anywhere else](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it). Hence, making them `static` won't hurt...

There's no silver bullet, and YMMV.