Is it correct to make Java private methods static or not? Pros and cons of each option?


I saw this question in the English version, but I didn't find it in the Russian version. Often, some programmers use private static methods to show that this private method does not use any variables and methods of the class, others on the contrary are against this approach because they consider it not the correct use of OOP (we are only talking about private methods of the class that do not use any class variables and other non-static methods).

That is, what is more correct by you can use it like this

   public class MyClass {      
      private static void func1() { // со статик
        ...
      }
   }

Or so

   public class MyClass {      
      private void func1() { // без статик
        ...
      }
   }

?

I was talking about those methods that do not use (and cannot use) fields directly, for example, the boolean isValid(T str) method, which is called in other methods of the class for many different objects, and which are only needed for this class and it makes no sense to put them in a separate Utils class.

As an example of such a method, this is hugeCapacity in ArrayList from Oracle JDK 8:

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

P.S. Any quotes and references to well-known Java authors will help a lot to solve the question (say, I know that in ArrayList of Oracle JDK, where the authors are quite famous Josh Bloch and Neal Gafter, private static methods are used). Do you know any other confirmations of this or that point of view?

That is, the ideal answer is an answer with quotes from books / articles by well-known Java authors or those who were engaged in OOP theory or design.

Author: Slava Vedenin, 2017-11-22

7 answers

Be guided by the meaning, and only by it. The structure of your classes should not reflect the technical ability to do one way or another (sometimes instance methods can be declared static), but the relationships between objects in the domain domain. This is really the base of all OOP (and where else to follow OOP, if not in Java?).

I can't quote from a smart book on this. But the very idea of making the signature of a method dependent not on its meaning, but on the details of its specific implementation seems to me a rude hack. Even if it is an internal, private method. If we write correctly in public methods intended for others, why do we write incorrectly in methods intended for ourselves?

To deviate from the correct design, you need good reasons. ArrayList has such reasons: it is used in millions of projects, and among them there are time-critical chunks, and there the gain of a couple of clock cycles plays a serious role. But for for most of the classes we write, the number of calls in our programs is not in the tens of thousands per second, and deviating from the correct design is hardly justified.


If the method refers to a specific object, then declare it as an instance of the methods, regardless of whether it accesses non-static fields and this or not. If the method is common to the entire class, and does not make sense in the context of a single instance, declare it static. If the method is not at all belongs to a class, put it in an auxiliary class.


Example: a knight's weapon is a sword. Yes, all knights have the same weapons. However, the method that issues the weapon is obviously an instance method. Further, knights do not use daggers. Therefore, the knight's dagger getter returns null. This is also an instance method.

class Knight : Warrior {
    private Weapon createMainWeapon() {
        return new Sword();
    }
    private Dagger getDagger() {
        return null;
    }
}

Next, the number of knights. Accordingly, it does not make sense in the context of a single knight, so it is static the method.

class Knight : Warrior {
    static int numberOfKnights;
    public Knight() {
        numberOfKnights++;
    }
    public static int getNumber() {
        return numberOfKnights;
    }
}

And finally, the method that finds out whether the ammunition is in order before the battle, does not belong to the field of activity of the knight at all. Let the squire handle it!

class Squire {
    Knight master;
    public prepareForBattle() {
       ...
    }
}
 17
Author: VladD, 2017-11-22 23:53:39

First, it would be good to start by deciding whether this class needs this method. Let's say we have a car class and a method for converting kilometers to miles.

public class Car {

    private static double convertToMiles(double km){
        return km*0.621371192;
    }   
}

Obviously, this method is not needed by the class at all and it would be good to put it in a separate one final Utils a similar class, since it can be used in many places.

Renaud Waldura in "The Final Word on Final" writes:

Since a final method is only implemented in the declaring class, there is no need to dynamically dispatch a call to a final method, and static invocation can be used instead. The compiler can emit a direct call to the method, bypassing entirely the usual virtual method invocation procedure. Because of this, final methods are also candidates for inlining by a Just-In-Time compiler or a similar optimization tool. (Remember, private/static methods are already final, therefore always considered for this optimization.)

I personally make software features static to show that the method does not depend on the state of the class and does not affect it in any way. In the IDE, such a method will be highlighted in italic font, which allows you to understand about its independence from the state of the class, without even looking inside the method.

 12
Author: Suvitruf - Andrei Apanasik, 2017-11-22 21:12:05

I will immediately indicate IMHO: the method should not be static and in the post I try to describe this point of view.


Everyone creates their own code. This may be relevant for optimization, but not for OOP. It turns out that this is not a method, but a procedure.

Quote from an interview with David West:

"The class doesn't have to do anything"

Egor: But in Java, classes are not just molds for objects. We put the methods there...

David: You shouldn't!

Egor: That's it and my question!

David: Well, as I tried to say in the book, the class doesn't have to do anything. Smalltalk has class methods, but you don't need to use them. Their use is a return to the team way of thinking. You take what should be the responsibility of the objects, and for some reason you're trying to shove it all into the classroom. And as a result, the class does a lot for the objects.

Interview in full


It all comes down to one question, why should this method belong to the class and not to the object?


Now I thought that this quote is not in the subject of the question, but let it remain.

I don't quite understand the purpose of making a private method static. If only for optimization.

If you do not take into account optimization, the method operates on the object fields (they will simply be passed as parameters). And then you can remember the "clean code". The fewer parameters a method has, the easier it is to read. So you can make it not static and use not parameters, but object fields.

If the private method does not get any parameters and does not access the object's variables, then I do not quite understand what it will do.


