144

I'm writing an explanation for some code for a course, and have been accidentally using the words method and function interchangeably. I decided to go back over and fix the wording, but ran into a hole in my understanding.

From what I understand, a subroutine is a function if it doesn't act on an instance of a class (its effect is restricted to its explicit input/output), and is a method if it operates on an instance of a class (it may carry out side effects on the instance that make it impure).

There's a good discussion here on the topic. Note that by the accepted answer's definitions, a static method should actually be a function because an instance is never implicitly passed, and it doesn't have access to any instance's members.

With this in mind though, shouldn't static methods actually be functions?

By their definition they don't act on particular instances of a class; they're only "tied" to the class because of relation. I've seen a few good looking sites that refer to static subroutines as "methods" though (Oracle, Fredosaurus, ProgrammingSimplified), so either they're all overlooking the terminology, or I'm missing something (my guess is the latter).

I'd like to make sure I am using the correct wording.
Can anybody clear this up?

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • 2
    I always thought it was function in php and method in Java. Basically the same thing with different names – Kaloyan Roussev May 22 '15 at 17:02
  • 20
    There's a difference between theoretical computer science and how a language applies it. The JLS makes no distinction and calls it a method. – Jeroen Vannevel May 22 '15 at 17:03
  • 3
    http://stackoverflow.com/a/155655/2669716 – Anirudh May 22 '15 at 17:07
  • @JeroenVannevel is correct. On terminology: an **instance** of a class is an **Object** and it has instance methods. A class can have static methods and won't apply to any instances created from the class. – Vic May 22 '15 at 17:18
  • 2
    It might be of interest to look at the definitions of "function" and "method" in Python, where there _is_ a difference: basically, a function is a chunk of code with a symbol table and a calling convention, whereas a method is what you get when you put a function into a class. The difference is quite subtle though, even to people who know Python. – David Z May 22 '15 at 19:27
  • I'd take the opportunity to explain how confusing it can be when authors of a programming language start playing with terminology, because *static methods* are exactly the same as *functions*. –  May 22 '15 at 19:40
  • 2
    When I was learning theory, I learned function returns a value and procedure does not. Then I learned java calls functions and procedures methods. Now I am trying functional programmjng and a function is idempotent. The terms change meaning on context. – emory May 23 '15 at 00:31
  • The difference between a static method and a function in most OO languages is that a method is allowed to access private variables and methods of the class. – Barmar May 26 '15 at 19:56
  • @Radiodef, how come this is not a duplicate of the linked question ? http://stackoverflow.com/questions/155609/difference-between-a-method-and-a-function – Habib May 26 '15 at 21:59
  • @Habib I'm inclined to turn that around and ask how it is a duplicate. This question references the definitions from the answers in that question and asks (in so many words) why Java doesn't appear to follow them. It's not clear to me how that is addressed by the referenced Q&A. – Radiodef May 26 '15 at 22:07
  • Terminology is language-specific. Java has a lot of terminology that may or may not have usage in the context of other languages. There is no universal terminology. It is just like a language's syntax. – Aleksandr Dubinsky May 27 '15 at 12:35

9 Answers9

129

This quote from 8.4.3.2 may help:

A method that is declared static is called a class method.

A method that is not declared static is called an instance method [...].

  • Class methods: associated with a class.
  • Instance methods: associated with an instance.

Java just wants you to "think object-oriented". Also, static methods have access to a surrounding scope which may include state. In a way, the class is like an object itself.

