1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Question Best way to deal with methods that can throw NullPointers

Discussion in 'Developer Support' started by theSmeg, Aug 6, 2019.

  1. theSmeg

    Joined:
    Jun 25, 2019
    Messages:
    24
    Likes Received:
    5
    So I'm finding that with a lot of my code it will work 98% of the time and then after an hour or two it will throw a NullPointers exception. Even if I do a Null check beforehand eg:

    Code (Text):
    1.      
    2. LocatableEntityQueryResults<Npc> nearestNpc = Npcs.newQuery().names("Some Npc").results().sortByDistance();
    3. try {
    4.     for (Npc npc : nearestNpc) {
    5.         if (npc.getTarget() != null) {
    6.             if (npc.getTarget().equals(Players.getLocal())) {
    7.                 if (Players.getLocal().getTarget() != null && Players.getLocal().getTarget().equals(npc)) {
    8.                     break;
    9.                 } else {
    10.                     npc.interact("Attack");
    11.                     break;
    12.                 }
    13.             }
    14.         } else if (Players.getLocal().getTarget() == null) {
    15.             getLogger().info("Attacking npc");
    16.             if (npc.getAnimationId() != 1190 && npc.getAnimationId() != 1184 && npc.getAnimationId() != 1186) {
    17.                 npc.interact("Attack");
    18.                 break;
    19.             }
    20.         }
    21.     }
    22. } catch (NullPointerException e) {
    23.     getLogger().warn("Threw null pointer trying to attack");
    24. }
    25.  
    So in this snippet there is the odd occassion where the npc is not null and then maybe it gets killed by another player and throws an exception when i try to interact with that npc. Another example is if im looting and the item isn't null when i search the area for it and then when i go to click(); it someone has already picked it up and a NullPointer has been thrown.

    Other than using a try catch statement, is there any other good pattern that I could used in any bit of code that might throw a NullPointer?
     
    #1 theSmeg, Aug 6, 2019
    Last edited: Aug 8, 2019
  2. Taarun

    Joined:
    Aug 11, 2018
    Messages:
    4
    Likes Received:
    1
    IntelliJ automatically offers this:

    Screenshot (91).png

    Maybe it can help.
     
  3. Makutu

    Makutu The Omen

    Joined:
    Dec 27, 2018
    Messages:
    159
    Likes Received:
    132
    First things first, please can things before you go into a long-winded nested-if block of code. Store your local player, nullcheck it, then carry on if its not null. The reason you're getting nullpointers in your code if because every time you call something like `Players.getLocal` or `npc.getTarget()` it's re-querying for that player or target which may be null at that time.

    Secondly, for (almost) every entity there's a query builder. GameObjects, Npcs, Interfaces, etc. Make use of those as they have builders that will help you massively reduce your lines of code and increase readability. For example your code could be reduced to 1 line in the form of
    `Npc target = Npcs.newQuery().targeting(Players.getLocal()).results().nearest();`

    You can even query for the person targetting a specific Npc by doing `Player player = Players.newQuery().targeting(npc).results().first();`. All your answers are in the jdocs at Generated Documentation (Untitled)
     
    Aidden likes this.
  4. theSmeg

    Joined:
    Jun 25, 2019
    Messages:
    24
    Likes Received:
    5
    Cheers for the advice. I've updated my original code to be more clear as I think it caused some confsuion which you have shown me in your response(Npc query filter).

    I have tried assigning the npc to a variable and the code still throws null pointer exceptions. This is because it doesn't matter if you store it in a variable becuase when the .click(); method is called the object it's referencing(dead npc or looted item) doesn't exist.

    This code is an attacking method, the reason I don't store things in a variable is becuase I wan't everything checked and calculated in real time, hence why I make the method call again and not reference something older stored in a variable.

    Hopefully this clears things up, it still doesn't help me find a common patteren used by bot authors here to deal with code that can throw null pointers other than using a try catch
     
  5. Makutu

    Makutu The Omen

    Joined:
    Dec 27, 2018
    Messages:
    159
    Likes Received:
    132
    You have still done it wrong. Call ".first()" on your query results to get the npc that's targetting you. You're also probably getting nullpointers on your Players.getLocal() stuff. Call it once at the start of your method, cache it in a variable, then use that variable for references later in the method.
     
  6. theSmeg

    Joined:
    Jun 25, 2019
    Messages:
    24
    Likes Received:
    5
    Sigh I still don't think you are properly understanding me.

    How does calling .first(); change the fact that the object im trying to interact with might still be null(dead npc, item that has been looted by someone else) and throw a Null Pointers exception? Using .first() also wouldn't be good as I want to grab all the npc's in the area and filter them. I can't do this with the query builder filters so I run them through a few if statements. I have included all my code above so hopefully it makes it more clear what im doing and why im doing it.

    Also calling Players.gerLocal() should never return null if the player is logged in, so it shouldn't throw a Null pointer exception and storing this in a variable wouldn't change that.
     
  7. Makutu

    Makutu The Omen

    Joined:
    Dec 27, 2018
    Messages:
    159
    Likes Received:
    132
    Players.getLocal() can occasionally return null, that's why it's marked as nullable and requires appropriate null-checking.

    Try this, this filters Npcs being targeted by you or no one else.
    Code (Text):
    1. Player local = Players.getLocal();
    2. if (local != null) {
    3.     Npc target = Npcs.newQuery().names("Some npc").targetedBy(local, null).results().sortByDistance().first();
    4.     if (target != null) {
    5.         target.interact("Attack");
    6.     }
    7. }
     
  8. theSmeg

    Joined:
    Jun 25, 2019
    Messages:
    24
    Likes Received:
    5
    Yup so I had something like that originally. It didn't work as well becuase the npcs im fighting are agressive. So i do a few checks to see which Npcs around me are trying to fight me and find which one is closest and attack that one, if none are found then just attack the closest.
     
  9. Derk

    Derk 12 year old normie

    Joined:
    Jan 8, 2015
    Messages:
    2,766
    Likes Received:
    1,339
    Use hella kotlin
     
    Makutu and Fabreze like this.

Share This Page

Loading...