Introduction to Programming (CPSC 124)
—Hobart & William Smith Colleges, Fall 2014
Class Notes—October 20, 2014
Home | Syllabus | Calendar | Class Notes | Labs and Projects | General Notes |

Method Definitions and Library Construction

One of the main uses for static methods is the construction of libraries, whose methods can be used by other programs. In class, a library was constructed for handling various matter related to formatting a calendar date:

/** * Subroutines related to date validation and formatting. */ public class DateUtils { /** * Determines whether or not a date is valid. * * @param y the year (4 digit, y > 1582) * @param m the month (1 <= m <= 12, 1 = Jan, 2 = Feb, etc) * @param d the day of the month (1, 2, ...) * @return true if the specified date is valid, false if not */ public static boolean isValidDate ( int y, int m, int d ) { int[] maxDays = new int[]{31,28,31,30,31,30,31,31,30,31,30,31}; boolean leapYear = (y %4 == 0) && (y % 100 != 0 || y %400 == 0); if (leapYear) { maxDays[1] = 29; } boolean valid = (1 <= m && m <= 12); // valid month? valid = valid && (1 <= d); // Is d >= 1 ? valid = valid && (d <= maxDays[m-1]); // Is d no bigger than the max? return valid; } // isValidDate /** * Formats a date in the form: monthname day, year. If the date is invalid, * prints an error message instead. Requires (y,m.d) be a valid date (use * isValidDate(y,m,d) to check, first). * * @param y the year (4 digit, y >= 1582) * @param m the month (1 <= m <= 12, 1 = Jan, 2 = Feb, etc) * @param d the day of the month (1, 2, ...) */ public static void formatDate ( int y, int m, int d ) { assert isValidDate(y,m,d); // Now we'll print the formatted date (which we know is valid) String[] monthNames = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; System.out.println(monthNames[m-1]+ " " + d + ", " + y); } // formatDate } // DateUtils class

In a separate file, we have a program, DateFormat3, which uses the methods in this library. You just need to make sure that the .class file for DateUtils is visible to DateFormat3 (for example, keep them in the same folder). The nice thing about this arrangement is that any other program can also use this library, without needing to redefine the methods on its own.

/** * Date formatting, using functions from a library. */ import java.util.Scanner; public class DateFormatV3 { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("enter a date (yyyy mm dd) or q to quit: "); while(input.hasNextInt()) { int y = input.nextInt(); int m = input.nextInt(); int d = input.nextInt(); if (DateUtils.isValidDate(y,m,d)) { // Both isValidDate and formatDate are defined in // the DateUtils library DateUtils.formatDate(y,m,d); } else { System.out.println("Sorry. That's not a valid date."); } System.out.print("enter a date (yyyy mm dd) or q to quit: "); } // while } // main } // DateFormat3 class

Bonus Material

I've modified the body of formatDate() to introduce a new construct that is particularly handy in expressing a method's preconditions: assertions. The assert statement always includes a boolean-valued expression. If that expression evaluates to true, then execution proceeds normally, and the assertion is invisible to the rest of the program. However, if the expression is false, the assertion fails, and an AssertionError exception is thrown.

Assertions are handy in part because by default, they're disabled, so you only need to encounter them when you're testing your program. To run a program with assertions enabled, add the "switch" -ea to the invocation of your program:

John-Lasseter:~ jlasseter$ java -ea DateFormat3 2014 10 22
October 22, 2014

John Lasseter