0

I have a class ProductionWorker with the superclass Employee, that I created for a school project. We are supposed to set up exceptions for it this week and I keep getting an error when trying to create one of them. Here's my code:

in ProductionWorker:

   public String toString() throws InvalidShift{
      DecimalFormat dollar = new DecimalFormat("$#,##0.00");
      String str = super.toString();

      str += "The employee's pay rate is " + dollar.format(getPayRate()) +"\n";
      str += "The employee works the " + getShift() + " shift";
      return str;
   }

The super.toString class:

   public String toString() throws InvalidShift{
      String str = "The employee's name is " + getEmployeeName() + ".\n";
      if (employeeNumber.equals("")){
         str += "The employee's ID number is invalid.\n";
      }else{
         str += "The Employee's ID number is " + employeeNumber + ".\n";
      }
      str += "The employee's hire date was " + hireDate + ".\n";

      return str;
   }

When I try to compile, I get the following errors:

Employee.java:126: error: toString() in Employee cannot override toString() in Object
   public String toString() throws InvalidShift{
                 ^
  overridden method does not throw InvalidShift
ProductionWorker.java:54: error: toString() in ProductionWorker cannot override toString() in Object
   public String toString() throws InvalidShift{
                 ^
  overridden method does not throw InvalidShift

Now, the actual exception itself is thrown in the getShift() method, so there's no way that the Employee.toString() method could actually throw the exception. The program would enter the ProductionWorker.toString(), run the Employee.toString() and return it's string, then execute getShift() later, which could throw the exception. So I don't need Employee.toString() to be capable of throwing, and it would cause a mess of other problems if it did.

Any help?

Edit

I'm going to just rewrite the whole thing to be an int instead of two booleans.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 4
    Well... the `toString()` method in fact doesn't throw the `InvalidShift` exception, so you shouldn't declare that it does, simple as that. – Hovercraft Full Of Eels Feb 11 '15 at 23:15
  • InvalidShift is a custom exception class, not a method that throws an exception. – D. Scott Boggs Feb 11 '15 at 23:16
  • 1
    My error. The bottom line is this: **toString() should not be written to throw any exceptions. Period** – Hovercraft Full Of Eels Feb 11 '15 at 23:16
  • 2
    For starters, even if this is a custom exception class, please abide to the conventions and name it appropriately: `InvalidShiftException` or the like – fge Feb 11 '15 at 23:16
  • Well then where should I throw the exception? I can't have it in the setShift() method because running the setShift method by default sets shiftValid to true. Basically I have two boolean variables: dayShift and shiftValid. If setShift() is never run, shiftValid would be false and the exception should be thrown if someone attemts to getShift(). If dayShift is true the person is said to work day shift, if it's false the personis said to work nights. Make sense? – D. Scott Boggs Feb 11 '15 at 23:19
  • @fge I would have but the assignment determined the names of the exception classes. I will be sure to do this in the future, of course, but you've gotta make the teacher happy. – D. Scott Boggs Feb 11 '15 at 23:22
  • 'but the assignment determined the names of the exception classes' <-- go please slam your teacher with a sledgehammer – fge Feb 11 '15 at 23:46

2 Answers2

6

The bottom line is this: toString() should not be written to throw any exceptions. Period It's only job is to create a String that represents the state of the object. It should not change the state of the object itself, and it should never need to throw an exception.

So get rid of throws InvalidShift from toString().

Instead, add this statement to a method that in fact may throw the exception.

You state:

Now, the actual exception itself is thrown in the getShift() method,

so this method should be declared to throw the exception.

so there's no way that the Employee.toString() method could actually throw the exception.

Right. And so it should not be declared as throwing it as you're doing in your code.

The program would enter the ProductionWorker.toString(), run the Employee.toString() and return it's string, then execute getShift() later, which could throw the exception. So I don't need Employee.toString() to be capable of throwing, and it would cause a mess of other problems if it did.

So why declare that it throws the exception in the first place?


And yeah, rename it to InvalidShiftException.


more

I can't have it in the setShift() method because running the setShift method by default sets shiftValid to true. Basically I have two boolean variables: dayShift and shiftValid. If setShift() is never run, shiftValid would be false and the exception should be thrown if someone attemts to getShift().

Then getShift() should be declared to throw the exception and in fact should throw it if someone calls it when the object is in an invalid state (if setShift() hasn't been called for instance).

e.g.,

public Shift getShift() thows InvalidShiftException {
   if (!shiftValid) {
      throw new InvalidShiftException("maybe some text in here");
   } else {
      return whatIsSupposedToBeReturned;
   }
}

Edit
You state:

the issue is that toString() calls getShift(), so toString() will be in the stack when the exception is thrown. There's no getting around that.

Yes there is! use a try/catch inside of toString()! Or test if shift is valid (call a boolean method) first before calling getShift() inside of toString()

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

You can't declare toString() to throw checked exceptions, but you can declare it (or just throw without declaring to throw) unchecked exceptions - which are subclasses of RuntimeException.

Change your exception class to extend RuntimeException instead of Exception.

Bohemian
  • 412,405
  • 93
  • 575
  • 722