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

Dashboard
Notifications
Mark all as read
Q&A

What are the disadvantages of using static methods in Java?

+2
−3

I was using static method few moments ago. But I noticed that I was returning a variable using that static method. According to the article,

Static is a keyword that identifies the class-related thing. It means the given Method or variable is not instance-related but Class related. It can be accessed without creating the instance of a Class.

I think I can access the static method without caring of class, isn't it? Is there something special of static method? static method can helps to decrease amount of source code. So Is it better to use static method? Or is there any limit of it?

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

I have changed the title to what I think is better summarising the content. Feel free to change somet... (2 comments)

4 answers

+3
−0

I am not a Java developer, but a C# .NET one, but I guess static concept is very similar between the two.

As in many areas, it depends, but for most applications using static should be avoided:

  • Single Responsibility Principle violation
  • prevents polymorphism
  • prevents abstraction (cannot use in an interface)
  • prevents inheritance
  • makes automatic testing through mocking way more complex and tedious
  • prevents garbage collector to kick in and collect the memory

For the specific case of utility functions, static is very useful, but for a medium or large application, this is only a tiny part of the codebase.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+3
−0

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 (which is an instance method) calls the resolvePreviousValid method:

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: 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 (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. 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:

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].

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:

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, 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:

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:

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) 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. 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. Hence, making them static won't hurt...

There's no silver bullet, and YMMV.


  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. ↩︎

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+2
−0

I think I can access the static method without caring of class, isn't it?

No. A static method is still a class method, and you still care about the class. The difference is that static methods aren't used with an instance of a class (an object).

static method can helps to decrease amount of source code.

True. As you pointed out in comment (putting it here too for better visibility): import static com.classes.Car.numCars(); means that you can simply invoke it as numCars();

So Is it better to use static method? Or is there any limit of it?

Opinions differ. The main thing is that you can't access object members in a static method, only static members.

For example, you might have a Car class, with a fuel member and a drive() method that makes fuel go down. You might also have a private static int numCars member, and a static printNumCars() method.

When accessing your static method, you still care about the class. It's still going to be Car.numCars(). numCars() has no way to access the fuel member, and that makes sense (which car's fuel would we be talking about?). On the other hand, "how many cars are there" isn't a property of any one specific car at all, it's a property of cars in general, as a whole category.

That's what static members are for - things that are relevant to the entire class, rather than any individual object.

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

decrease amount of source code (3 comments)
+0
−2

If it were always better to use static, the language would have been designed to always assume static, or at least default to static. That the language defaults to making methods not static indicates that the designers of the programming language envisioned static methods to be rare.

Java is intended to be an object oriented programming language, where a program is a set of objects that "talk" to each other using methods. Objects are created from classes, and classes can be related through inheritance. Specifically, a class can be declared to extend another class, which allows it to inherit or override methods from the parent class. For instance:

class Animal {
   void move() {
       System.out.prinln("The animal moves");
   }
}

class Dog extends Animal {
   @Override
   void move() {
       System.out.println("The dog walks");
   }
}

class Snake extends Animal {
   @Override
   void move() {
       System.out.println("The snake slithers");
   }
}

Which you can then use as follows:

Animal animal = new Snake();
animal.move(); // "The snake slithers"

So even though the variable contains an Animal, that Animal knows whether it is a Dog or a Snake, and responds accordingly when it is asked to move.

This ability to refine the behavior of a class in a subclass is very useful. However, since this depends on the type of the object, it is only available for methods of objects, not static methods.

By using static, you deny yourself this useful tool. This may seem a small price to pay when your programs are tiny and consist only of a few isolated methods. However, once your programs get bigger, and particularly once they start incorporating code written by other people, the ability to refine code they have written will be invaluable.

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Feel free to explain downvotes (3 comments)

Sign up to answer this question »