Java reflection after invoking method the method is not throwing exception

So I created an InvalidInputExeption exception class and that get used in the setter methods to throw an exception if there is not a valid input.

public class kalsi.ContestantInformation {

    public void setFirstName(String firstName) throws InvalidInputExeption {
        checkInput(firstName, "Please only enter letter in the first name");
        this.firstName = firstName.replaceAll("\\s", "").toLowerCase();
    }

    public void setLastName(String lastName) throws InvalidInputExeption {
        checkInput(lastName, "Please only enter letter in the last name");
        this.lastName = lastName.replaceAll("\\s", "").toLowerCase();
    }

    public void setStreetNumber(String streetNumber) throws InvalidInputExeption {
        checkInput(streetNumber, "Please only enter numbers in the street number");
        this.streetNumber = streetNumber.replaceAll("\\s", "").toLowerCase();
    }

    public void setStreetName(String streetName) throws InvalidInputExeption {
        checkInput(streetName, "Please only enter letter in the street name name");
        this.streetName = streetName.replaceAll("\\s", "").toLowerCase();
    }

    public void checkInput(String s, String message) throws InvalidInputExeption {
        char[] array = s.toCharArray();
        for (char c : array) {
            if (!Character.isLetter(c)) {
                throw new InvalidInputExeption(message);
            }
        }

    }

    public void checkInput(int i, String message) throws InvalidInputExeption {
        String s = i + "";
        char[] array = s.toCharArray();
        for (char c : array) {
            if (!Character.isDigit(c)) {
                throw new InvalidInputExeption(message);
            }
        }
    }
}

And here is the main method in which I invoke the setFirstName using reflection. Note setFirstName is not the only setter method. all the other methods are in an array of Strings which have the names of the setMethods.

public static void main(String[] args)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
        SecurityException, ClassNotFoundException, InstantiationException {
    ContestantInformation contestant1 = new ContestantInformation();
    String[] questions = { "What is your first name", "What is your last name", "What is your Street Name",
            "What is your Sreet Number" };
    String[] methods = { "setFirstName", "setLastName", "setStreetName", "setStreetNumber" };
    for (int i = 0; i < methods.length; i++) {
        do {
            try {
                flag = false;
                System.out.println(questions[i]);
                String scannerInput = scanner.nextLine();
                classContestantInfo.getDeclaredMethod(methods[i], stringParameter).invoke(contestant1,
                        scannerInput);
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof InvalidInputExeption) {
                    System.out.println(e.getMessage());
                }
            }
        } while (flag);
    }
}

The problem is when I input something that is not a String it does not re ask the the question or give the error message here is the output.

What is your first name 9 null What is your last name

it outputs null and moves to the next question even though its supposed to output "Please only enter letter in the first name" and then ask for the user input again.

Here is the git clone URL if anyone want to clone the code the program is the RealityShowApplication in the ICS4U repository:

https://github.com/simar1998/ICS4U.git

Upvotes: 0

Views: 74

Answers (2)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31269

You are showing the message of the InvocationTargetException, not of your InvalidInputException.

You also want to make sure that the question is repeated by setting your repeat-flag to true.

Change the catch clause body to:

if (e.getCause() instanceof InvalidInputExeption) {
    System.out.println(e.getCause().getMessage()); // <-- note: getCause() here
    flag = true; // Make sure that the question is repeated
}

I would suggest to change flag to inputError, repeatFlag or something else more descriptive of the function of this flag.

Upvotes: 1

Evan VanderZee
Evan VanderZee

Reputation: 867

In addition to the other answer posted here, the reason that you do not continue to loop and ask the same question until it is sufficiently answered appears to be that you set flag = false before you have a successful invocation of the method that will check the input. Also, you should reset flag = true at the beginning of the for loop so that if a second or subsequent question has invalid input, you will continue to loop on that question until it is answered.

Upvotes: 1

Related Questions