Java中从static方法调用non-static方法printMonth无输出求助
Hey there! Let's walk through why your printMonth() method isn't outputting anything and fix it up step by step:
1. Critical Bug: Reversed Assignment in Constructor
The biggest issue is in your MyDate constructor—you're assigning member variables to parameters instead of the other way around! This means when you create a MyDate object with new MyDate(day, month, year), the day, month, and year member variables stay at their default value of 0. All your calendar calculations rely on these values, so they return incorrect results, leading to no visible calendar output.
Fix the constructor like this:
public MyDate(int theDay, int theMonth, int theYear){ day = theDay; // Assign parameter to member variable month = theMonth; year = theYear; }
2. Redundant getDate() Call
In your main method, after creating the MyDate object correctly (once the constructor is fixed), you don't need to call myDateObj.getDate(datePartsObj)—this method re-assigns the same values you already passed to the constructor, which is unnecessary. You can remove that line entirely or adjust it if you had a different intent.
3. Improve Calendar Formatting (Optional but Recommended)
Your current print logic uses manual spaces, which can lead to alignment issues. Using System.out.printf will make your calendar look cleaner and more consistent. Here's an updated version of printMonth():
public void printMonth() { int theYear = myDateObj.getYear(); int theMonth = myDateObj.getMonth(); int startDay = myDateObj.getStartDay(theYear, theMonth); int numberOfDaysInMonth = myDateObj.getNumberOfDaysInMonth(theMonth, theYear); // Print leading spaces to align the first day with the correct weekday for (int i = 0; i < startDay; i++) { System.out.printf("%3s", ""); } // Print each day with consistent spacing for (int i = 1; i <= numberOfDaysInMonth; i++) { System.out.printf("%3d", i); // Start a new line after Saturday if ((i + startDay) % 7 == 0) { System.out.println(); } } System.out.println(); }
4. Verify Weekday Alignment
Double-check that your getStartDay() calculation matches your header. Your header starts with Sun, and since startDay1800 = 3 (1800-01-01 was a Wednesday), your current calculation will correctly align days to the header. For example, 2024-01-01 was a Monday, so startDay should return 1 (0 = Sunday), which will leave one empty space before printing the 1st.
Full Corrected Code Snippet
Here's the adjusted code with all fixes applied:
class MyDate { private int day; private int month; private int year; // Fixed constructor public MyDate(int theDay, int theMonth, int theYear){ day = theDay; month = theMonth; year = theYear; } public MyDate(){ } public int getDay() { return day; } public int getMonth() { return month; } public String nameOfMonth() { switch (month) { case 1: return "January"; case 2: return "February"; case 3: return "March"; case 4: return "April"; case 5: return "May"; case 6: return "June"; case 7: return "July"; case 8: return "August"; case 9: return "September"; case 10: return "October"; case 11: return "November"; case 12: return "December"; default: throw new RuntimeException("Invalid month number"); } } public int getYear() { return year; } // Optional: Remove if not needed public String getDate(String[] datePartsObj) { day = Integer.parseInt(datePartsObj[0]); month = Integer.parseInt(datePartsObj[1]); year = Integer.parseInt(datePartsObj[2]); return day + "/" + month + "/" + year ; } public int getStartDay(int theYear, int theMonth) { year = theYear; month = theMonth; int startDay1800 = 3; // 1800-01-01 was Wednesday int totalNumberOfDays = getTotalNumberOfDays(theYear, theMonth); return (totalNumberOfDays + startDay1800) % 7; } public int getTotalNumberOfDays(int theYear, int theMonth) { year = theYear; month = theMonth; int total = 0; for (int i = 1800; i < theYear; i++) if (isLeapYear(i)) total += 366; else total += 365; for (int i = 1; i < theMonth; i++) total += getNumberOfDaysInMonth(i, theYear); return total; } public int getNumberOfDaysInMonth(int theMonth, int theYear) { month = theMonth; year = theYear; if (theMonth == 1 || theMonth == 3 || theMonth == 5 || theMonth == 7 || theMonth == 8 || theMonth == 10 || theMonth == 12) return 31; if (theMonth == 4 || theMonth == 6 || theMonth == 9 || theMonth == 11) return 30; if (theMonth == 2) return isLeapYear(theYear)?29:28; return 0; } public boolean isLeapYear(int theYear) { year = theYear; if ((theYear %4 ==0) && (theYear%100 !=0)) return true; if (theYear%400 ==0) return true; return false; } } public class MyCalendar { private static MyDate myDateObj; public enum WeekDay{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday; } public MyCalendar(MyDate newdate){ } public MyCalendar(){ } public int weekOfMonth() { return 0; } // Improved printMonth method public void printMonth() { int theYear = myDateObj.getYear(); int theMonth = myDateObj.getMonth(); int startDay = myDateObj.getStartDay(theYear, theMonth); int numberOfDaysInMonth = myDateObj.getNumberOfDaysInMonth(theMonth, theYear); for (int i = 0; i < startDay; i++) { System.out.printf("%3s", ""); } for (int i = 1; i <= numberOfDaysInMonth; i++) { System.out.printf("%3d", i); if ((i + startDay) % 7 == 0) { System.out.println(); } } System.out.println(); } public static void main(String [] args) { String[] datePartsObj = args[0].split("/"); int day = Integer.parseInt(datePartsObj[0]); int month = Integer.parseInt(datePartsObj[1]); int year = Integer.parseInt(datePartsObj[2]); myDateObj = new MyDate(day, month, year); MyCalendar myCalendar = new MyCalendar(); System.out.println(myDateObj.getDay() + "/" + myDateObj.getMonth() + "/" + myDateObj.getYear() + " is located in " + myDateObj.nameOfMonth()); System.out.println("The calendar of " + myDateObj.nameOfMonth() + " " + myDateObj.getYear() + " is: "); System.out.println(); System.out.println(" Sun Mon Tue Wed Thu Fri Sat"); myCalendar.printMonth(); } }
Now when you run this with a valid date argument (like java MyCalendar 1/1/2024), you should see the correct calendar output!
内容的提问来源于stack exchange,提问作者user12062753

