0

Apologies for the long code I'm about to include. What I'm trying to do is save certain validated, user input variables to an object. I believe my issue is due to the variables scope, that's why I'm having the error customerAccount may not have been initialized.

If anybody could point me in the right direction, it'd be greatly appreciated.

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

public class ATM {
    public void run() {

        // USED FOR DEBUGGING PURPOSES. SET TO TRUE TO ENABLE DEBUGGING MODE
        boolean debug = false, mainCheck = false, check = false;
        Scanner input = new Scanner(System.in);
        Scanner fInput = null;
        int idNumber = 0;
        String lastName, firstName, emailAddress, phoneNumber;
        double startingBalance;
        Client customerAccount;

        File file = new File("accountData.txt");
        if(!file.exists()) {
            System.out.println("File does not exist within directory. Creating file now.");
            PrintWriter output = null;
            try {
                output = new PrintWriter(file);
            }
            catch(IOException e) {
                System.out.println("Something went wrong during file creation.");
            }
            finally {
                if (output != null)
                    output.close();
            }
        }

        ArrayList<Client> clientArr = new ArrayList<Client>();

        try {
            fInput = new Scanner(new File("accountData.txt"));
        }
        catch(Exception e) {
            System.out.println("ERROR: File Not Found.");
            e.printStackTrace();
        }
        while(fInput.hasNext()) {
            try{
                int tempID = fInput.nextInt();
                String tempFName = fInput.next();
                String tempLName = fInput.next();
                String tempPNumber = fInput.next();
                String tempEmail = fInput.next();
                double tempBalance = fInput.nextFloat();
                Client tempClient = new Client(tempID, tempFName, tempLName, tempPNumber, tempEmail, tempBalance);
                tempClient.getAccount().setID(tempID);
                clientArr.add(tempClient);

            if(debug == true)
                System.out.println(tempID+" "+tempFName+" "+tempLName+" "+tempPNumber+" "+tempEmail+" $"+tempBalance);
            }
            catch(NoSuchElementException e) {
                System.out.println("ERROR: Missing a required data field.");
            }
        }

        if(debug == true)
            System.out.println(clientArr.size());

        int menuChoice = 0;
        while(menuChoice != 5) {
            System.out.println("**********************************");
            System.out.println("Thank you for choosing Java World Bank!");
            System.out.println("Main Menu: ");
            System.out.println("[1] Login as an existing user.");
            System.out.println("[2] Display client list sorted by last name.");
            System.out.println("[3] Display client list sorted by account number.");
            System.out.println("[4] Create a new client.");
            System.out.println("[5] Exit.");
            System.out.println("====================================");
            do {
                try {
                    System.out.println("Enter your choice: ");
                    menuChoice = input.nextInt();
                    mainCheck = true;
                }
                // Checks if user enters an unexpected input (not a digit)
                catch(InputMismatchException e) {
                    System.out.println("Invalid input! Please use a numeric value between 1 and 5.");
                    if(debug == true)
                        e.printStackTrace();
                    input.nextLine();
                }
            }while(!mainCheck);

            switch(menuChoice) {
                case 1:
                    System.out.println("Please enter your fist name: ");
                    input.nextLine();
                    String loginFName = input.nextLine();
                    while(loginFName.matches("[a-zA-Z]*") == false) {
                        System.out.println("Invalid input. First name needs to be all letters. Please try again.");
                        loginFName = input.nextLine();
                    }
                    System.out.println("Please enter your last name: ");
                    String loginLName = input.nextLine();
                    while(loginLName.matches("[a-zA-Z]*") == false) {
                        System.out.println("Invalid input. Last name needs to be all letters. Please try again.");
                        loginLName = input.nextLine();
                    }
                    final String searchFName = loginFName;
                    final String searchLName = loginLName;
                    int loginValidation = 0;

                    Optional<Client> queryResult = clientArr.stream().filter(value -> value.getFName().equals(searchFName)
                                                                             &&value.getLName().equals(searchLName)).findFirst();
                    if(queryResult.isPresent()) {
                        System.out.println("User "+loginFName+" "+loginLName+" successfully logged into. Welcome back to Java World Bank.");
                        menuChoice = 5;
                    }
                    else
                        System.out.println("Login failed. Returning to main menu.");
                    break;
                case 2:
                    System.out.println("Clients of Java World Bank, sorted by last name: ");
                    clientArr.sort( (p1, p2) -> p1.getLName().compareTo(p2.getLName()) );
                    for(Client client : clientArr)
                        System.out.println(client);
                    menuChoice = 5;
                    break;
                case 3:
                    System.out.println("Clients of Java World Bank, sorted by ID: ");
                    clientArr.sort( (p1, p2) -> Integer.compare(p1.getAccount().getID(),
                                                                p2.getAccount().getID()));
                    for(Client client : clientArr)
                        System.out.println(client);
                    menuChoice = 5;
                    break;
                case 4:
                    System.out.println("You are now creating a new client account with Java World Bank!");
                    System.out.println("Some information is required to create this account.");
                    System.out.println("What would you like your ID number to be? It must contain only integers.");
                    check = false;
                    do {
                        try {
                            System.out.println("Please enter your choice: ");
                            idNumber = input.nextInt();
                            check = true;
                        }
                        catch(InputMismatchException e) {
                            System.out.println("ERROR: ID must contain integers only!");
                            input.nextLine();
                        }
                    }while(!check);
                    startingBalance = 0;
                    check = false;
                    // Continiously prompts user to enter valid input
                    do {
                        try {
                            System.out.println("What will be your starting balance?");
                            startingBalance = input.nextDouble();
                            check = true;   
                        }
                        // Checks if user enters a value that is not a double
                        catch (InputMismatchException e) {
                            System.out.println("Invalid input! Please enter a numeric value.");
                            input.nextLine();
                            if(debug == true)
                                e.printStackTrace();
                        }
                    }while(!check);
                    customerAccount = new Client(idNumber, startingBalance);
                    System.out.println("Please enter client's first name: ");
                    firstName = input.nextLine();
                    customerAccount.setFName(firstName);
                    // Verifies first name is only letters, either capital or lowercase
                    while(firstName.matches("[a-zA-Z]*") == false) {
                        System.out.println("Invalid input. First name needs to be all letters. Please try again.");
                        firstName = input.nextLine();
                        customerAccount.setFName(firstName);
                    }
                    System.out.println("Please enter client's last name: ");
                    lastName = input.nextLine();
                    customerAccount.setLName(lastName);
                    // Verifies last name is only letters, either capital or lowercase
                    while(lastName.matches("[a-zA-Z]*") == false) {
                        System.out.println("Invalid input. Last name needs to be all letters. Please try again.");
                        lastName = input.nextLine();
                        customerAccount.setLName(lastName);
                    }
                    System.out.println("Please enter client's email address: ");
                    emailAddress = input.nextLine();
                    customerAccount.setEmail(emailAddress);
                    // Verifies email address only uses lowercase/capital letters, dot, underscore, and/or dashes followed by @ symbol to specify domain
                    while(emailAddress.matches("^[A-Za-z0-9+_.-]+@(.+)$") == false) {
                        System.out.println("Invalid input. Email not in valid format. Please try again.");
                        emailAddress = input.nextLine();
                        customerAccount.setEmail(emailAddress);
                    }
                    System.out.println("Please enter client's phone number: ");
                    phoneNumber = input.nextLine();
                    // Verifies phone number follows valid North American format 000-000-0000
                    while(phoneNumber.matches("[0-9]\\d{2}-[0-9]\\d{2}-\\d{4}") == false) {
                        System.out.println("Invalid input. Phone number must be in the following format: 123-456-7890. Please try again.");
                        phoneNumber = input.nextLine();
                        customerAccount.setPNumber(phoneNumber);
                    }


            // Verifies that the starting balance the user inputs is positive
            while(startingBalance < 0) {
                System.out.println("**********************************");
                System.out.println("ERROR: You can not start with a negative balance.");
                System.out.println("Please enter a POSITIVE value for your starting balance: ");
                startingBalance = input.nextDouble();
            }

        }//end switch
    }
        // Debugging to verify user input is correctly stored
        if(debug == true) {
            System.out.println(customerAccount.toString());
            Account testing = customerAccount.getAccount();
            System.out.println("ID: "+testing.getID()+ " Balance: "+testing.getBalance());
        }

        System.out.println("********************************");
        System.out.println("Your account has been fully initialized! Thank you for choosing Java World Bank!");
        System.out.println("********************************");

        // Loops through menu prompt until user enters 4 to quit
        int choice = 0;
        while(choice != 4) {
            System.out.println("Client Menu");
            System.out.println("[1] Check Balance");
            System.out.println("[2] Withdraw");
            System.out.println("[3] Deposit");
            System.out.println("[4] Exit");
            System.out.println("=================================");

            // Continiously prompts user to enter valid input
            check = false;
            do {
                try {
                    System.out.println("So... What do you want to do?");
                    choice = input.nextInt();
                    check = true;
                }
                // Checks if user enters an unexpected input (not a digit)
                catch(InputMismatchException e) {
                    System.out.println("Invalid input! Please use a numeric value between 1 and 4.");
                    if(debug == true)
                        e.printStackTrace();
                    input.nextLine();
                }
            }while(!check);

            double amount = 0;
            switch(choice) {
                // Will display updated balance
                case 1:
                    System.out.println("Your current balance is: $"+customerAccount.getAccount().getBalance());
                    System.out.println("********************************");
                    break;
                // Allows user to withdraw money from current balance
                case 2:
                    // Continiously prompts user to enter valid input
                    check = false;
                    do {
                        try {
                            System.out.println("How much do you wish to withdraw?");
                            amount = input.nextDouble();
                            customerAccount.getAccount().withdraw(amount); // Passes withdraw value to Account class
                            System.out.println("********************************");
                            check = true;
                        }
                        // Validates that customer has enough money to withdraw the specified amount
                        catch(OutOfMoney error) {
                            System.out.println("You do not have enough funds to do this.");
                            System.out.println("********************************");
                        }
                        // Validates that customer enters expected input
                        catch(InputMismatchException e) {
                            System.out.println("INVALID INPUT. Please enter a numeric value.");
                            // Used to clear input buffer after catching exception
                            input.nextLine();
                            System.out.println("********************************");
                        }
                    }while(!check);

                    // Debugging to make sure values are correctly calculated
                    if(debug == true) 
                        System.out.println(customerAccount.getAccount().getBalance());
                    break;
                // Allows user to deposit money to current balance
                case 3:
                    check = false;
                    do {
                        try {
                            System.out.println("How much do you wish to deposit?");
                            amount = input.nextDouble();
                            customerAccount.getAccount().deposit(amount); // Passes deposit value to Account class
                            System.out.println("********************************");
                            check = true;
                        }
                        // Validates that user enters expected input
                        catch(InputMismatchException e) {
                            System.out.println("Invalid input. Please enter a numeric value.");
                            // Used to clear input buffer after catching exception
                            input.nextLine();
                            System.out.println("********************************");
                        }
                    }while(!check);

                    // Debugging to make sure values are correctly calculated
                    if(debug == true)
                        System.out.println(customerAccount.getAccount().getBalance());
                    break;
                // Exits program
                case 4:
                    System.out.println("Thank you for choosing Java World Bank!");
                    break;
                // Checks if user does not enter 1, 2, 3, or 4 in main menu prompt
                default:
                    System.out.println("You have entered an invalid input. Please try again.");
                    System.out.println("********************************");
                    break;
            }
        }
        input.close();
    }
}
sudo-potato
  • 171
  • 9

