Java Help - My head exploding

Darzil

Developer
Trying to get my head around this. As part of trying to expand maximize to handle Crown of Thrones (and later Buddy Bjorn) I'm trying to make an array list of all familiars which will improve on the best previous headgear in the Crown of Thrones. I'll then iterate over it in MaximiserSpeculation in the Hat section.

However, I'm currently getting a weird null pointer exception at the marked line ****. Given that I've already checked that familiar isn't null, why am I getting a null pointer exception trying to do this.enthronedFamiliars.add( familiar ) ?

Probably obvious, but I can't see it !

Code:
In public class Evaluator:

	private ArrayList<FamiliarData> enthronedFamiliars;


In Evaluator.enumerateEquipment:

				if ( item.getItemId() == ItemPool.HATSEAT )
				{
					Boolean useHat = false;
					double bestScore = 0;
					FamiliarData bestFamiliar = FamiliarData.NO_FAMILIAR;
					// Check each familiar in hat to see if they are worthwhile
					List familiarList = KoLCharacter.getFamiliarList();
					String[] familiars = new String[ familiarList.size() ];
					for ( int f = 0; f < familiarList.size(); ++f )
					{
						FamiliarData familiar = (FamiliarData) familiarList.get( f );
						KoLmafia.updateDisplay( "Familiar: " + familiar.getName() );
						if ( familiar != null && familiar != FamiliarData.NO_FAMILIAR && familiar.enthroneable() &&
							!familiar.equals( KoLCharacter.getFamiliar() ) && !this.enthronedFamiliars.contains( familiar ) )
						{
							spec.setEnthroned( familiar );
							double score = spec.getScore();
							if ( score > this.maxUseful( slot ) )
							{
								this.enthronedFamiliars.add( familiar ); **** null pointer exception ****
								if ( score > bestScore )
								{
									useHat = true;
									bestScore = score;
									bestFamiliar = familiar;
								}
							}
						}
					}
					if ( useHat == false )
					{
						continue;
					}
					spec.setEnthroned( bestFamiliar );
					spec.getScore();
					spec.failed = false;
 
Odds are you're not initializing enthronedFamiliars. Remember, in Java the default value for an object is null.

edit: wait, no, that'd throw an error a few lines earlier. Not sure. Maybe you're setting enthronedFamiliars to null in one of the function calls you do? (setEnthroned, perhaps?)
 
Last edited:
I'd also look at the initialization of enthronedFamiliars. There are enough conditionals that I'm not sure I agree with the esteemed (hee)^3 that an initialization error would have occurred sooner.
 
The only thing I can think of is that something's happening in the spec.setEnthroned. Try walking through that whole block with a debugger, maybe?
 
Thanks folks, will take a look tomorrow when back at my dev environment.

I think I might be able to get Crown of Thrones (and then Buddy Bjorn) working with Maximizer, which should then hopefully make Softcore easier (as I'm never remembering to swap Crown familiars). Fingers crossed.
 
I'd also look at the initialization of enthronedFamiliars. There are enough conditionals that I'm not sure I agree with the esteemed (hee)^3 that an initialization error would have occurred sooner.

The line in question is encapsulated by
Code:
if ( familiar != null && familiar != FamiliarData.NO_FAMILIAR && familiar.enthroneable() &&
							!familiar.equals( KoLCharacter.getFamiliar() ) && !this.enthronedFamiliars.contains( familiar ) )
						{
The last of these invokes a method of this.enthronedFamiliars. Since the conditions are all chained together via &&, no short-circuiting can have happened, since we managed to get inside the clause.
 
Given that I've already checked that familiar isn't null

*And* you called familiar.getName() one line before you checked it ;)
(BTW, adding a null to an ArrayList shouldn't throw an NPE, I think, anyway ...)

I still want to see how enthronedFamiliars is initialized.
And I wouldn't put it past java to throw NPE at certain line when the actual problem is inside optimized native code somewhere deep inside. Maybe something lets .contains() work but not .add()?
(I also wouldn't be too surprised if the exception's line number was wrong)

Put it in debug mode, put in print calls for everything everywhere, doublecheck all variables after every line of execution ...
 
My guess is that
Code:
private ArrayList<FamiliarData> enthronedFamiliars;
needs to be
Code:
private ArrayList<FamiliarData> enthronedFamiliars = new ArrayList<FamiliarData>();
 
It was indeed initialization of enthronedFamiliars. I'd copied the initialization of familiars to do it, but failed up update both mentions of familiars.
 
Back
Top