I can't figure out how to fix my null pointer. My holder (Holder Pattern class) is undefined - I'm not sure how to fix it. I am still pretty new to programming. Thanks for any ideas on how to go about fixing this!
public Goose (JPanel container, GooseBehavior behavior, BehaviorHolder holder) {
super(container);
_holder = holder;
double rnd = Math.random(); //local variable to create random angle
//System.out.println(rnd);
this.setRotation(rnd);//sets the rotation angle to a random angle
this.setSize(25, 20); //sets size
this.setFillColor(java.awt.Color.RED); //sets color
this.setWrapping(true); //sets wrapping to true
_gooseBehavior = behavior; //stores _gooseehavior
_gooseBehavior = _holder.getBehavior();
}
public void react() {
_gooseBehavior.stop(); //tells the current _gooseBehavior to stop
_holder.getBehavior(); //gets the stored behavior from the holder
_gooseBehavior = _holder.getBehavior(); //sets the new value to one stored in holder
_gooseBehavior.setTarget(this); //sets the target on goose
_gooseBehavior.start(); //starts the behavior
}
Stacktrace:
Exception in thread "main" java.lang.NullPointerException
at Animal.Goose.<init>(Bee.java:26)
at Animal.DrawingPanel.<init>(DrawingPanel.java:30)
at Animal.ControlPanel.<init>(ControlPanel.java:27)
at Animal.App.<init>(App.java:28)
at Animal.App.main(App.java:39)
Here's the code where I instantiate BehaviorHolder in my Control Panel (top level object), and then I just have it stored in my drawingPanel, Goose class, and BehaviorButtons so that its associated with the three.
public ControlPanel() {
super();
this.setLayout(new BorderLayout());//sets a new BorderLayout
_drawingPanel = new DrawingPanel(_holder);
_moveRandomly = new MoveBehavior();
_doNothing = new StopBehavior();
_kingGoose = new FollowBehavior(_kingGoose);
_holder = new BehaviorHolder(_moveBehavior);
Its hard to say without a stack trace and incomplete code example, but there's multiple potential problems with your code:
public Goose (JPanel container, GooseBehavior behavior, BehaviorHolder holder) {
super(container);
// removed some code for clarity
_gooseBehavior = behavior; // <<- You store behaviour here
_gooseBehavior = _holder.getBehavior(); // <<- then immediately override it
}
public void react() {
_gooseBehavior.stop();
_holder.getBehavior(); // <-- this isn't getting assigned to anything
_gooseBehavior = _holder.getBehavior(); // A duplicate assignment, previously done in constructor. Are you changing holder's behaviour outside of the display class?
_gooseBehavior.setTarget(this); //sets the target on goose
_gooseBehavior.start(); //starts the behavior
}
I would guess _gooseBehaviour
is null, but you can help us answer your question if you include the full stack trace (The error that was printed out that let you know you had a null pointer exception).
EDIT
Based off your NPE I'll bet dollar's to donuts that your holder is getting passed into the constructor as a null. Inspect it's value in your debugger or print out its value to verify.
It can help to explicitly validate the constructor/method parameters, and throw a more informative exception if there's something wrong:
if (behavior == null)
throw new NullPointerException("behavior is null");
if (holder == null)
throw new NullPointerException("holder is null");
That way:
NullPointerException
without any added info you know immediately that the problem isn't a null parameter. Then you can add further validation of the parameters once you know they aren't null
:
if (holder.getBehavior() == null)
throw new IllegalArgumentException("holder's behavior is null");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.