2

So I'm learning Java (gasp bet you could've never guessed that), and today I'm focused heavily on making sure that I'm using static methods properly.

My big practice program right now is an account manager program, that I tweak and add to as I learn more and more concepts. One component of it is printing out a list of all the accounts added to the system. Because this list gets summoned more than once, I created a static method that can be invoked to generate it, and placed it above my main method in the code.

My question is: should I do this? Is it a good idea/good programming etiquette to create methods like this for repetitive sections of code? And if the answer to both of those is yes, should I make it a static method?

Here's the code for the static method I'm talking about:

/**
 * accountList() method displays a list of all accounts currently loaded into the program
 */
public static void accountList(){
    System.out.println("     ACCOUNT LIST");
    System.out.println("NUMBER      INFORMATION");
    for(int num = 0; num < accountArray.size(); num++){
        System.out.println("  " + (num + 1) + "         " + accountArray.get(num).getAccountName()
                         + " : " + moneyFormat.format(accountArray.get(num).getValue()) + " "
                         + accountArray.get(num).getCurrencyType());
    }
    listMax = accountArray.size();
}

Then below this would be my main() method, and periodically within my main would be the invocation of this method to generate an account list:

public static void main(String[] args){
    accountList(); //example of how I would invoke this method
}

So, do I have this figured out properly? Am I using this correctly? Thanks.

PS. My accountList() method is in the same class as my main() method, which is why there's no class name before it. That's also why I'm asking, because I know one of the main purposes of the term "static" is that it would be easily accessible from another class, so I'm not sure if it needs to be static if it's in this same class.

Razib
  • 10,965
  • 11
  • 53
  • 80
craigmiller160
  • 5,751
  • 9
  • 41
  • 75
  • 2
    Yes, creating small, focused methods is good, since it is a small bit of logic which you can understand by itself. Whether or not they should be static depends upon what you are using them for. This case does not look appropriate, however, since you are mutating state (listMax), and mutable static state is normally a bad idea since it is basically a global variable. – Andy Turner Mar 14 '15 at 19:58

5 Answers5

