3

I have a private helper method that uses no instance variables or methods, I feel it would be less confusing if it was static (this way, it's given fewer points it can access).

I am a bit unsure if this question applies to private methods too.

I've also taken a look at this second question but again testing is not going to test private static helper methods directly.

Question: Why shouldn't I make my private helper methods static? Is it the confusion that would maybe lead someone to reuse it in a static context? As far as I see, that should be fine.

Any thoughts and suggestions are appreciated.

user85190
  • 133
  • 1
  • 5
  • 1
    [first question](http://programmers.stackexchange.com/questions/215826/make-methods-that-do-not-depend-on-instance-fields-static) definitely applies: "official Java tutorial is rather restrictive on when methods should be static: 'A common use for static methods is to access static fields.'" As long as private method isn't used to access static fields, declaring it static would go against intended use – gnat Jul 23 '15 at 09:51
  • But, as you quoted, that is a "common use" not the only intended use. Besides, utility classes are static and usually contain no state as far as I've seen (Disclaimer: I do not have 10 years of Java professional experience like some people here do) – user85190 Jul 23 '15 at 11:23
  • it's really simple, you need a compelling reason to deviate from recommended practices. Think of [reviewer looking at your code](http://programmers.stackexchange.com/a/141010/31260) and asking why you have chosen to do it the way that differs from recommended. If you can't provide a solid reason (and in the context of this question, you can't), it means you wasted your and their time. And no, "I like it better" is not a compelling reason – gnat Jul 23 '15 at 12:02
  • The source of @gnat 's quote ("A common use for static methods is to access static fields") is [Oracle's Java Tutorial](https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html) – Peter Wippermann Oct 07 '22 at 12:14

2 Answers2

6

The widespread antipathy towards static methods is largely due to fear that you won't be able to override a method easily for testing the class or mocking to test another class.

With a private method this isn't a concern, so my opinion is: if it can be static, make it static - this acts as a useful bit of automatic documentation ("this method does not depend on any instance state at all"). You shouldn't rewrite helper methods so that the become static-capable (e.g. by replacing field access with input parameters), but if this is its natural form then there's no harm and a little bit of gain.

Kilian Foth
  • 107,706
  • 45
  • 295
  • 310
  • 2
    Up-voting even though I disagree with your final sentence. State is the biggest cause of bugs, so the more you can do to minimise the exposure of that state, the better. Whenever practical, make private methods static and pass fields in as parameters. – David Arno Jul 23 '15 at 08:42
  • @DavidArno That's a bit extreme isn't it? Non-static private methods exist to give you a controlled way of mutating state. Not using them is opting out of using a very useful encapsulation tool. – MetaFight Jul 23 '15 at 09:12
  • 2
    If private methods make it difficult to track your class' state changes, then I'd argue your class is too large. – MetaFight Jul 23 '15 at 09:14
  • 1
    @MetaFight, I have a very strict policy of "no source file of more than 200 lines" which I strictly impose upon myself. I'd argue large class size isn't the reason behind wanting to minimising state and where it can change ;) – David Arno Jul 23 '15 at 09:19
  • @DavidArno The "no source file of more than 200 lines" rule says nothing about the classes' complexity. A class' complexity is determine by it's member fields, not by the methods - and the fields are only a small part of the code. If you add another 20-line method that pretty-prints objects the class doesn't get more complicated - if you are adding another field(1 line) it does. – Idan Arye Jul 23 '15 at 10:41
  • @IdanArye, I would argue that a system with no class > 200 lines actually speaks volumes about the likely complexity of that system. A single class of < 200 lines tells one nothing. However, that's academic; my point was simply that one should seek to contain state, no matter how large the file and thus MetaFight's assumption was wrong. – David Arno Jul 23 '15 at 11:34
  • 1
    @davidarno I used to think as you do. Then I discovered clojure - a functional language on the jvm. Now I still think as you do, I just use better tools. – emory Jul 23 '15 at 23:39
  • @DavidArno my assumption about your classes and their sizes *may* have been wrong. However, I still think private methods are a tool just like any other. There's a time and a place to use them. It's not the fault of the tool if it gets abused by reckless users. And those abuses are no reason to abandon the tool altogether. – MetaFight Jul 24 '15 at 12:00
3

To answer this, we should clarify the definition of static:

Static methods are meant to be relevant to all the instances of a class rather than to any specific instance. They are similar to static variables in that sense. An example would be a static method to sum the values of all the variables of an instance for a class. For example, if there were a Product class it might have a static method to compute the average price of all products.

Any static method can become a non-static method, so being static makes a statement about the impact calling such a method would have on your instance, which is to say none unless of course you were passing said instance to the static method (thus defeating the purpose of being static).

This method holds no state to do its job properly and could refer to any instance, so I would say yes, you should make it static. However do be sure to leave it also private, since it is a method that only makes sense in the context of your class, and until that changes, it should remain private.

If you find yourself with several such private static helper methods, you should consider creating a final class with private constructor containing only protected static methods, which can only be called by classes in your package.

I hope that answers your question.

Neil
  • 22,670
  • 45
  • 76