Community
  • 1
  • 1
Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • That being said, while "function" is technically correct as a unit of execution in Java, the preferred nomenclature throughout pretty much all of Java is "method", since all Java functions are part of a class or interface (excluding lambdas, and maybe some other things I'm not aware of). – Shotgun Ninja May 22 '15 at 17:17
  • 1
    Lambdas are actually anonymous inner classes with the `@FunctionalInterface` annotation and with 1 method under the hood. A lambda is just syntactic sugar and in that regard there is nothing new. – Adam Arold May 22 '15 at 22:47
  • 1
    @AdamArold Lambdas are quite a bit fancier than an anonymous inner class. For example, non-capturing lambdas can share an instance across multiple evaluations of a particular expression. (But you are right they ultimately get compiled to static and instance methods.) – Radiodef May 23 '15 at 00:33
  • @Radiodef Maybe a better way to phrase it would be "All lambda expressions can be replaced with equivalent non-lambda expressions, without making any changes to files other than the one containing the lambda expression" or something like that. – user253751 May 23 '15 at 11:16
  • 4
    I'm embarrassed. I'm coming from Scala and still managed to miss the fact that the class itself is object-like. Thank you. – Carcigenicate May 23 '15 at 12:17
  • Also, IIRC, a class method, if passed an instance of the class as an argument, can access the private members. (As well as any static private members.) – Harry Johnston May 24 '15 at 04:20
82

The simple answer is that when Java decided to call everything a "method", they didn't care about the distinction between a function and a method in theoretical computer science.

Bitcoin M
  • 1,206
  • 8
  • 24
  • 3
    That's right. Until and including Java 7 you won't even find the word "function" in the [Language Specification](https://docs.oracle.com/javase/specs/jls/se7/html/index.html) – Erwin Bolwidt May 23 '15 at 06:48
  • 4
    As much as I like the simplicity of this answer, I think Radiodef's answer is more on track because it mentions the key point that the class itself acts as an object. Thank you though. – Carcigenicate May 23 '15 at 12:15
  • 2
    Interestingly, this is paralleled by earlier languages' decisions not to differentiate between functions and subroutines. – Random832 May 23 '15 at 13:37
  • 4
    I'm unpleasantly surprised that this answer got so many upvotes. Firstly, this answer pretends that class methods don't exist. Secondly, this is hardly a concept introduced in Java. Class methods already existed in Smalltalk, for example, which was there for decades before Java became a thing. – Malcolm May 23 '15 at 19:46
  • 1
    @Malcolm I have to agree with you. After considering the other answers, this seems wrong. It's not apathy on the Java creator's part, unless they truly didn't care but ended up naming it correctly regardless. – Carcigenicate May 24 '15 at 15:45
  • 1
    By "class methods" @Malcolm, do you mean Java's static methods? The point that BitcoinM is making is that in the Java language we don't use the word "function" for instance or static methods. This is implied in Radiodef's answer as well. We can talk about OOP theory but programmers don't make that distinction and the Java language specs don't as well. – Gray May 26 '15 at 21:21
  • 1
    @Gray Once again, quoting JLS: _"A method that is declared static is called a class method."_ I don't know, to be honest, how to tie your comment to the actual contents of the answer. I see a completely different point in there, like Java creators invented some wrong terminology when it is in fact (a) entirely correct and (b) had existed before Java. And as for the distinction, it's pretty clear to me that if all the functions in Java are methods, it makes more sense to call them methods. – Malcolm May 26 '15 at 21:46
27

Static methods are not exactly functions, the difference is subtle, but important.

A static method using only given input parameters is essentially a function.

But static methods may access static variables and other static functions (also using static variables) so static methods may have a state which is fundamentally different to a function which are by definition stateless. (ADDENDUM: While programmers are often not so strict with using "function" as definition, a strict function in computer science can access only input parameters). So defining this case of accessing static fields it is not valid to say that static methods are always functions.

Another difference which justifies the usage of "static method" is that you can define in C derivates global functions and global variables which can be accessed everywhere. If you cannot access the class which contain static methods, the methods are inaccessible, too. So "static methods" are limited in their scope by design in contrast to global functions.

Thorsten S.
  • 4,144
  • 27
  • 41
  • 2
    I kind of like this answer, but would like to better understand some things. Isn't this more a "pure" vs "side-effectful" function, rather than function vs method? Or is it that a method is such because of side effects? I'm just brainstorming here. – Nadir Sampaoli May 23 '15 at 12:24
  • 2
    This answer is right. However, one could argue that functions in many (most?) languages can access global variables, so they are often not strictly stateless (same input, same output). And in the case of Java static methods, to access class variables could be considered equivalent to access "global" (i.e. not local to a function/method) variables - with the class instance being sort of a namespace. – leonbloy May 24 '15 at 20:31
  • 2
    @leonbloy Pure [Functional programming languages](https://en.wikipedia.org/wiki/Functional_programming) like Haskell are completely stateless; there's nothing which can be called a global variable. – Thorsten S. May 24 '15 at 20:42
17

In Java, a user-defined class is actually an instance of a subclass of java.lang.Class.

In this sense, static methods are attached to an instance of a conceptual class: they are attached to an instance of a subclass of java.lang.Class.

With this in mind, the term "class method" (an alternate name for Java's static methods) begins to make sense. And the term "class method" can be found in many places: Objective C, Smalltalk, and the JLS -- to name just a few.

Mike Clark
  • 10,027
  • 3
  • 40
  • 54
  • Is it possible to have two instances of this subclass? – Random832 May 22 '15 at 19:18
  • Of course, you can load a class in different classloaders (the reason of getting ClassCastExceptions with the message "cannot cast CustomClass to CustomClass"). – dunni May 22 '15 at 20:41
  • 2
    @Random832 -- sort of. You can have two (or more) instances of the same Class subclass in the same JVM, as long as each instance has its own separate classloader. You cannot instantiate the same Class subclass more than once per classloader. It gets a little confusing and analogies to classic OO concepts start to get stretched a bit thin at this point. – Mike Clark May 22 '15 at 22:35
  • @MikeClark if I do that, are they _really_ the same? Like, will the Class subclass be the same class even if the class itself is a different instance of it? Classloaders are pretty confusing to me. Could I call (without reflection) a static method of one classloader's instance of a class from another classloader's instance of the same class, by having a reference to it passed in? What if they have different methods? – Random832 May 22 '15 at 22:36
  • 1
    @Random832 "Sort of?" From a purely OO theory point of view, are any two instances of a class ever *really* exactly the same? At the very least two otherwise identical instances of the same class will have different addresses. Otherwise, how can we have two of a thing? The only thing that is *exactly* the same as something, is the thing itself. – Mike Clark May 22 '15 at 22:40
  • By "really the same" I mean the class _of_ the class (i.e. the class-subclass itself) being `==`-equal, being able to pass either one to a parameter of type Class, etc. – Random832 May 22 '15 at 22:42
  • In that sense they are definitely not the same. The JVM will not let you cast com.foo.Bar (from classloader A) to com.foo.Bar (from classloader B), and they will not be considered `==` equal. Re: generics: I'm not quite sure. Generic checks are done at compile-time, so I'm not sure you'd find out you have a problem until runtime. – Mike Clark May 22 '15 at 22:42
  • I'm talking about whether the class _of_ [A]com.foo.Bar.class is the same as the class of [B]com.foo.Bar.class - i.e. whether they are both separate instances of a single hypothetical "ClassComFooBar extends Class", or whether there are also two separate ClassComFooBar's for each loader's com.foo.Bar.class to be instances of. That is, will com.foo.Bar.class.getClass() return A) two separate values, per loader B) one value shared only by com.foo.Bar classes or C) java.lang.Class.class? – Random832 May 22 '15 at 23:43
  • @Random832 [A]com.foo.Bar.class and [B]com.foo.Bar.class are not instances of some a singleton "ClassComFooBar extends Class" inside the JVM. There will be [A]"ClassComFooBar extends Class" and [B]"ClassComFooBar extends Class", respectively. The two classes could contain 99% different bytecode from each other (they might only have a name in common). On the other hand, the two classes can (and very often do) have identical bytecode, loaded from the same source. In which case [A]Bar and [B]Bar are conceptually identical, but still treated as entirely unrelated by the JVM. – Mike Clark May 26 '15 at 18:53
  • So then the answer to "Is it possible to have two instances of this subclass?" was "no." – Random832 May 26 '15 at 18:54
  • I agree with you that the answer is definitely "no" _in a certain [very real] context_. Two contexts that are interesting to me are: conceptual classes (_roughly_, at the UML level) vs. "physical" classes (_roughly_, at the JVM level). To me, if [A]Bar and [B]Bar have identical bytecode that is loaded from the same resource, they are conceptually two instances of the same class. The JVM physically separates [A]Bar and [B]Bar, and treats them as unrelated, but that does not mean they are unrelated (or even unidentical) in all possible ways of thinking about the structure of the system. – Mike Clark May 26 '15 at 19:06
11

In computer science function clearly maps to a static method. But "method" of a class is a bit generic, like "member" (field member, method member). There are wordings like

Data members and method members have two separate name spaces: .x and .x() can coexist.

So the reason is, that as the philosoph Ludwig Wittgenstein said, Language is a tool with different contexts. "Method" is a nice moniker in the citation above to categorize a "member".

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
9

Your thinking is right and it makes sense. It's just not established terminology in the Java community. Let me explain some internals that can help understand why the terminology subsists.

Java is a class based object oriented language. A method is always member of a class or instance (This is a general statement valid for other programming languages too). We think of class and instance being both objects.

Instance method (dynamic)

You cannot invoke this method from a class directly, you have to create an instance. Each instance references that method. You can overwrite a method definition with the exact same method signature (when subclassing), i.e. the reference points to a different method (which has the same signature, but can have a different method body). The method is dynamic.

Class method (static)

You only can invoke this method from the class directly, i.e. you don't need to create an instance of that class. There is only one global definition of that method in the whole program. You cannot overwrite the exact same method signature when the method is declared static, because there is only one definition valid for the whole program. Note that the method is member of the class object itself, the instances have all the same unique (and fix) reference to that method.

Ely
  • 10,860
  • 4
  • 43
  • 64
7

Here is another take on the terminology, using Scala as a mnemonic:
In Scala you have objects, which are singleton instances of an implicitly defined class 1.

Per your definition, we can call these subroutines belonging to the object methods, as they operate on a single instance of the class.
Additionally the object will also define class A, and create all of the methods in object A as static methods on class A (for interfacing with Java) [2].

Therefore we can say that the static methods of Java class A access the same members as the Scala singleton instance, which per your definition then deserve to be called (static) methods of class A.

Community
  • 1
  • 1
mucaho
  • 2,119
  • 20
  • 35
2

Of course, the main difference is - method can use static fields, not only method parameters. But there is additional one - polymorphism! Results of evaluation Class A.doTheSameStaticMethod() and ClassB.doTheSameStaticMehod() will be depends of class. In this case function is impotent.

1

Each class has an object to represent it that is an instance of a subclass of the Class class. Static methods are really instance methods on these objects that are instances of a subclass of Class. They have access to state in the form of static fields, so they are not restricted to being just (stateless) functions. They are methods.

Bohemian
  • 412,405
  • 93
  • 575
  • 722