I'd really appreciate some general formatting/style/performance tips, as well as any ways I could improve this code in general that I wrote for an assignment (title) that's due at the end of the week.  The code passes every test input given (leap years and such), so the logic is all set.  I had the HashSet as a List originally, but I read that a HashSet will give better performance, although I'm not sure if it even matters with only 4 values.import java.util.*;class Dates {    private static final Set<Integer> THIRTY_DAY_MONTHS = new HashSet<>(Arrays.asList(4, 6, 8, 11));    private String monthString;    private Dates() {        //Initializing input method        System.out.println(Enter month/day/year to be converted to normal format: );        Scanner s = new Scanner(System.in);        //Creates an array of strings split at forward slash        String[] input = s.nextLine().split(/);        //Converts the array of strings to array of ints with matching indices        int[] inputNumbers = new int[input.length];        for (int i = 0; i < input.length; i++) {            inputNumbers[i] = Integer.parseInt(input[i]);        }        //String month values for numeric inputs        if (inputNumbers[0] == 1) {            monthString = January;        } else if (inputNumbers[0] == 2) {            monthString = February;        } else if (inputNumbers[0] == 3) {            monthString = March;        } else if (inputNumbers[0] == 4) {            monthString = April;        } else if (inputNumbers[0] == 5) {            monthString = May;        } else if (inputNumbers[0] == 6) {            monthString = June;        } else if (inputNumbers[0] == 7) {            monthString = July;        } else if (inputNumbers[0] == 8) {            monthString = August;        } else if (inputNumbers[0] == 9) {            monthString = September;        } else if (inputNumbers[0] == 10) {            monthString = October;        } else if (inputNumbers[0] == 11) {            monthString = November;        } else if (inputNumbers[0] == 12) {            monthString = December;        }        //Logic for testing valid inputs        try {            if (inputNumbers[0] > 12 || inputNumbers[0] <= 0) { //Logic for valid range of months                throw new MonthException();            } else if (THIRTY_DAY_MONTHS.contains(inputNumbers[0]) && inputNumbers[1] > 30) { //Logic for valid day ranges for months that only contain 30 days                throw new DayException();            } else if (inputNumbers[1] > 31 || inputNumbers[1] <= 0) { //Logic for max and min # of possible days per any month                throw new DayException();            } else if (inputNumbers[0] == 2 && inputNumbers[1] > 29 && inputNumbers[2] % 4 == 0 && (inputNumbers[2] % 100 != 0 || inputNumbers[2] % 400 == 0)) { //Logic for # of days in February for a leap year                throw new DayException();            } else if (inputNumbers[2] < 1000 || inputNumbers[2] > 3000) { //Logic for valid range of years                throw new YearException();            }            //Prints and formats the numeric input as a string            System.out.println(monthString + ' ' + inputNumbers[1] + ,  + inputNumbers[2]);        } catch (MonthException e) {            System.out.println(e.getMessage());            loop();        } catch (DayException e) {            System.out.println(e.getMessage());            loop();        } catch (YearException e) {            System.out.println(e.getMessage());            loop();        }    }    //Exactly the same as the above code minus the initial prompt, only runs if the user enters any invalid input    private void loop() {...}    public static void main(String[] args) {        @SuppressWarnings(UnusedAssignment) Dates d = new Dates();    }}Each exception class is defined like this:class YearException extends Exception {    public YearException() {        super(Invalid year! Re-enter valid year!);    }    public YearException(String message) {        super(message);    }}I know I don't make use of the second constructor, but I was taught it's generally a best-practice to include it.
Converting numeric (month/day/year) date inputs to regular format (month day, year)
java;datetime
Some quick pointers:Fail-fastFirst, your //Logic for testing valid inputs occurs after you interpret your month value, which means it is either already unnecessary after successfully setting monthString (and the other values are valid), or you just wasted code in your long if-else (see next point) should the validation fail afterwards for the day value, for example. Also, this snippet should already suggest that you should handle user inputs elsewhere instead of the constructor (see last point)://Exactly the same as the above code minus the initial prompt, only runs if the user enters any invalid inputprivate void loop() {...}Long if-elseUsing a Map or Enum is greatly preferred.Unused assignmentJust mentioning this for the sake of mentioning (see final point below), but you can probably get away with just this:public static void main(String[] args) {    new Dates();}Doing everything in constructorThink of public static void main as the entry point to your Java class, so handling user inputs is usually done within this method and not in the constructor. This encourages you to either use your class as an utility class or a model class. The former usually implies the class will have a private constructor and some public static methods to only perform the conversion you require, while the latter usually implies that it will have some internal fields to be set upon its construction, for example. The current approach you have is creating an instance of your class to handle inputs and also do the formatting, which is not recommended. In either ways, it will also cut down on the code duplication you experienced in the first point, since you no longer need a loop() method.try-with-resources and multi try-catchIt appears that you are already using Java 7, consider try (Scanner scanner = new Scanner(System.in)) { ... } to close your Scanner instance safely. And Java 7 lets you try-catch on multiple exceptions, assuming that is part of your assignment.