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
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 ...
Answer
#1: Initial revision
> *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.