[Tutorial] Creating a Utility class

Discussion in 'Resources' started by Dragonphase, Aug 4, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Dragonphase

    A utility class is an efficient way of allowing you to create methods that you often re-use in your code. If you find yourself using the same code over and over, and it doesn't depend on an instance variable, you can put that code in a method within a Utility class and call the method from there.

    A basic example of a Utility class:

    Code:java
    1. import java.util.Arrays;
    2.  
    3. import org.bukkit.Location;
    4.  
    5. public final class Utils {
    6. public final static String MC_VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
    7.  
    8. private Utils() { } //Prevent the class from being constructed
    9.  
    10. /**
    11.   * Remove the first element from an array
    12.   * @param args The array
    13.   * @return The trimmed array, without it's original first element
    14.   */
    15. public static <T> T[] trim(T[] args){
    16. return Arrays.copyOfRange(args, 1, args.length);
    17. }
    18.  
    19. /**
    20.   * Retrieve a location as a custom String
    21.   * @param location The location
    22.   * @return The custom String representing the location
    23.   */
    24. public static String getLocationationAsString(Location location){
    25. return "world: " + location.getWorld().getName() + ", x: " + location.getBlockX() + ", y: "+location.getBlockY()+", z: " + location.getBlockZ();
    26. }
    27. }


    Some things to note about Utility classes:
    • A Utility class should be final, indicating that it cannot be extended.
    • A Utility class should contain a private constructor, indicating that it cannot be constructed.
    • A Utility class should only contain final static fields. These fields are effectively constants.
    • A Utility class should only contain static methods. Why? Other than obvious reasons such as not being required to create an instance of the Utility class, a static method causes less overhead because of the fact that it is executed at compile-time.
    "Why should it only contain static fields? I've heard using statics is bad!"
    Public static fields represent a global state. This means that anything can modify them due to them having a global scope. Consider this example:

    Code:java
    1. public class PlayerInfo{
    2. public static Player somePlayer;
    3. public static String someData;
    4.  
    5. public PlayerInfo(Player player, String data){
    6. somePlayer = player;
    7. someData = data;
    8. }
    9. }


    Since somePlayer and someData are both static, they belong to the class and not any one instance of the class. Every time you instantiate a new PlayerInfo object, you're overriding the data stored in somePlayer and someData, because they're static. It's considered bad practice.

    This is different for Utility classes however; we've already established that a Utility class cannot be instantiated. Because it's final, it cannot be extended, and all fields inside it are static and final, AKA constant, and cannot be changed elsewhere.
     
    Phasesaber likes this.
  2. Offline

    raGan.

    How does that work? Are you implying that static fields of final class can't be changed?
     
  3. Offline

    Dragonphase

    raGan.

    Whoops, I knew I missed something. Fixing :D
     
  4. Offline

    LePouletSuisse0

    Hi, I just saw this tutoriel and it was exactly what i was looking for but a still got a question: How can we access to a Util method from our main class?

    If i got in my Util.class:
    Code:java
    1. public final class Util {
    2. private Util() { } //Prevent the class from being constructed
    3.  
    4. public static boolean TrackError(int i){
    5. boolean bol=(i==0) ? true:false;
    6. return bol;
    7. }
    8. }


    How can i access it in my code? I tried to import it but it doesn't seems to work if i don't call it like
    Code:java
    1. if(Util.TrackError(x)){
    2. //Do something interessant
    3. }


    But it just mean nothing, i could do a simple class if i wanted that... i want to call it without object, like
    Code:java
    1. if(TrackError(x)){
    2. //Do something interessant
    3. }


    I know it's a basic question but i'm a beginner :/

    Thank you for this tutoriel
     
  5. Offline

    JBoss925

    Import the methods statically at the top of your code like
    Code:java
    1. import static path.to.util.*;
     
  6. Offline

    Not2EXceL

    JBoss925
    You shouldn't be telling a user to use bad habits.
     
    Dragonphase and Skyost like this.
  7. Offline

    raGan.

    That is not true. You would only need to add that simple piece of text (Util.) before the method call. You don't need an actual object instance stored anywhere or passed by anything to call static method. Static imports might lead to a confusion, because those calls can't be simply distinguished from local method calls. (I know IDEs tend to display them differently.)
     
  8. Offline

    Not2EXceL

    Not only this, but static imports should be used very sparsely. In some cases its valid to use them, but for static class methods, no, especially when the class is named a common name like util.
     
  9. Offline

    JBoss925

    I understand it's a bad habit, perhaps I should've warned the user but still, it's the only way to achieve the effect they wanted.
     
  10. Offline

    Dragonphase

    LePouletSuisse0

    I understand what you're asking now. A utility class isn't designed to remove the requirement of the class specification, it's designed to store a number of methods that you might find yourself using a lot in more than one class. It reduces the amount of repeating code.
     
  11. Offline

    Phasesaber

    JBoss925
    No, just import it regularly. Util.methodName(args); works fine, it's just like any other static method in any other class.
     
  12. Offline

    LePouletSuisse0

    Thank everyone for this answer.
    Dragonphase
    I knew this method is for my own method for the repeating code but it seems strange that i have to call a Object with it. Anyway, i got my response and i think i'll do a normal import and use the Util.method();, seems better. Thank one more time for helping me ^^'
     
  13. Offline

    Not2EXceL

    LePouletSuisse0

    You're not calling an object with it, nor using an object to reference the method. :mad:

    You're simply referencing the method from the class -_-
     
  14. Offline

    RawCode

    does not belong to cbukkit.
    this tutorial is reimplementation of JDK javadocs
     
Thread Status:
Not open for further replies.

Share This Page