NullPointerException error in java

4

I have a class of type User that has as attribute a vector of Sensors , and class Sensors has as attribute a vector of Data . After creating five User objects and saving them to a txt file, I populated 3 Sensor objects of a certain User and tried to save them to the same txt file, but this error gives NullPointerException .

public class test 
{ 
    public static void main ( String args[] ) throws IOException
    {
        Users[] users = new Users[5];
        File file = new File("C:\Users\Daniel\Documents\poo.txt");
        int id=0, goal, id2=0, consumo, n=0, i, j, k, novogoal, idedit, iddelete, iduser;
        boolean type, status;
        String name, password, c, name2, description, novoname, novopassword;
        float cost, novocost;

        for (i=0; i<5; i++)
        {
            users[i] = new Users(i, "", "", 0, 0);
            for (j=0; j<50; j++)
            {
                users[i].sensors[j] = new Sensors(j, "", "", false);
                for (k=0; k<100; k++)
                {
                    DateTime time = new DateTime("2004-12-13T21:39:45.618-08:00");
                    users[i].sensors[j].data[k] = new Data(false, 0, time);
                }    
            }
        }

        FUsers fusers = new FUsers();
        FSensors fsensors = new FSensors();
        FData fdata = new FData();

        //criar e salvar usuário
        for (i=0; i<5; i++)
        {
            c = JOptionPane.showInputDialog("Tipo de usuário: 1 - ADMIN | 0 - COMUM");
            type = Boolean.parseBoolean(c);
            name = JOptionPane.showInputDialog("Digite seu nome");
            password = JOptionPane.showInputDialog("Digite a senha");
            c = JOptionPane.showInputDialog ("Custo do kWh");
            cost = Float.parseFloat(c);
            goal = Integer.parseInt(JOptionPane.showInputDialog("Meta de consumo"));
            users[i] = fusers.createUser(i, name, password, cost, goal, type);
        }
        fusers.saveUser (file, users);
        //*/

        /*criando um sensor*/
        iduser = Integer.parseInt(JOptionPane.showInputDialog("Id do user que terá o sensor"));
        for (i=0; i<3; i++)
        {
            name2 = JOptionPane.showInputDialog ("Aparelho ligado ao sensor");
            description = JOptionPane.showInputDialog ("Localização do aparelho");
            c = JOptionPane.showInputDialog ("O aparelho está ligado?");
            status = Boolean.parseBoolean(c);
            consumo = Integer.parseInt(JOptionPane.showInputDialog("Consumo do aparelho"));
            users[iduser].sensors[i] = fsensors.createSensor(i, name2, description, status);
        }
        fsensors.saveSensor(file, users); /*erro aqui*/
    }
}
public class FSensors {

    public Sensors createSensor(int id, String name, String description, boolean status)
    {
        Users user = new Users();
        user.sensors[id]= new Sensors(id, name, description, status);
        return user.sensors[id];
    }

    /**
     *
     * @param file
     * @param users
     * @param sensor
     * @throws IOException
     */
    public void saveSensor(File file, Users[] user) throws IOException
    {
        int i, j;
        String id, status;
        for (i=0; i<5; i++)
        {
            for (j=0; j<50; j++)
            {
                try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)))
                { 
                    id = Integer.toString(user[i].sensors[j].getId()); /*erro aqui*/
                    status = Boolean.toString(user[i].sensors[j].getStatus());
                    bw.write(id);
                    bw.newLine();
                    bw.write(user[i].sensors[j].getNome());
                    bw.newLine();
                    bw.write(user[i].sensors[j].getDescription());
                    bw.newLine();
                    bw.write(status);
                    bw.newLine();
                    bw.close();
                }  
            }
        }
    }
public class FUsers {

    public Users createUser(int id, String name, String password, float cost, int goal, boolean type)
    {
        if (type)
        {
            AdminUser admin = new AdminUser();
            admin.setId(id);
            admin.setName(name);
            admin.setPassword(password);
            admin.setCost(cost);
            admin.setGoal(goal);
            admin.setType(type);
            return admin;
        }
        else
        {
            CommonUser common = new CommonUser();
            common.setId(id);
            common.setName(name);
            common.setPassword(password);
            common.setCost(cost);
            common.setGoal(goal);
            common.setType(type);
            return common;
        } 
    }

    public void saveUser (File file, Users[] user) throws IOException
    {
        int i;
        String id, cost, goal, type;
        for (i=0; i<5; i++)
        {
            if (i==0)
            {
                try (BufferedWriter bw = new BufferedWriter(new FileWriter(file)))
                {
                    id = Integer.toString(user[i].getId()); 
                    cost = Float.toString(user[i].getCost());
                    goal = Integer.toString(user[i].getGoal());
                    type = Boolean.toString(user[i].getType());
                    bw.write(id);
                    bw.newLine();
                    bw.write(user[i].getName());
                    bw.newLine();
                    bw.write(user[i].getPassword());
                    bw.newLine();
                    bw.write(cost);
                    bw.newLine();
                    bw.write(goal);
                    bw.newLine();
                    bw.write(type);
                    bw.newLine(); 
                    bw.close();
                }
            }
            else
            {
                try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)))
                {
                    id = Integer.toString(user[i].getId()); 
                    cost = Float.toString(user[i].getCost());
                    goal = Integer.toString(user[i].getGoal());
                    type = Boolean.toString(user[i].getType());
                    bw.write(id);
                    bw.newLine();
                    bw.write(user[i].getName());
                    bw.newLine();
                    bw.write(user[i].getPassword());
                    bw.newLine();
                    bw.write(cost);
                    bw.newLine();
                    bw.write(goal);
                    bw.newLine();
                    bw.write(type);
                    bw.newLine(); 
                    bw.close();
                }
            }
        }
    }
