views:

225

answers:

9

I have a class User that contains attributes: nickname, ipAddress, sharedFolder. The idea is to have a user with these attributes and a list of files from a shared folder.

This is my code:

import java.io.*;
import java.util.*;

public class User {

    String nickname;
    String ipAddress;
    static ArrayList<String> listOfFiles;
    File sharedFolder;
    String fileLocation;

    public User(String nickname, String ipAddress, String fileLocation) {

        this.nickname = nickname.toLowerCase();
        this.ipAddress = ipAddress;
        sharedFolder = new File(fileLocation);

        File[] files = sharedFolder.listFiles();
        listOfFiles = new ArrayList<String>();

        for (int i = 0; i < files.length; i++) {
            listOfFiles.add(i, files[i].toString().substring(fileLocation.length()));
        }
    }

    public static void showTheList() {
        for (int i = 0; i < listOfFiles.size(); i++) {
            System.out.println(listOfFiles.get(i).toString());
        }
    }

    @Override
    public String toString() {
        return nickname + " " + ipAddress;
    }

    public static void main(String[] args) {
        showTheList();
    }
}

However, when I run it I can't get the list of files. It throws an exception:

Exception in thread "main" java.lang.NullPointerException at User.showTheList(User.java:35) at User.main(User.java:52) Java Result: 1

I know it's probably a tiny little mistake but I can't seem to fix it :( Please help.

+1  A: 

Try this:

public static void main(String[] args) {
    new User(..., ..., ...);
    showTheList();

}

You haven't put any value to the showList, that's why you get NullPointerException. BTW, we usually call it just NPE.

nanda
I tried that in the other class that calls for User and creates a new one, but it still won't work
AmateurProgrammer
+5  A: 

listOfFiles being a static field should be initialized in a static block, not constructor.

i.e.

static{
    listOfFiles = new ArrayList<String>();
}

or you can also initialize it at the site of declaration itself.

i.e.

static ArrayList<String> listOfFiles = new ArrayList<String>();

In your code, you are not creating any object of the class and hence listOfFiles reference is never assigned an ArrayList instance. That's the reason you're getting a NullPointerException.

missingfaktor
Thanks! It was so obvious :(I gotta take a nap seriously. 13 hours of programming straight is not okay
AmateurProgrammer
+3  A: 

You need to initialize listOfFiles

static ArrayList<String> listOfFiles = new ArrayList<String>();
YuppieNetworking
+2  A: 

NullPointerException is the most common exception in Java. You should learn to cope with it by yourself.

It occurs when:

  • Calling the instance method of a null object.
  • Accessing or modifying the field of a null object.
  • Taking the length of null as if it were an array.
  • Accessing or modifying the slots of null as if it were an array.
  • Throwing null as if it were a Throwable value.

  • (not included in the docs) Unboxing a null Number.

Bozho
* Unboxing a null Number/Boolean.
BalusC
yup. this is unluckily not included in the docs
Bozho
-1 This is not really an answer to the question.
nfechner
tehcnically, it is - it says why is he getting the NPE. And is definitely more helpful than just pointing how to fix it. Should he be asking a question for each NPE in his programming practice?
Bozho
Thanks a lot for this, this kind of help is highly appreciated
AmateurProgrammer
+1  A: 

Looks like listOfFiles has not been initialized. You have to either create a new User first, or initialize and fill it in a static method

Silvio Donnini
+5  A: 

your "showTheList" function is assuming that listOfFiles is already populated. However, that variable is not created until you run the User constructor.

As a point of practice, it's not a good idea to initialize a static variable inside an instance constructor. If you do it that way, it's not clear who the data belongs to. In this case since listOfFiles is dependant on the state of the User instance, it shouldn't be static, and your call would look more like

 User u = new User(..., ..., ...);
 u.showTheList(); 
Steve B.
Thank you, it was also very helpful
AmateurProgrammer
+1  A: 

I suppose, you are running the main method in this class. In that case, you're missing a call to your constructor.

nfechner
A: 

I completely agree with GreyMatter 9.0's answer, but since I couldn't comment on that I have to ask; why is this field static?

From your description and simply looking at the class I can see no reason why you would want this field to be static. When constructing multiple Users (assuming you correctly remove and instantiate the List) the listOfFiles field would contain the files of every instance of that class. Wouldn't you prefer to only access the files belong to that specific User?

Alasdair
I'm not exactly sure. The Idea for entire file sharing application is this one (as far as file lists handling goes):User asks for a specific file and gets a list of users that have that particular file in their respective shared folders.
AmateurProgrammer
+1  A: 

I would rewrite the entire class like this (Code Complete - Chapter 7):

import java.io.File;
import java.util.ArrayList;

public class User {

private String nickname;
private String ipAddress;
private String sharedFolder;

public User(String nickname, String ipAddress, String sharedFolder) {
    //TODO do some params check
    this.nickname = nickname.toLowerCase();
    this.ipAddress = ipAddress;
    this.sharedFolder = sharedFolder;
}

public void showFiles() {
    ArrayList<String> listOfFiles = this.retrieveFileNames();
    for (String fileName : listOfFiles) {
        System.out.println(fileName);
    }
}

private ArrayList<String> retrieveFileNames() {
    File folder = new File(this.sharedFolder);
    File[] files = folder.listFiles();
    ArrayList<String> listOfFiles = extractFileName(files);
    return listOfFiles;
}

private ArrayList<String> extractFileName(File[] files) {
    ArrayList<String> listOfFiles = new ArrayList<String>();
    for (int i = 0; i < files.length; i++) {
        listOfFiles.add(i, files[i].getPath().substring(
                sharedFolder.length() + 1));
    }
    return listOfFiles;
}

public String toString() {
    return nickname + " " + ipAddress;
}

public static void main(String[] args) {
    User user = new User("tom", "127.0.0.1", "/tmp");
    user.showFiles();
}
}
rodrigoap
Thank you SOOO much, I'll give it a try and pick up a few hints :)
AmateurProgrammer
This is great. I tested it and it works fine :)You're the man. Thank you
AmateurProgrammer