Необходимо также быть подозрительной блокировкой или уведомлением относительно объектов как Строка и Целое число, которое может быть интернировано JVM (для предотвращения создания большого количества объектов, которые представляют целое число 1 или строка"").
JDK 8 делает это простым и элегантным:
public class AgeCalculator {
public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
if ((birthDate != null) && (currentDate != null)) {
return Period.between(birthDate, currentDate).getYears();
} else {
return 0;
}
}
}
Тест JUnit для демонстрации его использования:
public class AgeCalculatorTest {
@Test
public void testCalculateAge_Success() {
// setup
LocalDate birthDate = LocalDate.of(1961, 5, 17);
// exercise
int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
// assert
Assert.assertEquals(55, actual);
}
}
К настоящему времени все должны использовать JDK 8. Срок службы поддержки всех более ранних версий истек.
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = now.get(Calendar.DAY_OF_MONTH);
int day2 = dob.get(Calendar.DAY_OF_MONTH);
if (day2 > day1) {
age--;
}
}
// age is now correct
Check out Joda, which simplifies date/time calculations (Joda is also the basis of the new standard Java date/time apis, so you'll be learning a soon-to-be-standard API).
EDIT: Java 8 has something very similar and is worth checking out.
e.g.
LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);
which is as simple as you could want. The pre-Java 8 stuff is (as you've identified) somewhat unintuitive.