Update: I was talking about those methods that don't use (and can't use) fields directly, like the boolean isValid(T str) method), which is called in other methods of the class for many different objects, and which are only needed for this class and it makes no sense to put them in a separate Utils class.

The validity of an object can be determined by the object itself, and then an "information expert" is needed, and then the essence of the generic method goes to each class, i.e. instead of a static method for the validity of any object, we will ask the object itself whether it is valid.

 6
Author: Виктор, 2017-11-22 21:24:37

For a deeper understanding, I will add a historical context in general about static methods. Some researchers of the question generally consider all such methods to be evil in the OOP.

When a topic is difficult to understand, one of the best ways is to turn to the story. Java originated from Smalltalk. Everyone who has spent at least one day studying it knows this. In the Smalltalk language (since 1971), there were already static methods - although they go there under the name "class methods". Where did they come from there? Smalltalk has another ancestor-Simula (since 1965). It turns out that in Simula there were such methods - only there they go under the name "free block". But in turn, who "dragged "these"free blocks" from the Simul language? And the Simula's ancestor is Algol. Because the Simula is originally a superset of Algol 60. So that's where the legs come from:

A) Algol

procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
    value n, m; array a; integer n, m, i, k; real y;
comment The absolute greatest element of the matrix a, of size n by m
    is transferred to y, and the subscripts of this element to i and k;
begin
    integer p, q;
    y := 0; i := k := 1;
    for p := 1 step 1 until n do
        for q := 1 step 1 until m do
            if abs(a[p, q]) > y then
                begin y := abs(a[p, q]);
                    i := p; k := q
                end
end Absmax 

B) Simula

Begin
   Class Glyph;
      Virtual: Procedure print Is Procedure print;
   Begin
   End;

   Glyph Class Char (c);
      Character c;
   Begin
      Procedure print;
        OutChar(c);
   End;

   Glyph Class Line (elements);
      Ref (Glyph) Array elements;
   Begin
      Procedure print;
      Begin
         Integer i;
         For i:= 1 Step 1 Until UpperBound (elements, 1) Do
            elements (i).print;
         OutImage;
      End;
   End;

   Ref (Glyph) rg;
   Ref (Glyph) Array rgs (1 : 4);

   ! Main program;
   rgs (1):- New Char ('A');
   rgs (2):- New Char ('b');
   rgs (3):- New Char ('b');
   rgs (4):- New Char ('a');
   rg:- New Line (rgs);
   rg.print;
End;

Thus, the OOP was originally an add-on over the imperative - so completely " cut out" static methods will fail. In institutional economics, there is such an observation - the priority/importance of a rule is determined only by one thing - the cost of changing it (or canceling it). "Cancel" static methods will cost humanity so many man-years that they are probably with us forever. We can only reduce their use in our own code in order to work with objects more conveniently.

As for exactly private static methods-to the general disadvantages of static methods we also add privacy. I have very rarely seen such methods in the code. I don't use it myself, as I try to minimize static methods in the code and consider myself a supporter of the ideas of Yegor Bugayenko.

 6
Author: dSH, 2017-11-25 15:01:11

This is probably the shortest explanation of the meaning of using static methods.

Static methods should be used in two cases.

• When the method does not need access to the object state data, because all the necessary parameters are set explicitly (for example, in the Math.pow method ()).

• When the method only needs access to the static fields of the class.

Horstmann, Kay S. Java. Professional Library, volume 1. The basics. 10th ed. page 157

 4
Author: Олег Сухих, 2017-11-29 12:27:08

The first duty I want to say is my opinion this is my experience !!! (I think that you know the essence of the usual and static method, so I do not write a definition.)

  1. The statistical method - is a functional approach. In object-oriented design, this affects development , i.e. maintenance is difficult, thinking changes to functionality , and so on (general answer).

  2. Well, from the point of view of c memory , normal or static method no loss why: In memory ".NET/Java " uses the Flyweight (even this technique has a pattern, but that's not the point). This technique saves RAM (I will not explain the technique in detail), and here the normal or static method does not affect anywhere (in terms of memory), because each class is allocated one object(this is the technical name) which methods are contained in this object every instance only contains normal Fields/Properties (mutable) and these instances refer to this object, that's the brief gist. (technical influence is implied here).

I want to touch on one point. The problem is that in any normal or static method, you can not load a large responsibility or a large amount of code (one of the important principles). I think that it is not necessary to look so critically at this topic.

I will not philosophically tell a fairy tale. Well, I divided it up split into two parts (analyze).

Well, I can recommend a philosophical book on these topics "Object Thinking David West" it explains in detail the pure object-oriented programming / thinking architectural distinction and topics such as static, ordinary (methods , classes) and so on.

 4
Author: Rasul, 2017-12-03 08:38:18

No wrong. More precisely, it is wrong to make the private methods of the class static. Technically, of course, this can be done, but in the sense of there are cases when it is harmful and not necessary.

I'll give you an example: I often see that in the same Android, when a new super-duper API is announced, when studying the source code, it turns out that they just made a previously private method in the class public. That is, Google actively uses private non-static methods as a way of version control. Meaning simple, there is a private method that is hidden inside the class and is actively used by normal public methods, so the method passes a kind of run-in in real conditions. Then, after studying the bugtracks, the development team decides to bring the method out: the method signature is declared as public and everything is ready-the progers get their hands on a new API tool.

I think this is a very good practice. And at least for the sake of this method, declaring a private method static was not worth it would.

 2
Author: Barmaley, 2017-12-01 13:01:12