Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling a new exception in an anonymous inner class

Tags:

java

exception

I have a situation similar to the following:

/** Get a list of records */
public ArrayList<Record> foo() throws BazException{

    // Create the list
    static ArrayList<Record> records = new ArrayList<Record>();

    // Use MyLibrary to load a list of records from the file
    String str = SomeoneElsesLibrary.loadData(new File("mydata.dat"), new DataLoader(){

        // will be called once for each record in the file
        String processRecord(Record r){

            // if there's no "bar", invalid record
            if( ! r.hasField("bar") ){
                throw new BazException();
            }
            records.add(r);
        }
    });
    return records;
}

Obviously this doesn't work, because SomeoneElsesLibrary has no idea what a BazException is. I also can't say processRecord() throws BazException because then the prototype would no longer match. I'm starting to think that my overall structure for this implementation is wrong. (I'm recovering from a bout of Node.JS addiction and have to re-learn some most Java patterns.) How would I restructure my code to make it more idiomatic Java?

Pseudocode is fine, or even just a description. Also, don't feel like you need to use an anonymous inner class, like I did in my first go at it; I'm just looking for "the Java way" to do this.

like image 342
Ryan Kennedy Avatar asked Sep 15 '13 18:09

Ryan Kennedy


2 Answers

Ryan, ensure that your BazException is an extension of the RuntimeException (unchecked exception) rather than Exception (checked one).

Otherwise, as you must have probably noticed, the compiler will complain about not handling your own exception.

For more information, have a look to some information about unchecked exceptions (i.e. RuntimeException or Error):

http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

like image 95
ASBH Avatar answered Oct 20 '22 03:10

ASBH


An exception refers to the method can throw it, not to a class (SomeoneElsesLibrary).

There are two types of exceptions, checked (subtype of Exception) and unchecked (subtype of RuntimeException). The checked must be declared explicitly in the signature of the method that can throw it. The unchecked can propagate without being declared in the signature of the method and without being handled by no try/catch block.

Generally checked are used when the caller of the method that raises the exception can remedy it, the unchecked otherwise.

You can handle the unchecked exception in foo() method by a try/catch ...

public ArrayList<Record> foo(){
    static ArrayList<Record> records = new ArrayList<Record>();

    try{
       SomeoneElsesLibrary.loadData( ... );
    } catch (BazException be){ // you just handle the exception here
    }

    return records;
}

... or not

public ArrayList<Record> foo(){
    static ArrayList<Record> records = new ArrayList<Record>();

    // if SomeoneElsesLibrary.loadData raise the BazException
    // it is propagated to the caller of foo()
    SomeoneElsesLibrary.loadData( ... );

    return records;
}

Instead a checked exception must always be handled.

like image 39
Modestino Avatar answered Oct 20 '22 03:10

Modestino