Java performing instance commands before static ones [closed] - java

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I ran into this problem, when an object uses a classes static instance, before it's even created. Example:
class Chair {
public static Chair mychair = new Chair();
public void foo() {}
}
class Table {
public Table() {
Chair.mychair.foo();
}
}
So if I call the mychair.foo() , I get a NullPointerException. I know, not even static things get performed until the class is really needed. But how can I force Java to actually load the class, so it will be created?
Stacktrace of original program:
Exception in thread "main" java.lang.ExceptionInInitializerError
at hu.intelligames.game.level.Level.<init>(Level.java:34)
at hu.intelligames.game.Game.initialize(Game.java:64)
at hu.intelligames.game.Game.<init>(Game.java:43)
at hu.intelligames.game.Game.main(Game.java:80)
Caused by: java.lang.NullPointerException
at hu.intelligames.game.level.tiles.Tile.<clinit>(Tile.java:25)
... 4 more
Constructor of Level class (from line 25):
public Level(int width, int height) {
this.width = width;
this.height = height;
tiles = new Tile[width * height];
for (int i = 0; i < tiles.length; i++) {
if (i % 3 == 0)
tiles[i] = Tile.GRASS;
else if (i % 3 == 1)
tiles[i] = Tile.GRASS;
else
tiles[i] = Tile.STONE;
}
init();
}
Whole code for Tile class:
public class Tile {
public static Spritesheet tileSheet = new Spritesheet("/tiles.png");
public static final Tile VOID = new Tile(0, 0, tileSheet, 0x00000000);
public static final Tile GRASS = new Tile(1, 0, tileSheet, 0xff00ff00);
public static final Tile STONE = new Tile(2, 0, tileSheet, 0xffaaaaaa);
public static final Tile ROAD = new Tile(3, 0, tileSheet, 0xffabcdef);
private Spritesheet sheet;
private int x;
private int y;
private int colorCode;
private static ArrayList<Tile> tileList;
static {
tileList.add(VOID);
tileList.add(GRASS);
tileList.add(STONE);
tileList.add(ROAD);
}
public Tile(int x, int y, Spritesheet sheet, int colorCode) {
this.sheet = sheet;
this.x = x;
this.y = y;
this.colorCode = colorCode;
}
public void render(int xPos, int yPos, int xOff, int yOff, Screen screen) {
screen.render(xPos, yPos, xOff, yOff, x, y, sheet);
}
public int getColorCode() {
return colorCode;
}
public static Tile getTileByColorCode(int code) {
for (Tile t : tileList) {
if (t.getColorCode() == code) return t;
break;
}
return VOID;
}
}

private static ArrayList<Tile> tileList;
Remains null
static {
tileList = new ArrayList<>();
tileList.add(VOID);
tileList.add(GRASS);
tileList.add(STONE);
tileList.add(ROAD);
}

Your field tileList is not initialized, so the static initialization code throws NPE.
This should do the trick:
private static ArrayList<Tile> tileList = new ArrayList<>();

Related

