How do you refer to a non-static method?

Discussion in 'Plugin Development' started by CompuIves, Apr 10, 2012.

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

    CompuIves

    Hi guys!
    I'm making a (HungerGames) plugin for my server and I stumbled upon the famous error: "Cannot make a static reference to the non-static method addTribute(Player) from the type TributeList"

    The code is:
    Code:
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
            Player player = null;
            if (sender instanceof Player) {
                player = (Player) sender;
            }
                else sender.sendMessage("You can't use this command without being player");
              if(cmd.getName().equalsIgnoreCase("hg")){ 
                  if (args[0].equalsIgnoreCase("Join"))
                      player.sendMessage("Trying to do command"); //for debugging purposes
                      TributeList.addTribute(player);
                  return true;
              } //If this has happened the function will break and return true. if this hasn't happened the a value of false will be returned.
              return false;
          }
    The problem is, I can't refer to the method addTribute... How do you guys fix this wrong refer? :confused:
    Thanks in advance!
     
  2. Offline

    Timr

    Modify TributeList with the static modifier. do the same with addTribute()

    ex:
    PHP:
    public static void addTribute() {}
    public static List<
    StringTributeList
     
  3. Offline

    CompuIves

    Thanks for the answer!
    I've tried to put addTribute to static, but I got a lot of error messages from that. TributeList is a class by the way, I forgot to mention that...
    addTribute:
    Code:
        public void addTribute(Player player) { //Add new tribute
            player.sendMessage("Call succesfull"); //TODO Remove this
            String playerName = player.getName();
            if (!this.Tributes.contains(playerName)) {
            this.Tributes.add(new Tribute(playerName, 0 , 1, new Date()));
            getServer().broadcastMessage(ChatColor.BLUE + playerName + " has joined the Game!");
            this.plugin.log(playerName + " was added to the list of Tributes.");
            save();
            }
            else {
                player.sendMessage("You are already participating");
            }
        }
     
  4. Offline

    Father Of Time

    Making everything static so that it can be reached outside of a class is extremely poor programming practice. What you need to do instead is put that function you are trying to use inside a handler class, then in your main plugin class create an instance of that handler and use a getter to get an instance of your handler class, then use that instance to call the function. So for example:

    Code:
    In Custom class:
     
    public void MyCustomFunction()
    {
    }
     
     
    In main class:
     
    private final ClassName MyClass = new ClassName();
     
    public static ClassName getClassName()
    {
    return MyClass;
    }
    
    With this kind of set up, regardless of what class you are in you can do the following to access your MyCustomFunction()

    Code:
        MainClass.getClassName().MyCustomFunction();
    You are making the getter function static so it can be accessible from anywhere, but the actual class itself is not static. You should get into the habit of creating handlers to do similar task, then making final static instances of those handlers inside the main class and using getters to access and use them.

    I hope this helps, good luck!
     
    FunIsDangerous likes this.
  5. Offline

    CompuIves

    Thank you very much! I think this will work!
    I tried your code like this:
    Code:
    public class HungerGames extends JavaPlugin
    {
      Logger log;
      public HashSet<Player> Frozen = new HashSet<Player>();
      public FileConfiguration config;
      public static HungerGames plugin;
      public String pluginName;
      final private TributeList tributelist = new TributeList();
     
    ...
     
      public static TributeList getTributeList()
      {
      return tributelist;
      }
    The problem is that I get the same error:
    Cannot make a static reference to the non-static field tributelist

    I fixed this with removing static from the handler, but I think that's not the way to fix it, is it?
     
  6. Offline

    Father Of Time

    It's my pleasure, I am happy to assist.

    Code:
    public class HungerGames extends JavaPlugin
    {
        Logger log;
        public HashSet<Player> Frozen = new HashSet<Player>();
        public FileConfiguration config;
        public static HungerGames plugin;
        public String pluginName;
        final private TributeList tributelist = new TributeList();
     
    ...
     
          public static TributeList getTributeList()
          {
            return tributelist;
        }
    
    Very nice implementation for a first try, I am very impressed. So with what you have here you could access any function within your TributeList class by doing the following:

    Code:
        HungerGames.getTributeList().FUNCTIONNAME();
    
    By making this function static:

    Code:
          public static TributeList getTributeList()
          {
            return tributelist;
        }
    
    it means that no matter what class you are in that you can call this function with:

    Code:
        HungerGames.getTributeList();
    
    And when you call that it returns an instance of your TributeList as it's "functionality", so with that instance you can then call any functions within it:

    Code:
        HungerGames.getTributeList().CALLFUNCTIONHERE();
    
    Remember, the above is the exact same as the following:

    Code:
        TributeList list = HungerGames.getTributeList();
        list.CALLFUNCTIONHERE();
    
    I hope this helps break it down and clarify things a bit more.

    Good luck with your project!
     
  7. How is that different from public methods ?
    No, seriously, I'm curious because I've been using static since I found out about it, it's much easier and I'm using them with 'protected', not 'public'.... which makes me question:
    I thought 'protected' restricted other classes except those in the same directory (or package) from accessing the methods and variables.
    And I thought static is only a instance-less pointer and that's why it can be accessed by using the class name instead of calling a new instance of it and getting that reference pointer.
    Correct me if I'm wrong :}
     
  8. Offline

    CompuIves

    Wow, that clarifies a lot!
    I have used your code and tips and I got still one problem to solve xD
    When I use my code I get an error at
    Code:
    final private static TributeList tributelist = new TributeList();
    error:
    The constructor TributeList() is undefined

    Thank you very much for your help, you've helped me already alot!
     
  9. Offline

    Father Of Time

    There are many reasons why they differ from one another, but the primary is something you already noted:

    Although you can make a function static and protected to allow it to be globally accessible and unalterable (to external class) you are also taking away the ability to have an instance of the object per class, and instead create a single instance that is shared among all of your class instances. As you've stated, static should be used when you would like to have an instant-less object to be shared among all classes.

    So for instance, I want to make a class that stores info on a player, and then I want to be able to get the players name from that class later.

    I could make the player name variable inside my custom record class static and that would allow me to access the players name any time I want, but it would have the consequence of making all the records share the same name. So rather than making the name static in the record, I would make the record handler static so it can be obtained from anywhere, and then use that record handler store a collection of none static records.

    I can use the static handler to get a single handler that has all my records, but then use that single instance of the handler to obtain player records which aren't static, hence each record can contain unique information on a record to record basis...

    Unfortunately I am having a hard time explaining myself because:
    1) I am extremely tired
    2) I am rushing trying to get out the door of my office
    3) it's a fairly hard thing to convey

    All I will say is this, when I began programming I used static for EVERYTHING... Static made life soo much easier (or it seemed), but as I got more advanced I started to feel the massive limitations of making everything static. Every professor I've ever had screams "Oh god no!" every time they see static variables, and frankly as time has gone in I've begun to understand why.

    Object oriented languages are just that, oriented around objects; by making something static you take aware some of the flexibility that you gain from having object instances, which negates the benefits of an object oriented language.

    Wow, that was a hell of a ramble with little substance... sorry! :D

    Do you have a java class named TributeList? if you are trying to make a literal list you need to use the following instead:

    Code:
        List<Object> TributeList = new ArrayList<Object>();
    replacing the word "Object" with the class type the list is storing.

    If you are trying to use a custom class that you've made simply paste the class itself so I can take a look and make sure all is good.

    Then my efforts are worth while, it's my pleasure to assist.

    I am heading home from work, take care CompuIves!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 25, 2016
    devilquak likes this.
  10. Offline

    CompuIves

    Oke, I'll send the class via private message because I can't publish the source code yet :).
     
  11. I am aware of what static is and I was not talking about classes that need to have multiple instances, beause of course you won't be able to access their data individually if they're static.... BUT, for stuff that don't need to have more than 1 instance (like that tribute list in the thread) I find it very usefull and easy to make them static and access them directly instead of sending pointers through variables or making tons of methods.
    Also, It's "object oriented" not "instance oriented", so it doesn't negate anything because you're still using objects, you just deny their use in multiple instances, which is good for stuff that don't need to have multiple instances and may as well hurt if you by accident call another instance and get the default values instead of the stored values.

    However, I want to understand why is static so "oh god, nooo!", but from what I've learned so far, I find it vey useful for ... well, static stuff.
     
  12. Offline

    CompuIves

    Woot!
    I think I fixed it.
    code:
    Code:
    public class HungerGames extends JavaPlugin
    {
      public static HungerGames plugin;
      final private static TributeList tributelist = new TributeList(plugin);
      Logger log;
      public HashSet<Player> Frozen = new HashSet<Player>();
      public FileConfiguration config;
      public String pluginName;
     
    ...
     
      public static TributeList getTributeList()
      {
      return tributelist;
      }
    I've put plugin in TributeList, I gotta test it out though, going to do that now.
     
  13. Offline

    hatstand

    I think that's part of what Father of Time is saying - It's useful for things you are only ever going to need one of.
     
  14. And that includes the list variable in this thread :p which also doesn't need a getter.

    CompuIves
    You got to understand what static and methods mean in order to understand what you've solved and if it's correct.

    In that last code of yours, the getTributeList is unnecesairy because you can just use HungerGames.tributelist.<methods> instead of HungerGames.getTributeList().<methods>, that extra method is a waste of space and processing in my opinion XD

    In your first code you could've quickly solved by setting addTribute() as static and the rest of things in your TributeList class as static *IF* you need only one tribute list (1 instance).

    That's what the error was talking about, you called a non-static method as a static.

    EDIT: eh, I thought that "i" was an "L" in your name xD
     
  15. Offline

    Sessional

    The way I tackle passing in plugins into each thing is I had a (<MyModMainJava> plugin) parameter to each of my constructors that I will need it in, and then set a variable inside the class to store that plugin. That way I can avoid "statics". I use a public getter to get it, and it can not be set from outside of the main plugin class. I make sure that each object I'm using can be referenced from this method.
    Code:
        public CommandHandler(WpsPlugin plugin)
        {
            this.plugin = plugin;
            returnPoints = new HashMap<String, Location>();
        }
    That is how I manage it. Later on from inside this CommandHandler class I can just go:
    plugin.getMyObject().<access>

    I have yet to run into a problem I can not solve this way. It may not be the best, but as said, statics are generally not an advisable programming practice.
     
  16. Offline

    desht

    What I see here, and what Father Of Time is also pointing out, is a lack of understanding of object-oriented design. Not intended to be condescending, since good OO design is a highly non-trivial subject. Using static methods to avoid complexity is to negate much of Java's OO power, and treat it as if it were C with some handy libraries. Which is fine for simple programs, but poor practice when creating large scalable systems (and especially when creating plugins which are part of a larger OO framework - in this case, Bukkit).

    Oracle intro: http://docs.oracle.com/javase/tutorial/java/concepts/

    Grady Booch's seminal book: http://www.informit.com/store/product.aspx?isbn=020189551X - if you're serious about getting into OO design & programming, this one's a must IMHO
     
    Father Of Time likes this.
  17. Offline

    Njol

    This implies that Bukkit "negates much of Java's OO power" since the class Bukkit only contains static methods. But since the server is a singleton, i.e. intended to only run once per program, static methods are perfectly acceptable. And a plugin is also intended to only run once per server which basically makes the plugin's main class a singleton (I don't know how Bukkit handles enabling/disabling of a plugin, thus I don't know whether the main class might be instantiated more than once).
     
  18. Offline

    desht

    I was actually referring to the entire Bukkit API, not just the Bukkit class (which is, as you say, a collection of static methods). I'm not suggesting that static methods should never be used - but a good design recognises which parts of the system should be composed of objects, and which methods should belong to a class (rather than instances of that class).
     
    Father Of Time likes this.
  19. Offline

    CompuIves

    Thank you guys, I will look some more into statics :).
     
  20. Offline

    Father Of Time

    I feel that both of your contributions were exactly the substance that my post were missing due to my lack of time to finish my thoughts. I don't believe any experienced programmer would ever suggest to avoid using static variables entirely; but as suggested by desht, to use them to reduce complexity is poor practice, and although it often works in smaller scale projects, will often prove to be a limitation as a project scales up.

    Often main classes have a plethora of static variables, because the main class is often where handlers, listeners, and other singleton objects reside, the reason being that we can use the main class as a "hub" to store and retrieve static variables. But as suggested once more by desht, when you look outside the main Bukkit class you will rarely see static variables used (not rarely, but definitely the minority compared to none static variables).

    I've done both, the first few years I programmed I heavily relied on static variables because I didn't understand instances that well and didn't know how to grab information private to one instance in another instance, but once I began to wrap my head around handler classes, getters, setters and a few other things I immediately realized how much more organized that method was.

    Me personally I would rather have all of my static objects in one class (my main class) and have every other class "call" that main class for information then having every class with it's own public static varibables that class A has to call class D for information, and class C has to call class B for information, and class C has to call class A for information, etc etc. I like to centralize my information so that I know no matter what it can be found by doing:

    mainclass.

    and not having to look at 30 different java classes to try and remember which I stored a specific variable in. I am just rambling at this point, but for me it's not even a matter of efficiency, but rather an issue of orginization and project simplicity.

    However, this is only my opinion. :D
     
  21. Putting it simply: both instanced and static ways are valid and have different advantages and disadvantages.

    And in my opinion, you should use whatever you think is required for the long run, always think ahead for your project.
     
Thread Status:
Not open for further replies.

Share This Page