public Users (int id, String name, String password, float cost, int goal)
{
    this.id = id;
    this.name = name;
    this.password = password;
    this.cost = cost;
    this.goal = goal;
}
public Sensors (int id, String name, String description, boolean status)
{
    this.name = name;
    this.description = description;
    this.status = status;
}

If anyone can help, I'm grateful!

    
asked by anonymous 21.07.2015 / 01:02

1 answer

5

This code is suspect:

    public Sensors createSensor(int id, String name, String description, boolean status)
    {
        Users user = new Users();
        user.sensors[id]= new Sensors(id, name, description, status);
        return user.sensors[id];
    }

Note that the Users object created does not survive the method call. This code is equivalent to this other code:

    public Sensors createSensor(int id, String name, String description, boolean status)
    {
        return new Sensors(id, name, description, status);
    }

Let's simplify your saveUser method to avoid copying and pasting so much:

    public void saveUser (File file, Users[] user) throws IOException
    {
        for (int i = 0; i < 5; i++)
        {
            try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, i != 0)))
            {
                String id = Integer.toString(user[i].getId()); 
                String cost = Float.toString(user[i].getCost());
                String goal = Integer.toString(user[i].getGoal());
                String type = Boolean.toString(user[i].getType());
                bw.write(id);
                bw.newLine();
                bw.write(user[i].getName());
                bw.newLine();
                bw.write(user[i].getPassword());
                bw.newLine();
                bw.write(cost);
                bw.newLine();
                bw.write(goal);
                bw.newLine();
                bw.write(type);
                bw.newLine(); 
                bw.close();
            }
        }
    }

Let's do the same with createUser :

    public Users createUser(int id, String name, String password, float cost, int goal, boolean type)
    {
        Users user = type ? new AdminUser() : new CommonUser();
        user.setId(id);
        user.setName(name);
        user.setPassword(password);
        user.setCost(cost);
        user.setGoal(goal);
        user.setType(type);
        return user;
    }

Another problem:

        try (BufferedWriter bw = ...)
        { 
            // Várias linhas de código...
            bw.close();
        }

You're already using try-with-resources so you do not have to worry about closing BufferedWriter , but you still close it anyway. Remove these bw.close(); .

Finally, look at this from here, with the comments I've added:

Users[] users = new Users[5]; // Cria um array com 5 users.
// ...
for (i=0; i<5; i++) // Este for preenche o array "users"
{
    users[i] = new Users(i, "", "", 0, 0); // Coloca 5 users no array.
    for (j=0; j<50; j++) // Este for preenche o array "sensors".
    {
        users[i].sensors[j] = new Sensors(j, "", "", false); // Coloca um sensor no array.
        // ...
    }
}

// Chegando aqui, o array está todo preenchido com usuários,
// e cada usuário todo preenchido com sensors.
// MAS SERÁ QUE ISSO SERÁ ASSIM PARA SEMPRE?

for (i=0; i<5; i++)
{
    // ...

    // Surpresa! Sobrescreve um user que estava no array com um outro
    // que tem todos os sensors definidos como null!
    users[i] = fusers.createUser(i, name, password, cost, goal, type);
}

// Chegando aqui, o array foi todo sobreescrito com novos usuários,
// e todos estes novos usuários têm um array cheio de nulls como sensors!

// ...

iduser = Integer.parseInt(JOptionPane.showInputDialog("Id do user que terá o sensor")); // Escolhe apenas um usuário.
for (i=0; i<3; i++) // Preenche 3 sensors no array de 50 sensors apenas deste usuário.
{
    // ...
    users[iduser].sensors[i] = fsensors.createSensor(i, name2, description, status);
}

// Agora, apenas um usuário têm um array com 3 sensores preenchidos e 47 nulls!
// Os demais, têm 50 nulls!

fsensors.saveSensor(file, users); /*erro aqui*/

And then:

    public void saveSensor(File file, Users[] user) throws IOException
    {
        int i, j;
        String id, status;
        for (i=0; i<5; i++)
        {
            // Um user tem 3 sensors e 47 nulls!
            // Todos os outros têm 50 sensors nulls!
            for (j=0; j<50; j++)
            {
                try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)))
                {
                    // A maioria dos elementos do array é null.
                    // Ao chamar getId() no null, temos um NullPointerException!
                    id = Integer.toString(user[i].sensors[j].getId());
                    // ...
                }
           }
       }
   }

That is, you may have to change your for (i=0; i<3; i++) to for (i=0; i<50; i++) . Or maybe check on for if user[i].sensors[j] is null . Or not overwrite the users of the array initially created.

I recommend using lists instead of arrays. Arrays have fixed sizes, which seems to be just messing you up, whereas lists can have a variable size that you'll rarely have to worry about knowing what they are, as well as being much easier to create and use .

    
21.07.2015 / 01:47