Why is my method populating my array with null? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed yesterday.
Improve this question
I need to create a program to display the content of an array of tables, each table with width and height.
public class Table {
private static int width;
private static int height=20;
private static final Table[] tables = new Table[10];
public Table(int width, int height) {
this.width=width;
this.height=height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public static Table[] getTables() {
return tables;
}
public static int tableWidth(){
int widthMin=50;
int widthMax=200;
width= widthMin+ (int) (Math.random()*(widthMax-widthMin));
return width;
}
public static Table fillArray(){
int i;
for (i=0; i<tables.length-1;i++){
tables[i]=new Table(tableWidth(),height);
}
return tables[i];
}
#Override
public String toString() {
return tables + "";
}
}
public class Main {
public static void main(String[] args) {
for (int i=0;i<Table.getTables().length;i++){
System.out.println(Table.fillArray());
}
}
}
Why isn't the method filling the array, but its presenting null in all positions?

Adding objects to an array list - "Cannot invoke xxx.add because yyy is null" [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
I have a class of objects:
public class SubObjects {
int depth;
public SubObjects(int d) {
this.depth = d;
}
}
And then another class of objects:
import java.util.ArrayList;
public class Objects {
private int height;
private int width;
ArrayList<SubObjects> liste;
public Objects(int h, int w) {
this.height = h;
this.width = w;
}
}
The idea here is that each object should be able to hold a height value, a width value and a list of SubObjects.
E.g. = 2,4,[SubObject1, SubObject2]
The following being the main class:
import java.util.*;
public class Tryout {
public static void main(String[] args) {
SubObjects S1 = new SubObjects(7);
SubObjects S2 = new SubObjects(9);
Objects O1 = new Objects(2,4);
O1.liste.add(S1);
O1.liste.add(S2);
System.out.println(O1);
}
}
First I create two SubObjects.
Then I create an Object with the ints 2 and 4.
Where everything goes astray is the next line:
O1.liste.add(S1);
The error code given:
Cannot invoke "java.util.ArrayList.add(Object)" because "O1.liste" is null
Now I get that the array list is null, I have not added anything yet of course, but why can't I add anything to it?
liste is not initilized. In other words, it isn't an ArrayList - it's a null reference. Since there's no object there, you can't call any methods on it.
To solve the issue, you could initialize liste in the constructor:
public Objects(int h, int w) {
this.height = h;
this.width = w;
this.liste = new ArrayList<>();
}
liste was never initialized. Either initialize as below or in the constructor.
public class Objects {
private int height;
private int width;
ArrayList<SubObjects> liste = new ArrayList<>(); // <===add this
public Objects(int h, int w) {
this.height = h;
this.width = w;
}
}

Unable to add to object ArrayList from other class [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I got a concurrent modification exception from adding an element to an ArrayList located in another class. (GUI program)
Exception in thread "Thread-0" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:937)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:891)
at sentinel/entity.EntityManager.tick(EntityManager.java:35)
at sentinel/worlds.World.tick(World.java:80)
at sentinel/state.GameState.tick(GameState.java:25)
at sentinel/game.Game.tick(Game.java:72)
at sentinel/game.Game.run(Game.java:115)
at java.base/java.lang.Thread.run(Thread.java:844)
I tried to include an iterator because I googled how to resolve the ConcurrentModificationException. However, it did not help or maybe I am using it wrong.
This is the class that I am adding the element to the ArrayList.
public class SentryHive extends StaticEntity{
private long lastSpawnTimer, spawnCooldown = 1000, spawnTimer = spawnCooldown;
private Random r = new Random();
public SentryHive(Handler handler, double x, double y) {
super(handler, x, y, tiles.Tiles.TILEWIDTH*3, tiles.Tiles.TILEHEIGHT*3);
bounds.x = 32*3;
bounds.y = 64*4 - 80;
bounds.width = 50;
bounds.height = 32;
}
#Override
public void tick() {
SpawnSentry();
}
public void SpawnSentry() {
spawnCooldown = r.nextInt(100) * 1000;
spawnTimer += System.currentTimeMillis() - lastSpawnTimer;
lastSpawnTimer = System.currentTimeMillis();
//Iterator<Entity> it = handler.getWorld().getEntityManager().getEntities().iterator();
//while (it.hasNext()) {
if(spawnTimer >= spawnCooldown) {
handler.getWorld().getEntityManager().addEntity(new Sentry(handler, 1080, 910, 10, 10));
}
// }
spawnTimer = 0;
}
this is the part of my program where I added other entities (if you need):
public class World {
private int width, height;
private int[][] tiles;
private int[][] entities;
private int spawnx, spawny;
private Handler handler;
private EntityManager entityManager;
private State state;
private ItemManager itemManager;
public int requiredSentry = 0;
private Random r = new Random();
//fun: ALT command R to change all of the same word in a file
public World(Handler handler, String path, String topper) {
this.handler = handler;
entityManager = new EntityManager(handler, new Player(handler, 600, 600));
itemManager = new ItemManager(handler);
entityManager.addEntity(new SentryHive(handler, 980, 810));
loadWorld(path);
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
int temp = r.nextInt(1000);
if(temp >=1 && temp <= 10) {
entityManager.addEntity(new DyingTree(handler, i*64, j*64));
} else if(temp >= 11 && temp <= 15) {
entityManager.addEntity(new Sentry(handler, i*64, j*64, 10, 10));
} else if(temp >= 21 && temp <= 25) {
entityManager.addEntity(new Beetle(handler, i*64, j*64, 40, 40));
} else if(temp == 30) {
entityManager.addEntity(new BeetleRed(handler, i*64, j*64, 40, 40));
}
}
}
entityManager.getPlayer().setX(spawnx * Tiles.TILEWIDTH);
entityManager.getPlayer().setY(spawny * Tiles.TILEHEIGHT);
}
below is my entity manager class (if you need):
public class EntityManager {
private Handler handler;
private Player player;
private ArrayList<Entity> entities;
private Comparator<Entity> renderSorter = new Comparator<Entity>() {
#Override
public int compare(Entity a, Entity b) {
if(a.getY() + a.getHeight() < b.getY() + b.getHeight())
return -1;
return 1;
}
};
public EntityManager(Handler handler, Player player) {
this.handler = handler;
this.player = player;
entities = new ArrayList<Entity>();
addEntity(player);
}
public void tick() {
Iterator<Entity> it = entities.iterator();
while(it.hasNext()) {
Entity e = it.next();
e.tick();
if(!e.isActive())
it.remove();
}
entities.sort(renderSorter);
}
public void addEntity(Entity e) {
entities.add(e);
}
I think there might be an initialization or declaration error somewhere, I just want the list to add the entity and resolve the error because my render method can draw everything in the ArrayList to the screen.
Your list is used by multiple thread and at same time if one thread try to read and another try to write then this Exception will Occur, to avoid this you can used CopyOnWriteArrayList list .
Example:
CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
Write data using this is more costlier , so read all pros and cons of this api.

How to make a singleton reinitialize variables?

My singleton class:
public class XandY {
private double x, y;
private static XandY xy;
//Constructor sets an x and y location
private XandY() {
x = 210.0;
y = 100.0;
}
public static XandY getXandY() {
if (xy == null)
xy = new XandY();
return xy;
}
public void updateXandY() {
x += 10;
y += 5;
}
}
Other class that changes singleton values and tries to reinitialize. My question is if I call changeXandY a few times then want to call resetXandY how do I make it reset back to the original x and y?
public class GameWorld {
private List<GameObject> objects;
public void initialize() {
objects = new ArrayList<GameObject>();
objects.add(XandY.getXandY());
...add other objects that are not singletons
}
public void changeXandY {
for (int i=0; i<gameObject.size(); i++) {
if (gameObject.get(i) instanceof XandY)
((XandY)gameObject.get(i)).updateXandY();
}
public void resetXandY {
initialize();
}
}
For this use case, you could simply store them as default values. Such as
private double x, y;
private static XandY xy;
private static final double default_x = 210.0;
private static final double default_y = 100.0;
That way when you reset, just:
public void resetXandY {
this.x = default_x;
this.y = default_y;
}
That being said, you may want to change your default constructor to look the same way.
If you can make the XandY reference protected, you can use a static initializer in an anonymous subclass:
// I need to reset the singleton!
new XandY(){
{ xy = null; }
};
But really, if you need to be able to (re)initialize the singleton, you should put a method to that effect into its signature. Obscure solutions are, at best, still obscure...
Create a resetXandY() method to set default value:
public class XandY {
private double x, y;
private static XandY xy;
//Constructor sets an x and y location
private XandY() {
x = 210.0;
y = 100.0;
}
//reset x=0 and y=0
public void resetXandY() {
x = 0;
y = 0;
}
public static XandY getXandY() {
if (xy == null)
xy = new XandY();
return xy;
}
public void updateXandY() {
x += 10;
y += 5;
}
}

Java Object Array Initialization

I am working on a java project which contains 3 classes and an object array in one of the classes. This project is ultimately supposed to move 4 entity objects around on a board by using the coordinates of the entity objects. These entity objects are stored in an array in the world class. My problem is with the array initialization in the world class. I am not sure how to set each element of the array equal to an object from the entity class and then access that object's coordinates to move it around on the board. The coordinates for the entity objects are initially set at 20x30 in a default constructor. Here is my code:
public class entity {
private int xcoordinate;
private int ycoordinate;
private String name;
private char symbol;
public entity(){
xcoordinate = 20;
ycoordinate = 30;
}
private entity(int newxcoor, int newycoor, String newname, char newsymbol){
xcoordinate = newxcoor;
ycoordinate = newycoor;
name = newname;
symbol = newsymbol;
}
public int getXCoor(){
return xcoordinate;
}
public int getYCoor(){
return ycoordinate;
}
}
public class world {
private entity[] ObArray = new entity[4];
public world(){
world test = new world();
}
public void draw(){
for (int i = 0; i < 4; i++)
{
//int x = ObArray[i].getXLoc();
//int y = ObArray[i].getYLoc();
}
}
}
public class mainclass {
public static void main(String[] args){
world worldob = new world();
//entity a = new entity();
//entity b = new entity();
//entity c = new entity();
//entity d = new entity();
worldob.draw();
}
}
My draw function and main function are not finished. After the array is initialized I will be able to finish the draw method using the entity get functions.
Thanks for your help.
That is one way of doing it. You can also define all of your entities inline like this:
private entity[] ObArray = {
new entity(0,0,"Entity1",'a'),
new entity(10,10,"Entity2",'b'),
new entity(20,20,"Entity3",'c'),
new entity(30,30,"Entity4",'d')
};
A better way may be to do an ArrayList instead of an array:
private List<entity> ObArray = new ArrayList<>();
ObArray.add(new entity(0,0,"Entity1",'a');
ObArray.add(new entity(10,10,"Entity2",'b');
ObArray.add(new entity(20,20,"Entity3",'c');
ObArray.add(new entity(30,30,"Entity4",'d');
To access each element you just need to get the element from the array and either get or set the properties you need:
ObArray[0].getXCoor();
ObArray[0].setXCoor(5);
Your problem is only creating new object of world inside world's constructor which throws stack overflow error, otherwise it is fine:
public world(){ world test = new world(); //REMOVE THIS LINE
}
You simply need to initialise the array. This can be done in the world constructor.
public world()
{
for (int i = 0; i < 4; i++)
{
ObArray[i] = new entity();
}
}
Then you can access the objects in your draw method, as you've shown:
public void draw()
{
for (int i = 0; i < 4; i++)
{
int x = ObArray[i].getXCoor();
int y = ObArray[i].getYCoor();
System.out.println("x" + x);
System.out.println("y" + y);
// Manipulate items in the array
// ObArray[i].setXCoor(10);
}
}
A more complete example, with the move functions added, and the class names capitalised:
public class Entity
{
private int xcoordinate;
private int ycoordinate;
private String name;
private char symbol;
public Entity()
{
xcoordinate = 20;
ycoordinate = 30;
}
private Entity(int newxcoor, int newycoor, String newname, char newsymbol)
{
xcoordinate = newxcoor;
ycoordinate = newycoor;
name = newname;
symbol = newsymbol;
}
public int getXCoor()
{
return xcoordinate;
}
public void setXCoor(int xcoordinate)
{
this.xcoordinate = xcoordinate;
}
public int getYCoor()
{
return ycoordinate;
}
public void setYcoor(int ycoordinate)
{
this.ycoordinate = ycoordinate;
}
public static void main(String[] args)
{
World worldob = new World();
worldob.draw();
worldob.move(0, 15, 30);
worldob.move(1, 45, 0);
worldob.move(2, 23, 27);
worldob.move(3, 72, 80);
worldob.draw();
}
}
class World
{
private final Entity[] ObArray;
public World()
{
this.ObArray = new Entity[4];
for (int i = 0; i < ObArray.length; i++)
{
ObArray[i] = new Entity();
}
}
public void move(int index, int xCoor, int yCoor)
{
if (index >= 0 && index < ObArray.length)
{
Entity e = ObArray[index];
e.setXCoor(xCoor);
e.setYcoor(yCoor);
}
}
public void draw()
{
for (Entity e : ObArray)
{
int x = e.getXCoor();
int y = e.getYCoor();
System.out.println("x" + x);
System.out.println("y" + y);
}
}
}

Categories

Resources