GeeCON Prague 2014*
The moose likes Beginning Java and the fly likes try and catch Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Beginning Java
Bookmark "try and catch " Watch "try and catch " New topic
Author

try and catch

Maureen Charlton
Ranch Hand

Joined: Oct 04, 2004
Posts: 218
I have a class called VehicleRecord which has the following method which uses the try and catch for exception handling:



I then have a method in the ValidateRecord class which throws a message depending on the date:



When compiling I get the following error message:

C:\java\PoliceDatabase>javac TestApp.java
.\InvalidRecord.java:76: unreported exception java.text.ParseException
caught or declared to be thrown
Date inputDate = sdf.parse (date);
^
.\InvalidRecord.java:77: unreported exception java.text.ParseException
caught or declared to be thrown
Date dateFrom = sdf.parse (from);
^
.\InvalidRecord.java:78: unreported exception java.text.ParseException
caught or declared to be thrown
Date dateUntil = sdf.parse(until);
^
3 errors

Is someone able to tell me if I have coded the try and catch statements correctly? - I had difficulty finding examples when it was used in two different classes. Previously I have used try and catch in the same method in the same class in the same file.
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

In your first code example, the method declares that it might throw an InvalidRecord exception. But actually the code catches (handles) any such exception, so you really don't need to declare it.

However, in the second code example, you call parse methods that could throw a ParseException. This exception is neither caught nor declared, so it's generating compilation errors. To fix this, you need to either put the parse calls in a try block and catch the ParseException, or add the ParseException to the method declaration (separating it from the InvalidRecord with a comma)...

public static void validateDate (String date) throws InvalidRecord, ParseException {...


"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
Maureen Charlton
Ranch Hand

Joined: Oct 04, 2004
Posts: 218
Marc,

Many, many thanks for your response.

Unfortunately one of the constraints of this requirement is the method name in the VehicleRecord class and the InvalidRecord class.

It has to be:
public static void validateDate (String date) throws InvalidRecord

Would it therefore be feasible to put the catch ParseException e in the class: InvalidRecord? Or am I going off in the wrong direction here?
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Maureen Charlton:
... Would it therefore be feasible to put the catch ParseException e in the class...? ...

Yes, if you're not able to declare that the method throws this exception, then you're going to have to handle this type of exception within the method. That is, place your calls to the parse method within a try block and catch the ParseException.
Maureen Charlton
Ranch Hand

Joined: Oct 04, 2004
Posts: 218
marc

Again, thanks for your response. I will give it ago.
Maureen Charlton
Ranch Hand

Joined: Oct 04, 2004
Posts: 218
I have given this ago and amended my code as follows:

In my VehicleRecord class I now have the following method:



Please note I have changed my class called InvalidRecord to InvalidRecordException; as I did some reading and this is what was recommended.

My class InvalidRecordException now has the following code:



I am testing the program with the following code in a class called TestApp.
The code for this class is:




But I am STILL getting an error message when compiling. The error message is:

C:\java\PoliceDatabase>javac TestApp.java
TestApp.java:54: unreported exception InvalidRecordException; must be caught or
declared to be thrown
record.validateDate("1003");
^
1 error

My understanding is that I am catching this InvalidRecordException and declaring it to be thrown. I don't understand. Please can someone help? I'd really appreciate it! I've been looking at this most of the day and most of last night.
M Beck
Ranch Hand

Joined: Jan 14, 2005
Posts: 323
the key is in the "throws" declaration. this is used to tell other methods, "hey, this particular method might give rise to such and such an exception - if you use me, take care to handle it!". it's not meant to explain what exceptions your method might run into; nobody else needs to know that, so there's no declaration needed about that.

now, look at your method "validateDate". it's declared as "throws ParseException, InvalidRecordException", which means that any other methods that use it need to watch out for those to be thrown; either they must wrap any usage of validateDate in a try/catch pair that deals with those two, or they themselves must be declared to throw those, so as to pass them on upstream. (you might want to look at the guts of this method, too; can it, really, throw both those exceptions? where from?)

secondly, look at the methods that make use of "validateDate". are they, in fact, correctly wrapping any use of that method in try/catch blocks to manage all the exceptions that validateDate has declared it might throw? the error message seems to be telling you this is not so.

finally, and on an unrelated topic: you say near the top that your class "InvalidRecordException" is the class that contains "validateDate". that doesn't sound quite right to me. when creating one's own exception classes, they're usually empty, or nearly so. custom exception classes usually just extend some other class (normally Exception), with very little new stuff added. they get used by one's main, "business logic" classes, but it's not normal to put business logic code in an exception class. maybe you misspoke?
Maureen Charlton
Ranch Hand

Joined: Oct 04, 2004
Posts: 218
M Beck, Many thanks for your response. Much appreciated.

I'm so, so confused with this try and catch.
I have had NO Problems when using them in the same class and same method but to split them up is proving an absolute nightmare!!!

I can't find any examples of where this has been done previously either.

VehicleRecord class is to have the signature and declaration for validate date method. This throws InvalidRecord.

VehicleRecord extends ValidateRecordException class.

ValidateRecordException class extends Exception.

The ValidateRecordException has millions of validations in (this is the first of many so I really need to get to grips with it).
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

You're calling the method, parse(String source). This method is defined in java.text.DateFormat (and inherited in the subclass you're using, SimpleDateFormat).

