日期比较触发NullPointerException及Shipment代码修正请求
Alright, let's work through fixing your date comparison and NullPointerException issues step by step. Here's what's going wrong and how to resolve it:
Key Problems in Your Current Code
Unnecessary New Objects Causing NPE:
InShipmentBO.displayStatusOfShipment, you're creating brand new emptyShipment sandShipmentStatus SStatusinstances instead of using theshipmentparameter passed into the method. These empty objects havenulldate values, so callingDate.after()orDate.before()on them throws a NullPointerException.Missing Link to Actual Shipment Status:
You never retrieve thearrivedDatefrom the input shipment'sshipmentStatusarray. The original code uses a freshShipmentStatusobject that has no date set at all.Reversed Status Logic:
Your date comparison is backwards! For example,expectedDate.after(arrivedDate)means the expected delivery date is later than the actual arrival date—so the shipment arrived early—but your code prints that it arrived after the expected date. That's the opposite of what's true.Uninitialized ShipmentStatus:
In your main method, you never create aShipmentStatusobject, set itsarrivedDate, or attach it to theShipmentinstance. Without this, there's no arrival date to compare against.
Fixed Code
First, let's update the ShipmentBO class to use the passed shipment and handle nulls safely:
import java.text.SimpleDateFormat; import java.util.Date; public class ShipmentBO { public void displayStatusOfShipment(Shipment shipment) { // Guard against null shipment input if (shipment == null) { System.out.println("Error: Invalid shipment details provided."); return; } Date expectedDate = shipment.getexpectedDeliveryDate(); Date arrivedDate = null; // Get arrival date from the shipment's status (we'll use the first status entry here) ShipmentStatus[] statuses = shipment.getShipmentStatus(); if (statuses != null && statuses.length > 0) { arrivedDate = statuses[0].getarrivedDate(); } // Check if we have valid dates to compare if (expectedDate == null || arrivedDate == null) { System.out.println("Error: Missing expected delivery date or arrival date information."); return; } SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yyyy"); String formattedExpected = dateFormatter.format(expectedDate); String formattedArrived = dateFormatter.format(arrivedDate); // Correct the comparison logic to match the actual status if (arrivedDate.after(expectedDate)) { System.out.printf("The shipment arrived LATE. Expected: %s, Actual Arrival: %s%n", formattedExpected, formattedArrived); } else if (arrivedDate.before(expectedDate)) { System.out.printf("The shipment arrived EARLY. Expected: %s, Actual Arrival: %s%n", formattedExpected, formattedArrived); } else { System.out.printf("The shipment arrived ON TIME. Expected: %s, Actual Arrival: %s%n", formattedExpected, formattedArrived); } } }
Next, update your main method to properly set up the ShipmentStatus and link it to the shipment:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Scanner; public class Main { public static void main(String[] args) throws ParseException { Scanner sc = new Scanner(System.in); System.out.println("Enter the shipment details (ID, Source Port, Destination Port, Expected Date (dd-MM-yyyy), Customer Name):"); String userDetail = sc.nextLine(); String userDetailParts[] = userDetail.split(","); Shipment shipment = new Shipment(); SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); // Clean up input by trimming whitespace shipment.setid(userDetailParts[0].trim()); shipment.setsourcePort(userDetailParts[1].trim()); shipment.setdestinationPort(userDetailParts[2].trim()); shipment.setexpectedDeliveryDate(sdf.parse(userDetailParts[3].trim())); shipment.setcustomerName(userDetailParts[4].trim()); // Get arrival date input from user System.out.println("Enter the actual arrival date (dd-MM-yyyy):"); String arrivalDateInput = sc.nextLine().trim(); Date arrivedDate = sdf.parse(arrivalDateInput); // Create and populate ShipmentStatus ShipmentStatus shipmentStatus = new ShipmentStatus(); shipmentStatus.setarrivedDate(arrivedDate); shipmentStatus.setarrivalPort(shipment.getdestinationPort()); // Set arrival port to destination shipmentStatus.setshipment(shipment); // Link status to shipment // Attach status to the shipment shipment.setShipmentStatus(new ShipmentStatus[]{shipmentStatus}); // Run the status display ShipmentBO shipmentBO = new ShipmentBO(); shipmentBO.displayStatusOfShipment(shipment); sc.close(); } }
Extra Improvements
- Null Safety: Added guard clauses to handle null inputs and missing dates, preventing unexpected NullPointerExceptions.
- Input Cleanup: Used
trim()on input parts to avoid issues with extra spaces in the user's input. - Clear Status Messages: Updated the output to be more intuitive, with formatted dates for clarity.
- Proper Object Linking: Ensured the
ShipmentStatusis attached to theShipmentso the BO class can access the arrival date.
内容的提问来源于stack exchange,提问作者user1677627