2
  1. Is it a good idea/good programming etiquette to create methods like this for repetitive sections of code?

    Having many small methods in stead of fewer large methods is a good practice in terms of maintainability and re-usability.


  1. should I make it a static method?

    Static methods are used when they do not depend on state of some particular instance of the class. It is in general avoided since subtype polymorphism is not available for static methods (they can't be overridden). Small utility methods are made static (like Math.sqrt or System.currentTimeMillis()).


Note: (Optional)

When you define methods to re-use the code, the most important aspect is the contract that the method is supposed to fulfill. So the methods should communicate with each other using arguments and return values for predictable behavior. Mutating state of class fields (or even worse static fields) is generally considered a bad idea (you have to do it though sometimes).

You could improve your method to something like following.

public static void printAllAccounts(List<Account> accountList) {
    // Your code ...
}

This method specifies which accounts to print, and does not depend on state.

It would be even better if you can delegate it to another class and make it a non static behavior. That way if you come up with better way of printing all accounts, you can replace the behavior without touching this method.

Hope this helps.
Good luck.

Tanmay Patil
  • 6,882
  • 2
  • 25
  • 45
2

Don't repeat yourself (DRY) is a widely accepted principle and good practice, and creating methods for code that would otherwise be duplicated is the simplest and most obvious form for this.

(In some languages/contexts people hint at the potential overhead of a method invocation and its impact on performance. In fact, inlining methods is a common optimization that compilers do. But modern compilers (and particularly, the Just-In-Time-Compiler of the Java Virtual Machine) do this automatically when it is appropriate)


Whether helper methods should be static has already been discussed elsewhere.

My rule of thumb here is: Whenever a method can be static, then it should be static.

A more differentiated view: When a method does not modify instance fields (that is, when it does does not operate on a mutable state), but instead only operates on its arguments and returns a result (and is a "function", in that sense), and when it should not be involved in any form of polymorphism (meaning that it should not be overloaded), then it should usually be made static. (One might have to take aspects of unit testing into account here, but that might lead too far now)


Concerning your specific example:

You have a different problem here: The accountArray obviously is a static field, as well as the listMax variable. And static (non-final, mutable) fields are usually a horrible idea. You should definitely review this, and try to make sure that you do not have static fields that describe a state.

If you did this, your method could still be static, and receive the accountArray as a parameter:

public static void accountList(List<Account> accountArray){
    System.out.println("     ACCOUNT LIST");
    ...
}

However, in this form, it would violate another best practice, namely the Separation of Concerns. The method does two things:

  • it creates a string representation of the accounts
  • it prints this string to the console

You could then split this into two or three other methods. Depending on the indented usage, these could, for example, be

public static String createAccountInfoString(List<Account> accounts) {...}

public static void printAccountInfo(List<Account> accounts, PrintStream ps) {
    ps.println(createAccountInfoString(accounts));
}

public static void printAccountInfo(List<Account> accounts) {
    printAccountInfo(accounts, System.out);
}

(note that the method names indicate what the methods do. A method name like accountList doesn't tell you anything!).


However, as others have pointed out: Overusing static methods and passing around the information may be a sign of not properly using object-oriented concepts. You did not precisely describe what you are going to model there. But based on the keywords, you might want to consider encapsulating the account list in a class, like a class AccountList, that, among others, offers a method to print an account list to a PrintStream like System.out.

Community
  • 1
  • 1
Marco13
  • 53,703
  • 9
  • 80
  • 159
1

static members of a class (that is variables, method) are not related/associated to the instance/object of the class. They can be accessed without creating object of the class.

General rule of using static method is - "Ask yourself is the property or method of a class should applicable for all of the instance of the class". If the answer is yes then you may use static member.

Consider the following example -

public class Student{
    private int noOfStudent;
    .......

} 

Now you have a Student type. In this case you may consider to make the noOfStudent property static. Since this is not the property of a Student itself. Because all students of a class should share the same property of noOfStudent.

You can find more explanation here

Hope it will Help.
Thanks a lot.

Community
  • 1
  • 1
Razib
  • 10,965
  • 11
  • 53
  • 80
1

Here's what a static method is. A static method from the same class, you can just call without the class name, but a static method from another class, you would have to call with the class name. For example, if you have a static method called method1 in a class called Class1, and you're trying to call the method in a different class called Class2, you would have to call the method like this:

Class1.method1();

If you just use method1(), it would show up as an error, and it'll tell you that it can't find the method, because it only searches the class you're in for the method, and it doesn't find it. You would have to put the class name, Class1, so it knows to go search for the method in Class1, and not the class you're in.

As for whether you should use a static method or not, that depends, really, on your preference. Do you know the different between a static method, and a non-static one? I'll just gives you the basics for now. If you have more questions, you can ask.

Okay. A non-static method can only be called when you make an object out of the class the method is in. This is how you make an object:

(CLASS NAME)(OBJECT NAME) = new (CONSTRUCTOR NAME)();

The constructor's name is the same as the class name. And when you call the method, you would put (OBJECT NAME).METHOD NAME(); to call it. As for a static method, I already told you how you can call it. So. Anymore questions?

Ski
  • 111
  • 2
  • 3
  • 17
1

The use of static methods is something that could remember procedural programming. In fact, if you use static methods you cannot use OOP principles, like polymorphism.

First of all, it is not good that a method, which aims is to print a list, could change program state. Then, in the future, you may want to change the way the list is printed. Let say, you want to print it in file. How would you change your program to satisfy this new requirement if your ar using a static method?

Try to think more OO, and in the beginning, try to put your code inside a dedicated class (i.e. Printer). Then, you can extract an interface from that class, and finally try to apply some design patterns, like Strategy Pattern or Template Method Pattern.

riccardo.cardin
  • 7,971
  • 5
  • 57
  • 106