When programming a solution like this, in order to simplify the problem create a separate function for each component. So, I would break it up into three different parts:
String getUserInput() {
// Get input string and return it...
}
boolean isValidInput(String input) {
// Return true or false based off of the validity of the input string.
}
boolean isPalindrome(String input) {
int left = 0;
int right = input.length();
while(left < right) {
if(input.charAt(left++) != input.charAt(--right)) return false;
}
return true;
}
The reason for returning a boolean rather than throwing an exception is that a try catch can be expensive especially if there is a good chance of an error being thrown. Now, a boolean means later that there may be some sort of conditional branch, but that is less expensive than if there is a high chance of an error being thrown. Also, there is more usability with returning a boolean, because now you can decide if you want to throw an exception or just print true or false.
Since the question was more geared towards the optimization of the palindrome detection algorithm, I provided a solution that I have found to work the best for when detecting palindromic inputs.
The solution cuts the number of steps down to a quarter of your solution. This is done by assuming that if the first half is the same as the second half then the String must be palindrome. So, we start from both ends and work our way to the center (essentially when left equalsreaches or passes right). If any where along the way we find a point in which is not equal, then we know that we do not have a palindromic String. Therein, we can exit returning false. If we successfully exit the loop, then we know we were given a palindromic String. Therein, we return false.