I defined a class with public attributes.
However, when initializing the values in the constructor, I get a NullPointerException.
Here is my code:
class CacheBlock
{
public byte[] data;
public int frame;
public boolean ref;
}
public class Cache
{
private CacheBlock[] blocks;
public Cache(int blockSize, int cacheBlocks)
{
blocks = new CacheBlock[10];
blocks[0].data = new byte[blockSize]; //line that causes exception
}
}
This is the issue:
blocks = new CacheBlock[10];
Here the block array has been initialized but there is no CacheBlock object at index 0 therefore when it accessed in the next line, there is a NPE.
You would need to create CacheBlock instances and add it to the block array.
For instance:
blocks[0] = new CacheBlock();
and so on.
blocks = new CacheBlock[10];
This line, you only allocate the memory, but not initialize it.
You should add
blocks[0]=new CacheBlock();
above the suspect line.
Related
I am once again asking for technical support.
I need to define a custom type inside a class, I've done it like this:
public class MainClass {
private class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024]
System.out.println(this.CustomType[0].varB);
}
}
When I run it throws a NullPointerException at System.out.println(this.CustomType[0].varB);
I've tested if myArray gets properly initialized with 1024 elements and it does, however I can't seem to access them.
I just moved from C++ to Java so I'm still getting used to it, am I missing something blatant?.
You only create an array without any objects, so this.CustomType[0] is null.
You should add the objects to the array:
public MainClass() {
myArray = new CustomType[1024]
for (int i =0; i<myArray.length;i++ {
myArray[i] = new CustomType();
}
System.out.println(this.myArray[0].varB);
}
Also you should make the member of CustomType private and access it via getter and setter.
Two things,
You must instantiate CustomType.
CustomType does not need access to MainClass.this so you can make it static.
So
public class MainClass {
private static class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024];
for (int i = 0; i < myArray.length; ++i) {
this.CustomType[i] = new CustomType();
}
// Or
Arrays.setAll(myArray, CustomType::new);
System.out.println(this.CustomType[0].varB);
}
}
Not making it static stores a MainClass.this in every CustomType instance which is unnecessary overhead.
Arrays in java are objects. The following line of the code you posted creates an array of 1024 elements where each and every element is null.
myArray = new CustomType[1024];
If you want to place actual objects in the array, named myArray, you need to create instances of class CustomType and assign them to elements of the array, for example:
CustomType instance = new CustomType();
myArray[0] = instance;
Then you can execute the following line of code and it will not throw NullPointerException.
System.out.println(myArray[0].varB);
Here is the full code to get the value of varB. In which you can avoid declaring CustomType[] myArray
public class Test
{
private static class CustomType
{
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
public static void main(String... args)
{
System.out.println(new CustomType().varB);
}
}
The solution is to add some elements to that array. See the below steps for more information.
constructor will be invoked, when you create the object of that class
And then you created an empty array of CustomType with size 1024 and trying to access the first element which does not exist(default is null) and trying to perform operations on that null reference. So you are getting the NullPointerException.
In a Android application I am making I have an array of instances of a certain class I made, and later in the program I need to use the getter and setter methods from that class on an instance of the class from the array. Do I need to assign the instance of the class from the array to a new class initializer? Here is some code to clear this up:
Class
public class ProfileInformation {
private String console;
private String gamertag;
public String getConsole() {
return console;
}
public void setConsole(String console) {
this.console = console;
}
public String getGamertag() {
return gamertag;
}
public void setGamertag(String gamertag) {
this.gamertag = gamertag;
}
}
Array
ArrayList<ProfileInformation> ProfTags = new ArrayList<>();
Some instances of ProfileInformation are then added to arraylist, and then I get one of the instances from the arraylist and try to use getGamertag() to set it to a string:
ProfileInformation profNew = ProfTags.get(ProfTags.size()-1);
String example = profNew.getGamertag();
The problem is example will equal null. Why is this?
First, an Arraylist is a List, try not to confuse that with actual arrays.
Do I need to assign the instance of the class from the array to a new class initializer?
You don't need to get an element out of the Arraylist, no. You can chain many methods together
String example = ProfTags.get(ProfTags.size()-1).getGamertag();
example will equal null. Why is this?
For the same reason any object is null... You never set it equal to anything else
This code runs on my laptop:
public static void main(String[] args) {
ArrayList<ProfileInformation> ProfTags = new ArrayList<>();
element = new ProfileInformation();
element.setGamertag("Actual Gamer tag value");
ProfTags.add(element);
ProfileInformation profNew = ProfTags.get(ProfTags.size()-1);
String example = profNew.getGamertag();
}
Output is:
Actual Gamer tag value
I guess you didn't call setGamertag(String).
I have already done research on this question, and also tried to figure it out by myself but no luck. So I decided to ask it.
Basic info:
There are two classes. FBClient, and State. In FBClient, I have a static variable of it's type, fbc, a StateManager instance, which just has some methods to work with State stuff, some constants and two getters. In State, I am trying to initialize a BufferedImage.
public class FBClient
{
//Static
public static FBClient fbc;
//In init method
private StateManager stateManager;
//Constants
private final int INIT_FRAME_WIDTH = 320, INIT_FRAME_HEIGHT = (INIT_FRAME_WIDTH / 4) * 3, SCALE = 3, FRAME_WIDTH = INIT_FRAME_WIDTH * SCALE, FRAME_HEIGHT = INIT_FRAME_HEIGHT * SCALE;
public static void main(String[] args)
{
try
{
//First call in exception chain:
fbc = new FBClient();
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
private FBClient()
throws IOException
{
//Second call in exception chain:
init();
}
private void init()
throws IOException
{
stateManager = new StateManager();
//Third call in exception chain:
stateManager.addState(new MainMenu((byte) 0, "Main Menu")); //MainMenu is the subclass of State, and the constructor just calls "super(0, "Main Menu")"
}
public int getFRAME_HEIGHT()
{
return FRAME_HEIGHT;
}
public int getFRAME_WIDTH()
{
return FRAME_WIDTH;
}
}
public abstract class State
{
protected final byte ID;
protected final String NAME;
protected final BufferedImage SCREEN;
protected final Graphics2D GRAPHICS;
public State(byte id, String name)
{
this.ID = id;
this.NAME = name;
//Exception cause:
this.SCREEN = new BufferedImage(FBClient.fbc.getFRAME_WIDTH(), FBClient.fbc.getFRAME_HEIGHT(), BufferedImage.TYPE_INT_RGB);
this.GRAPHICS = SCREEN.createGraphics();
}
}
More info:
If I put literals in BufferedImage initialization it works.
If I initialize two variables in the State class, assigning them literals and putting those variables in initialization, it works.
If instead of assigning literals to those variables I assign them FBClient.fbc.getFRAME_WIDTH() and FBClient.fbc.getFRAME_HEIGHT(), it throws a NullPointerException.
If I make a System.out.println(getFRAME_WIDTH + " : " + getFRAME_HEIGHT) in FBClient class, it prints out properly, but if I do it in State class (and off course adding FBClient.fbc. before it), it throws a NullPointerException.
If I make FRAME_WIDTH and FRAME_HEIGHT constants public, and I try to access them from State
class by doing FBClient.fbc.FRAME_WIDTH and FRAME_HEIGHT, it throws a NullPointerException.
If I try to access the constants from FBClient class directly, instead of getters, it still prints out properly.
Finally
Thank you for taking your time, and if you need more information to work with, ask me in the comments and I'll provide it. Also, I apologise if the question is not constructed well/not explained well. If that's the case, tell me how can I improve it. And also, I apologise if this question was asked and answered once already, I may have missed it, but as I said, I did my research.
Edit #1
A comment suggested I print out a fbc value, to see if it's null.
So I added this line of code to the State constructor:
if(FBClient.fbc != null) System.out.println("Not null"); else System.out.println("Null");
And, as suspected, it printed out null. Why is that? I clearly initialized the variable in the main method...
You are referring to FBClient.fbc before it is assigned (actually in the constructor since fbc get assigned after the constructor finished working). To fix it add static to the final values, make the getter static and acess it with FBClient.getFRAME_HEIGHT(). You don't need non-static final variables.
The reason you are having a problem is because you are trying to reference FBClient.fbc within its constructor call and the object hasn't finished its own construction. It's not immediately obvious you're doing this but if you follow the code within the constructor you are calling init() which ultimately calls to a State constructor, which in turn tries to use FBClient.fbc.getFRAME_WIDTH().
I suggest you don't call init() within the FBClient constructor and change your main method code to:
public static void main(String[] args)
{
try
{
//First call in exception chain:
fbc = new FBClient();
fbc.init();
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
Hope this helps.
I think your FBClient.fbc is null.
I do not have much to ask really. Heck I don't even know what the question should say. Basically, this Java code works fine without any compilation errors.
public class Application {
static String[][] tiles;
public Application() {
tiles = new String[9][9];
}
public static void main(String[] args) {
Application app = new Application();
Grid mines = new Grid();
mines.fillTiles(tiles, 9, 9, 10);
}
}
class Grid {
Random rand;
public void fillTiles(String[][] tiles, int rowSize, int colSize,
int numMines) {
rand = new Random();
int rowIndex;
int columnIndex;
while (numMines > 0) {
rowIndex = rand.nextInt(rowSize);
columnIndex = rand.nextInt(colSize);
tiles[rowIndex][columnIndex] = "M";
numMines--;
}
}
}
But, when I remove the line
Application app = new Application();
from the main method in the first class, it is throwing a NullPointerException at
tiles[rowIndex][columnIndex] = new String("M");
Any reason why?
Application app = new Application();
If you don't instantiate Application, tiles will be pointing to null. Operation on null reference results in NullPointerException.
Your Array initialization logic is in constructor.
public Application() {
tiles = new String[9][9];
}
Constructor will be executed only on Object creation (new Application())
If you don't want to do Application app = new Application();
Just change static String[][] tiles=new String[9][9];
Defining static array variable doesn't mean that instantiation will happen on load. It just means that that variable is class variable.
You notice that you have instantiated your array in your constructor?
static String[][] tiles;
public Application() {
tiles = new String[9][9]; <--- Here
}
So, if you don't instantiate your Application using new Application(), your array would not be initialized, and your reference will be pointing to null.
Also, it is not a good idea to initialize your static variables in constructor. Ideally, you should initialize your static array in a static initializer block or at the place of declaration itself: -
static {
tiles = new String[9][9];
}
or
static String[][] tiles = new String[9][9];
If you initialize your array in your constructor, it will be re-initialized for every instance, every time you create one. As static variables are common to all the instances. So, the change you make to your static variable, will be reflected in all your instances.
I think I might know the reason why:
public class Application {
static String[][] tiles;
public Application() {
tiles = new String[9][9];
}
public static void main(String[] args) {
Application app = new Application();
Grid mines = new Grid();
mines.fillTiles(tiles, 9, 9, 10);
}
}
In this you have a static 2d array that holds strings called tiles. However, you only initialize it in the constructor of Application. Thus when calling "mines.fillTiles(tiles", tiles is still null and
tiles[rowIndex][columnIndex] = new String("M");
will throw a NullPointerException.
Because you are initializing tiles = new String[9][9]; in your constructor. You constructor is only called when you use new to create the object instance as new Application().
If you don't want to use the constructor, declare your static variable with initialization as:
static String[][] tiles = new String[9][9];
That should work fine without constructor call.
You are initializing the array in the constructor of an instance. If you create another instance after the first, it will re-initialize the static member.
I'm having a problem where I receive this error:
Exception in thread "main" java.lang.NullPointerException
at com.noxia.Main.startCombat(Main.java:101)
at com.noxia.Area1.createArea1Enemy(Area1.java:43)
at com.noxia.Main.main(Main.java:30)
I know that I need to initialize the variables because they are null, but I can't seem to figure out what I need to put where. I've minimized the code to show just the relevant parts as there are many other variables and methods left out, but this seems to pertain to the issue. Any help would be greatly appreciated =)
public class Main {
Player p;
Enemy e;
Area1 a1;
public static void main(String[] args) {
Main main = new Main();
main.a1 = new Area1();
main.p = new Player(100);
//the line directly below this is line 30 where the error occurs
main.a1.createArea1Enemy(10);
}
public void startCombat()
{
//the line directly below this is line 101 where the error occurs
while (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
{
p.playerAttack();
if (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
{
e.enemyAttack();
}
}
}
public class Player extends Main {
private int currentLife;
public int getCurrentLife()
{
return currentLife;
}
public void setCurrentLife(int cl)
{
currentLife = cl;
}
public Player(int cl)
{
currentLife = cl;
}
public class Enemy extends Main {
private int life;
public int getLife()
{
return life;
}
public void setLife(int lf)
{
life = lf;
}
public Enemy (inf lf)
{
life = lf;
}
public class Area1 extends Main {
public void createArea1Enemy(int enemyCounter)
{
while (enemyCounter > 0)
{
String[] enemyList = {"Enemy1", "Enemy2"} //code for Enemy2 left out below
int enemyListLength = enemyList.length;
int randomEnemy = (int) (Math.random() * enemyListLength);
if (enemyList[randomEnemy].equals("Enemy1"))
{
Enemy enemy1 = new Enemy("Enemy1", 100);
//the line directly below this is line 43 where the error occurs
startCombat();
}
enemyCounter--;
}
}
}
The simple answer is that you have to set e to an enemy before calling startCombat.
But a better way to do this would be to remove e, and pass the enemy object to startCombat using a method parameter. The e field is conceptually wrong. To understand the wrongness, try to come up with a coherent explanation of what it means in terms of the state of a Main object.
Clearly this is beginner code ... and there are a number of bad things about what you have written:
The fields of a class should be for object state, not for passing parameter values to methods.
You should avoid writing code that accesses the innards of a class ... like your main method does.
Best practice is to make fields private, and defined getter and / or setter methods (as required) for external classes to access / modify them.
You need to learn how to write constructors with parameters.
You need to design your code properly. Everything extending Main means that there is going to be no rational model of what the objects "mean". And there's the problem that each instance of Enemy and Area1 will have their own copies of the p, e, and a1 fields, and a whole bunch of inappropriate methods.
The main problem is that you never initialize Enemy e;. You create an enemy but never assign it to this.e.
Change this line:
Enemy enemy1 = new Enemy("Enemy1", 100);
To this:
this.e = new Enemy("Enemy1", 100);
There are also many other problems with your code.
Learn how to write a constructor properly. This code is wrong.
I see no reason at all why a Play, Area1, and Enemy should extend Main.