1

I've been kicking this code around for a while and I think I know what the general problem is, I can't figure out how to correct it. I'm getting the following error:

C:\Documents and Settings\Joe King\My Documents\418.85A Java\Project5>javac Project5.java
Project5.java:408: error: variable boatNames might not have been initialized
            boatArray1 = new Boat[boatNames.length];
                                  ^
1 error

The problem is my boatNames array is in a try/catch block and I think this is isolating it from the rest of the code. How can I get the boatNames array out of the try/catch block?

My code is as follows:

class Project5{

public static void main(String[] args){

    String[] boatNames;
    Boat[] boatArray1;
    Boat[] boatArray2;
    String result = " "; 
    String name = null;
    char firstChar;
    char firstLetter;
    char secondLetter;
    int totalRead;
    int i;
    int j;
    int k;
    int l;
    int m;

    Path inPath = Paths.get("C:/Documents and Settings/Joe King/My Documents/418.85A Java/Projects/Input").resolve("Boat Names.txt");

    if(!Files.exists(inPath)){

        System.out.println(inPath + " does not exist.  Terminating the program.");
        System.exit(1);

    }

    try(BufferedReader fileIn = Files.newBufferedReader(inPath, Charset.forName("UTF-16"))){

        totalRead = 0;

        while(fileIn.readLine() != null){

            name = fileIn.readLine();
            ++totalRead;
            name = null;

        }

        boatNames = new String[totalRead];

        for(i = 0 ; i < boatNames.length ; ++i){

            name = fileIn.readLine();
            boatNames[i] = name;
            name = null;

        }

    }catch(IOException e){

        System.err.println("Error writing file: " + inPath);
        e.printStackTrace();

    }   

    Path outPath = Paths.get("C:/Documents and Settings/Joe King/My Documents/418.85A Java/Projects/Output").resolve("Fleet Registry.txt");

    try{

        Files.createDirectories(outPath.getParent());

    }catch(IOException e){

        System.err.println("Error creating directory: " + outPath.getParent());
        e.printStackTrace();
        System.exit(1);

    }

    boatArray1 = new Boat[boatNames.length];

    if(boatNames.length > 0){

        try(BufferedWriter fileOut = Files.newBufferedWriter(outPath, Charset.forName("UTF-16"))){

            for(j = 0 ; j < boatNames.length ; j++){

                String delimiters = "[. ,]";
                int limit = -1;

                String[]tokens = boatNames[j].split(delimiters, limit);

                for(k = 0 ; k < tokens.length ; ++k){

                    firstChar = tokens[k].charAt(0);
                    firstChar = Character.toUpperCase(firstChar);
                    char[] tokenArray = tokens[k].toCharArray();                            
                    String text = new String(tokenArray, 1, (tokenArray.length - 1) );                          
                    tokens[k] = firstChar + text;                   
                    result = result + tokens[k] + " ";

                    if(k != tokens.length - 1){

                        continue;

                    }else{

                        result = result.trim();
                        boatNames[k] = result;
                        result = " ";

                    }
                }       

                firstLetter = boatNames[j].charAt(0);

                if((firstLetter == 'B') || (firstLetter == 'C') || (firstLetter == 'N')){

                    boatArray1[j] = new RaceBoat();


                }else{

                    boatArray1[j] = new SailBoat();

                }

                boatArray1[j].christenBoat(boatNames[j]);               

            }

            System.out.println("\n");

            for(l = 0 ; l < boatNames.length ; ++l){            

                secondLetter = Character.toUpperCase(boatNames[l].charAt(1));

                if((secondLetter == 'A') || (secondLetter == 'E')){

                    if(l > 0){

                        fileOut.newLine();
                    }                       
                    fileOut.write(boatArray1[l].goFast());

                }else{

                    if(l > 0){

                        fileOut.newLine();
                    }               
                    fileOut.write(boatArray1[l].goSlow());

                }           

                fileOut.newLine();
                fileOut.write(boatArray1[l].launchBoat());
                fileOut.newLine();
                fileOut.write(boatArray1[l].whatIsBoatState());
                fileOut.newLine();

            }

            boatArray2 = new Boat[3];

            boatArray2[0] = new SailBoat();
            boatArray2[1] = new RaceBoat("Endurance", true);
            boatArray2[2] = new RaceBoat(false);

            for(m = 0 ; m < boatArray2.length ; ++m){

                fileOut.newLine();
                fileOut.write(boatArray2[m].toString());
                fileOut.newLine();
                fileOut.write(boatArray2[m].launchBoat());
                fileOut.newLine();
                fileOut.write(boatArray2[m].whatIsBoatState());
                fileOut.newLine();

            }

            fileOut.newLine();
            fileOut.write("There are " + Boat.boatCount + " boats in the fleet this morning.");


        }catch(IOException e){

        System.err.println("Error writing outPath: " + outPath);
        e.printStackTrace();

        }

    }else{

        System.out.println("\n\n\nArgh!... you forgot to enter ship names scalawag!" +
            "\n\n\n\tPlease try again!");

    }

    System.out.println("\nThe Fleet Registry is completed, press ENTER to continue.\n");

    try{

        System.in.read();

    } catch(IOException e){

        return;
    }
}
}

