9

Why would there be an advantage to use a static method and pass the reference to an object as a parameter rather than calling the method on an object?

To clarify what I mean, consider the following class:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

Compared to this alternative implementation with a static method:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

My question is not restricted to this class alone; any point where you'd pass an object instead of calling it on a method is what I'm interested in. Is this ever advantageous? If so, why?

Ixrec
  • 27,621
  • 15
  • 80
  • 87
Addison Crump
  • 723
  • 1
  • 6
  • 10
  • 1
    It feels like a code smell with two methods doing the exact same thing. If the static method simply delegated to the other method, then it would feel useless, but not necessarily "bad" – Nathan Merrill Mar 11 '16 at 18:42
  • 13
    @NathanMerrill I think you're missing the point. He's asking if there's ever a situation where creating and using the second method *instead of* the first method would be preferable. –  Mar 11 '16 at 18:44
  • @Mego Not only the methods given in the example; I'm asking if there is _any_ moment when using static methods and passing objects is better than calling methods on objects? – Addison Crump Mar 11 '16 at 18:46
  • Presumably you are asking specifically for java? – enderland Mar 11 '16 at 18:51
  • @enderland Yes - that's why I tagged it as such. I suppose it could be applicable to multiple programming languages... should I remove the tag? – Addison Crump Mar 11 '16 at 18:53
  • Could you edit this question to ask about what makes situations good for this sort of thing, rather than asking for examples? There are tons of examples, which makes that sort of question really broad (and not a good fit for the site). – Telastyn Mar 11 '16 at 19:16
  • @Telastyn I've edited the question - any more notes for phrasing/broadness-fixing? – Addison Crump Mar 11 '16 at 19:24
  • 3
    I think this question makes a tacit assumption that object oriented code is some kind of optimum. A more procedural or functional approach would naturally lead to the use of static methods. ...Duplicating the functionality between a static and a instance method is pretty silly, though. I hope that's just an example and the actual code you're talking about only has the static. – jpmc26 Mar 12 '16 at 06:14
  • Related: [Can't I just use all static methods?](https://programmers.stackexchange.com/questions/98083/cant-i-just-use-all-static-methods?rq=1) – Ferrybig Mar 12 '16 at 12:04
  • This question got flagged as unclear, presumably because your example was a single class with two "redundant" methods if taken at face value, so I've changed the example code to better reflect what I think you intended to ask (and what most of the answers are trying to answer) which is why the class with a static method would be better than the equivalent class with an instance method. – Ixrec Mar 13 '16 at 16:06

4 Answers4

34

A trivial example: when the instance passed can legitimately be null and you want to incorporate the (non-trivial) handling of this into the method.

enderland
  • 12,091
  • 4
  • 51
  • 63
9000
  • 24,162
  • 4
  • 51
  • 79
  • 1
    example: String.Compare in C# (I think there is something similar in Java) – edc65 Mar 12 '16 at 02:10
  • Objects.equals() and Objects.compare() are examples in Java - but they aren't on the original class. In the Java standard library at least, it's common to have an instance method on something like Object, but then a static method on an Object**s** class. – daboross Mar 12 '16 at 21:15
20

In your example, the instance method is a clear winner.

In the general case, I can think of a few reasons where a static method might be appropriate:

  • You want to put the static method in another class, since you have a situation where it makes sense to separate the logic from the data (note: your example is not one of them).

  • You are passing two or more objects and want to emphasize that they are of equal importance.

  • null is a valid value (as explained by user 9000).

Heinzi
  • 9,646
  • 3
  • 46
  • 59
5

It would be wise to include the methods which change the state of the object as instance methods rather than static method.

However we can find examples of static methods which are pure methods and take the object as input, like when we need to instantiate the object based on certain validation rules. For example, .NET has the method DateTime.TryParse(String s, DateTime d) to validate and instantiate the object. But the parameter DateTime d is explicitly marked as out.

Another case can be when we compare the objects and want to get the desired object as return value rather than a boolean / integer value of comparison result, for example, Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). This will be cleaner than:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(leaving the case "draw" out for simplicity).

wonderbell
  • 722
  • 5
  • 7
  • 1
    One does not pass an "entire object". You pass the reference to a place in memory, which is a very small amount of data being passed. I'm not sure about the affect on performance that that has, but nevertheless... also, what does the "out" marking imply? – Addison Crump Mar 11 '16 at 20:00
  • 1
    I dropped the word 'entire' from my statement, it was confusing. I never intended performance or size, the answer is purely based on programming practices. Anyway, `out` is a `.Net` keyword used as a parameter modifier. It states that the parameter is passed by reference. See for details https://msdn.microsoft.com/en-us/library/t3c3bfhx.aspx – wonderbell Mar 11 '16 at 20:28
  • 4
    The first sentence is simply wrong. if we have `class C { int x; static void M() { ` then M is perfectly able to access `x`. For example `int y = (new C()).x;` is legal. – Eric Lippert Mar 12 '16 at 18:27
  • @EricLippert :) I am sure you know what did I mean. It's amazing how masters can read between the lines. May be I need to edit that sentence. For clarification, something like this `static void M() { this.x = 1; }` is not possible. – wonderbell Mar 12 '16 at 21:26
  • 1
    @wonderbell: No, I am sure I did not know what you meant. I knew what you wrote. I note that `this.x` is wrong not because `x` cannot be accessed but because `this` does not exist. It's not a question of *access* at all, it's question of *existence*. – Eric Lippert Mar 12 '16 at 21:35
  • @EricLippert I agree. I have edited the answer. Thanks for clever comments. – wonderbell Mar 12 '16 at 21:55
4

Dependency Injection would be a good reason to perform the call to the static method. Assuming that the concrete implementation of SomeClass has an inheritance chain or is the implementation of another class. You could use a mock of an object, pass that it for testing purposes to insure that your method does what it is supposed to, and then reports on that status.

Adam Zuckerman
  • 3,715
  • 1
  • 19
  • 27