2 Answers2

2

Since the initialization of your object happens in a condition the compiler cannot figure out if it is initialized or not so you need to make sure its initialized outside a condition,for example make it null.

Client customerAccount = null ;
Amer Qarabsa
  • 6,412
  • 3
  • 20
  • 43
2

First, you may want to see here about declaring and initializing variables: here

You initialize the customerAccount on this line: customerAccount = new Client(idNumber, startingBalance);

However, that occurs within the switch in case 4. Then on this line System.out.println(customerAccount.toString()); you attempt to access the customerAccount's toString function. As this step is not in case 4, customerAccount may not be initialized.

Consider the case where the switch statement does not go to 4 and debug is set to true. customerAccount will be declared from this line: Client customerAccount; however, the code path will not initialize it in any way so you cannot call toString on it.

One solution could be to initialize the customerAccount to a null when you declare it or to a new Client(), or only attempt to access this variable after it was necessarily initialized. Hard to be sure without seeing the Client class. Do note that in the null case, you may have to do some null checks, for instance, if customerAccount is null then customerAccount.toString() will throw an exception.

Community
  • 1
  • 1
gwcoderguy
  • 392
  • 1
  • 13
  • Hm, I need to restructure the layout of my code I think. Thank you for the advice. – sudo-potato Apr 19 '17 at 17:27
  • 1
    No problem, I edited my answer to include a couple of things I missed, most importantly that if its null you may have an issue if you call .toString() on it. You can get around something like that by doing `Client customerAccount = null` then when you want to access it do `if (customerAccount != null)`. – gwcoderguy Apr 19 '17 at 17:56