Thank you everyone, I've entered the following:

    if(boatNames != null){

        boatArray1 = new Boat[boatNames.length];

        if(boatNames.length > 0){

            try(BufferedWriter fileOut = Files.newBufferedWriter(outPath, Charset.forName("UTF-16"))){

                for(j = 0 ; j < boatNames.length ; j++){

                    String delimiters = "[. ,]";
                    int limit = -1;

                    String[]tokens = boatNames[j].split(delimiters, limit);

                    for(k = 0 ; k < tokens.length ; ++k){

                        firstChar = tokens[k].charAt(0);
                        firstChar = Character.toUpperCase(firstChar);
                        char[] tokenArray = tokens[k].toCharArray();                            
                        String text = new String(tokenArray, 1, (tokenArray.length - 1) );                          
                        tokens[k] = firstChar + text;                   
                        result = result + tokens[k] + " ";

                        if(k != tokens.length - 1){

                            continue;

                        }else{

                            result = result.trim();
                            boatNames[k] = result;
                            result = " ";

                        }
                    }       

                    firstLetter = boatNames[j].charAt(0);

                    if((firstLetter == 'B') || (firstLetter == 'C') || (firstLetter == 'N')){

                        boatArray1[j] = new RaceBoat();


                    }else{

                        boatArray1[j] = new SailBoat();

                    }

                    boatArray1[j].christenBoat(boatNames[j]);               

                }

                System.out.println("\n");

                for(l = 0 ; l < boatNames.length ; ++l){            

                    secondLetter = Character.toUpperCase(boatNames[l].charAt(1));

                    if((secondLetter == 'A') || (secondLetter == 'E')){

                        if(l > 0){

                            fileOut.newLine();
                        }

                        fileOut.write(boatArray1[l].goFast());

                    }else{

                        if(l > 0){

                            fileOut.newLine();
                        }

                        fileOut.write(boatArray1[l].goSlow());

                    }           

                    fileOut.newLine();
                    fileOut.write(boatArray1[l].launchBoat());
                    fileOut.newLine();
                    fileOut.write(boatArray1[l].whatIsBoatState());
                    fileOut.newLine();

                }

                boatArray2 = new Boat[3];

                boatArray2[0] = new SailBoat();
                boatArray2[1] = new RaceBoat("Endurance", true);
                boatArray2[2] = new RaceBoat(false);

                for(m = 0 ; m < boatArray2.length ; ++m){

                    fileOut.newLine();
                    fileOut.write(boatArray2[m].toString());
                    fileOut.newLine();
                    fileOut.write(boatArray2[m].launchBoat());
                    fileOut.newLine();
                    fileOut.write(boatArray2[m].whatIsBoatState());
                    fileOut.newLine();

                }

                fileOut.newLine();
                fileOut.write("There are " + Boat.boatCount + " boats in the fleet this morning.");


            }catch(IOException e){

            System.err.println("Error writing outPath: " + outPath);
            e.printStackTrace();

            }

        }else{

            System.out.println("\n\n\nArgh!... you forgot to enter ship names scalawag!" +
                "\n\n\n\tPlease try again!");

        }

        System.out.println("\nThe Fleet Registry is completed, press ENTER to continue.\n");

        try{

            System.in.read();

        } catch(IOException e){

            return;
        }
    }

Now I'm getting the following error:

C:\Documents and Settings\Joe King\My Documents\418.85A Java\Project5>java Project5
Exception in thread "main" java.lang.NullPointerException
       at Project5.main(Project5.java:424)

This doesn't make sense to me, in order to get to line 424 the boatNames array cannot be null because the length of boatNames was used several times before line 424. What am I missing?

Thanks

4

4 回答 4

9

The variable is out of the try/catch, otherwise the compile error would be different. The problem is that the initialization is inside the try block, so that code after the try can't be sure the variable was initialized.

There are two ways to deal with this:

  1. Initialize the variable when you declare it. Just using this would be enough:

    String[] boatNames = null;

  2. Move all the code that uses the variable inside the try block. This is often a good strategy, but only if your methods are small. In your case, I wouldn't recommend this, as your method is much too long. Now, if you could break your code up into shorter methods, then limiting the scope of the variable to a single try block would make good sense.

于 2012-06-11T04:18:05.083 回答
4

Before the try/catch block, initialize the array like this:

String[] boatNames = null;
于 2012-06-11T04:19:53.063 回答
4

You have declared your array outside try block

String[] boatNames;

It will be initialized under first try block

boatNames = new String[totalRead];

Issue is here boatArray1 = new Boat[boatNames.length];

Reason, your compiler has no way to know if boatNames initialization will be successful as there might be an exception and initialization will fail.

As part of your declaration you can do this:

String[] boatNames = null; // This will fix your immediate problem 

but doing this may lead you to NullPointerException since your File read can fail.

To solve this do a null check on your array before you use it.

if(boatNames == null){
   // I am not going to go further or will take corrective measures here
} 
于 2012-06-11T04:20:19.303 回答
0

boatNames此处的编译器考虑了在初始化之前可能在 try 块中引发异常的可能性,因此它会给出编译器错误might not have been initialized实力在这里很重要!

这里理想的解决方案是调整您的代码结构并放置

boatArray1 = new Boat[boatNames.length];

在同一个尝试块中!

于 2012-06-11T04:26:30.787 回答