If you check the API for java.text.DateFormat, you'll see that the parse(String source) method declares that it might throw a ParseException. This is a warning to you, the programmer.

The exception declaration is telling you that when you call parse in your own method, you need to take precautions. You have two choices:
  • Handle the exception by enclosing the parse calls in a try block, then catching the exceptions (if thrown) and dealing with them in a manner appropriate to your own program; OR...
  • Don't handle the exception. Just call the method without a try/catch block.
  • If you handle the exception within your method, then it's "safe." You've taken care of the potential exception, so there's no need to warn users. You do not need to declare it in your method.

    On the other hand, if you choose the second option, then you're leaving potential exceptions unhandled. Therefore, you must warn users of your method that it might throw this exception (just as the authors of the original parse method warned you that an exception might be thrown by calling parse). Specifically, you must declare it in your method.

    Now, if you take the second option and declare that your method might throw an exception, then you're kind of "passing the buck." This means that whatever method calls your method must then take the same precautions -- either enclosing your method in a try/catch block or declaring the possible exception...
    M Beck
    Ranch Hand

    Joined: Jan 14, 2005
    Posts: 323
    it definitely sounds like your class hierarchy is confused; i'm pretty sure the way you're describing it isn't how you would, ideally, want it to be set up.

    for reference, here's a small part of a previous class project of mine: an exception class i defined myself. this is the entirety of that class, as written and used.

    in fact, i could probably have made it even simpler still.

    here's an example of how i went about throwing this newly-defined exception of mine. this is a method defined in a whole other class entirely. (actually, it's the constructor method in a class named "Album".) the class this came from did not inherit from or extend on the AlbumException class, in any way, shape or form:

    note the "throws" declaration - this method can be the source of an AlbumException, and any code that wants to call this method had better know it and be prepared.

    here, finally, is an example of how to handle the exception:

    i hope this helps you get your head around the basic usage patterns. as well, the tutorial about exceptions on Sun's Java site might come in handy, also.
    James Carman
    Ranch Hand

    Joined: Feb 20, 2001
    Posts: 580
    Originally posted by Maureen Charlton:
    Marc,

    Many, many thanks for your response.

    Unfortunately one of the constraints of this requirement is the method name in the VehicleRecord class and the InvalidRecord class.

    It has to be:
    public static void validateDate (String date) throws InvalidRecord

    Would it therefore be feasible to put the catch ParseException e in the class: InvalidRecord? Or am I going off in the wrong direction here?


    It seems like you would do yourself some good to get an IDE of some sort. Most IDEs (I use IntelliJ IDEA) will tell you what the compiler problem is and give you suggestions on how to fix it (the little lightbulb icon in both IDEA and Eclipse). They even take it a step further and will usually generate the code for the suggested solution once you choose which one you want to use. For example, in Eclipse (since it's free), I pasted in your code for the second version of the validateDate() method. On the first line where you call sdf.parse(), it shows that there is a compiler error. When I click on the little lightbulb for suggestions, it has two options.

  • Add throws declaration
  • Surround with try/catch


  • If you choose the first option, it will change the method signature to...



    which you don't want. If you choose the second option, it will make the code look like...



    which only takes care of the first instance where you call the parse() method, obviously, but you could easily extend your try/catch to include all three calls.

    Some people disagree with using an IDE to learn the language, but I think it's these little features that will help you learn quicker. After all, if you were using Eclipse, you wouldn't have had to ask this forum what to do. As you are exploring the language, an IDE can help you realize what your options are when you encounter a problem rather than make you have to take a shot in the dark at trying to fix it (or wait for one of us to answer you on the forum). I would actually recommend IDEA over Eclipse, but that's just a personal preference. IDEA costs money (it's worth it to me), so it might not be an option. Eclipse is a very good IDE. I've just become so accustomed to editing in IDEA. Anyway, hope that helps and happy coding!


    James Carman, President<br />Carman Consulting, Inc.
    Maureen Charlton
    Ranch Hand

    Joined: Oct 04, 2004
    Posts: 218
    Marc Weber, M Beck and James Carmen,

    I owe you all a drink!! A BIG drink!

    I got there in the end.......

    My problem was I had InvalidRecord class which extended the Exception class.

    This declare the constructor InvalidRecord(String message) and InvalidRecord( ).

    What I was doing wrong through was putting the method to validateDate (date) throws InvalidRecord in the InvalidRecord class.

    The method validateDate (date) throws InvalidRecord was written with the business logic in the InvalidRecord class. BIG MISTAKE!

    I now understand that the validateDate (date) throws InvalidRecord should actually be written in the VehicleRecord class.

    So I now have my method validateDate(date) throws InvalidRecord in the VehicleRecord class.

    The InvalidRecord class simply extends Exception and has two constructors.

    I use a TestApp class to test whether it works. This calls the method and gets the relevant message.

    Yippppeee!!! is all I can say now PLUS a big THANK YOU!

    To those that have followed this thread here is the code which I feel is now correct:

    In my InvalidRecord class I have the following: (with no methods)


    In my VehicleRecord class I have the following method:


    In my TestApp class I have the following code:


    Note: there were many other tests here but I didn't think it necessary to show them all.

    [BOLD]The output was as follows:[/BOLD]
    Validating Date: 1003
    Date successfully validated

    Date input by user: 1003
    dateFrom is:= Thu Jan 01 00:00:00 GMT 1981
    dateUntil is:= Tue Dec 01 00:00:00 GMT 2020

    Finished!!!

    Testing when format of date is NOT valid i.e. 11/2/91
    ===================================

    Validating Date: 11/2/91
    Date input by user:= 11/2/91 Not valid.
    Needs to be four digits i.e. MMYY

    Finished Validation

    Testing when format of date is NOT valid i.e. 12th January 2001
    ===================================

    Validating Date: 12th January 2001
    Date input by user:= 12th January 2001 Not valid.
    Needs to be four digits i.e. MMYY

    Finished Validation

    Testing when date is before 0181 i.e. 0180
    ==================================

    Validating Date: 0180
    date NOT valid. Before 0181

    Finished Validation

    Testing when date is after 1220 i.e. 1221
    ===================================

    Validating Date: 1221
    date NOT valid. After 1220

    Finished Validation


    Again, many thanks! You have made me happy!
     
    GeeCON Prague 2014
     
    subject: try and catch