[Beginner] Constructors [WIP]

Discussion in 'Plugin Development' started by theguynextdoor, Sep 14, 2012.

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

    theguynextdoor

    It is episode 17 in thenewboston's tutorial series, but i shall be explaining them in my words here.

    Why would i need a constructor?
    Well in terms of plugins, they are used most commonly for getting methods and values from another class. A very common use in bukkit plugins, and a big cause for error in new developers plugins is getting the config in their listener. They try just putting the getConfig() in their listener and it doesn't work. I've even seen people make their listener extend JavaPlugin (That is wrong wrong sprinkled with extra wrong).

    Constructors can also be used so you can set unassigned values in a class through the use of the constructor. (I shall explain in just a moment after i have gone through getting methods and values)

    Using a constructor in plain java example
    Note: If you have an empty constructor, it is the same as not having one at all. Let me demonstrate.

    Code:
    public class Human {
       
        public Human() {
     
        }
     
    }
    
    Is the same as
    Code:
    public class Human {
       
    }
    
    So now lets say that this human had a name, and we made a method to get that name, and we wanted to simply print that out in the console. Our code would look something like this.

    Human class:
    Code:
    public class Human {
     
        public String getName() {
            return "Geoffry";
        }
    }
    So we have our human class, and our human has a most excellent name, how do we get that name when we are in our main class?

    Well:
    Code:
    public class Main {
     
        public static void main(String[] args) {
            Human human = new Human();
            System.out.println(human.getName());
        }
     
    }
    Let me explain that
    Code:
     Human human = new Human();
    This created a new human object, and because we did not have a constructor defined, we could just leave it blank (the () after new Human).

    And
    Code:
    System.out.println(human.getName());
    This just printed out his name to the console. The reason it did that is because the method getName() in our human class returned a string which was his name, and we simply put that in a System.out.println();

    Great, that is a constructor in basic java use. But now let me show you where you can use it in a bukkit plugin


    Using a constructor in a bukkit plugin
    Let's make a basic class, with a lovely configuration file set up
    Code:
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class Main extends JavaPlugin {
     
        @Override
        public void onEnable() {
            FileConfiguration config = getConfig();
     
            config.addDefault("Test.String", "Testing your test");
     
            config.options().copyDefaults(true);
            saveConfig();
        }
     
    }
    
    So now lets say we have a listener.





    TO BE CONTINUED (I'm off to bed)
     
    Juubes, Doamax and Neodork like this.
  2. Offline

    Acrobot

    adnotation to "Note: If you have an empty constructor, it is the same as not having one at all."

    It's not necessarily true.
    If you don't have any constructors, by default it is created like:

    Code:java
    1.  
    2. public XX() { super(); }
    3.  


    Empty constructor wouldn't call super().
    Also, that's not always the constructor you need.

    For example, for utility classes (that hold only static methods) some coding standards tell you that you should use private constructors:
    http://www.javapractices.com/topic/TopicAction.do?Id=40


    However, it seems like a good tutorial - keep up the good work :)
     
  3. Offline

    theguynextdoor

    I shall include this when i get time to finish this off. Thanks for mentioning that. I wouldn't want to spread false information

    I was going to go into the private constructors but i went to bed :p
     
    Acrobot likes this.
  4. Offline

    Neodork

    Alright so I tried this:

    Code:java
    1. public class Quest {
    2.  
    3. public static Questermain plugin;
    4.  
    5. String questName;
    6. String questType;
    7.  
    8. public Quest(String questname){
    9. questName=questname;
    10. questType=plugin.quest.getString("quest."+questname+".type");
    11. }
    12.  
    13. }


    Code:java
    1. public void rewardPlayer(Player player, String questname) {
    2. Quest rewardingQuest = new Quest(questname);
    3. }


    It error's on the line where questType gets initialized, any ideas? Questermain is the main class in a different package (I did the imports).
     
  5. Offline

    theguynextdoor

    Have you tried restarting your IDE. If you use eclipse you could also try cleaning the workspace by clicking the Project tab (at the top of the window), then 'clean'


    If it still persists then can you show a bit more of the error?, like what it actually says
     
  6. Offline

    Neodork

    Code:
     at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:332)
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:477)
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:459)
    at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:830)
    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:807)
    at net.minecraft.server.Packet3Chat.handle(Packet3Chat.java:44)
    at net.minecraft.server.NetworkManager.i(NetworkManager.java:211)
    at net.minecraft.server.NetworkManager.c(NetworkManager.java:326)
    at net.minecraft.server.NetworkReaderThread.run(SourceFile:93)
    Caused by: java.lang.NullPointerException
    at me.neodork.api.Quest.<init>(Quest.java:24)
    at me.neodork.rpg.Questcompleter.rewardPlayer(Questcompleter.java:260)
    at me.neodork.rpg.playerCommandListener.npcTalkerCommandChain(playerCommandListener.java:1283)
    at me.neodork.rpg.playerCommandListener.onPlayerChat(playerCommandListener.java:75)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:330)
    ... 9 more
    Well I restarted and recompiled still giving me this error..
     
  7. Offline

    theguynextdoor

    Your problem is:

    You use your plugin variable in your constructor in the Quest class, but you never assign the plugin variable to anything, so it is null which is giving you your NPE
     
    Neodork likes this.
  8. Offline

    Neodork

    You might have an easy way to assign plugin variable (a)? The class is from a different package. It's my main class.

    I tried some of the what seemed logical to me things but they didn't work ^^.
     
  9. Offline

    theguynextdoor

    Code:
    public class Quest {
     
        public Questermain plugin;
        private String questName
     
        public Quest(Questermain instance, String questName) {
        plugin = instance;
        this.questName = questName;
        }
     
    }
    Then your reward method would look like

    Code:
    public void rewardPlayer (Player player, String quest, Questermain instance) {
        Quest quest = new Quest (instance, quest);
    }
    But it depends where your method actually is depends if you need the Questermain variable in that method. Because if it is in your main class, then you wont need it, and can simply use 'this' when defining the new quest
     
  10. Offline

    Neodork

    Yea, I was kind of hoping there was a way without having to add the Questermain instance to the contructor but this will do ^^.
     
  11. Offline

    theguynextdoor

    There is one other way.
    https://github.com/theguynextdoor/T...scommunity/tribesnextdoor/TribesNextDoor.java

    You basically make a static instance of you plugin in your main class, so in your case you would do
    Code:
    private static Questermain plugin
    Then in your onEnable you would do
    Code:
    public void onEnable() {
        plugin = this;
    }
    Then also in your main class you would make a method so you can get this variable

    Code:
    public static Questermain getInstance() {
        if (plugin == null) plugin = new Questermain();
        return plugin;
    }
    So to get your main class you would do

    Code:
    Questermain.getInstance();
    I'm not 100% on this, but i believe you should also set plugin to null in your onEnable to prevent memory leaks i think it is, but i can't confirm that, so dont quote me on it :p
     
  12. Offline

    Neodork

    Mhhh guess I'll have to put that to the test. Sounds interesting though... If it worked without having memory leaks I'll post it here.
     
Thread Status:
Not open for further replies.

Share This Page