private or public doesn't make a difference - static methods are OK, but if you find you're using them all the time (and of course instance methods that don't access any instance fields are basically static methods for this purpose), then you probably need to rethink the design.
Yes, we can have private methods or private static methods in an interface in Java 9. We can use these methods to remove the code redundancy. Private methods can be useful or accessible only within that interface only.
Most helper or utility classes use static methods. You should only use non-static methods if you want to create multiple instances of your helper class, but since you just need a simple input -> function -> output, I would make the methods static.
Static helper classes are classes which contain only static methods, often having names that end in Helper or Utils. The existence of such a class usually indicates a sub-optimal design.
I prefer such helper methods to be private static
; which will make it clear to the reader that they will not modify the state of the object. My IDE will also show calls to static methods in italics, so I will know the method is static without looking the signature.
It might result in slightly smaller bytecode, since the static methods won't get access to this
. I don't think it makes any difference in speed (and if it did, it would probably be too small to make a difference overall).
I would make them static, since I generally do so if at all possible. But that's just me.
EDIT: This answer keeps getting downvoted, possibly because of the unsubstantiated assertion about bytecode size. So I will actually run a test.
class TestBytecodeSize {
private void doSomething(int arg) { }
private static void doSomethingStatic(int arg) { }
public static void main(String[] args) {
// do it twice both ways
doSomethingStatic(0);
doSomethingStatic(0);
TestBytecodeSize t = new TestBytecodeSize();
t.doSomething(0);
t.doSomething(0);
}
}
Bytecode (retrieved with javap -c -private TestBytecodeSize
):
Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
private void doSomething(int);
Code:
0: return
private static void doSomethingStatic(int);
Code:
0: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: invokestatic #2; //Method doSomethingStatic:(I)V
4: iconst_0
5: invokestatic #2; //Method doSomethingStatic:(I)V
8: new #3; //class TestBytecodeSize
11: dup
12: invokespecial #4; //Method "<init>":()V
15: astore_1
16: aload_1
17: iconst_0
18: invokespecial #5; //Method doSomething:(I)V
21: aload_1
22: iconst_0
23: invokespecial #5; //Method doSomething:(I)V
26: return
}
Invoking the static method takes two bytecodes (byteops?): iconst_0
(for the argument) and invokestatic
.
Invoking the non-static method takes three: aload_1
(for the TestBytecodeSize
object, I suppose), iconst_0
(for the argument), and invokespecial
. (Note that if these hadn't been private methods, it would have been invokevirtual
instead of invokespecial
; see JLS §7.7 Invoking Methods.)
Now, as I said, I don't expect there to be any great difference in performance between these two, other than the fact that invokestatic
requires one fewer bytecode. invokestatic
and invokespecial
should both be slightly faster than invokevirtual
, since they both use static binding instead of dynamic, but I have no idea if either is faster than the other. I can't find any good references either. The closest I can find is this 1997 JavaWorld article, which basically restates what I just said:
The fastest instructions will most likely be
invokespecial
andinvokestatic
, because methods invoked by these instructions are statically bound. When the JVM resolves the symbolic reference for these instructions and replaces it with a direct reference, that direct reference probably will include a pointer to the actual bytecodes.
But many things have changed since 1997.
So in conclusion... I guess I'm still sticking with what I said before. Speed shouldn't be the reason to choose one over the other, since it would be a micro-optimization at best.
My personal preference would be to declare them static, as it's a clear flag that they're stateless.
The answer is... it depends.
If member is an instance variable specific to the object you're dealing with, then why pass it as a parameter at all?
For instance:
public class Example {
private Something member;
public double compute() {
double total = 0;
total += computeOne();
total += computeMore();
return total;
}
private double computeOne() { /* Process member here */ }
private double computeMore() { /* Process member here */ }
}
One reason you might want to declare static helper methods is if you need to call them in the class constructor "before" this
or super
. For example:
public class MyClass extends SomeOtherClass {
public MyClass(String arg) {
super(recoverInt(arg));
}
private static int recoverInt(String arg) {
return Integer.parseInt(arg.substring(arg.length() - 1));
}
}
This is a bit of a contrived example but clearly recoverInt
cannot be an instance method in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With