View RSS Feed

Advanced Java

Generics - Exceptions

Rate this Entry
by , 11-29-2011 at 03:35 AM (1908 Views)
Due to erasure, exception use is limited with generics. As exceptions are know at both compile and at run time, it renders redundant the use of catch clauses. This also means that a generic class cannot inherit directly or indirectly from Throwable.

One can though use type parameters in the throws clause of a method declaration. This will allow you to write generic code that varies with the type of a checked exception:

Java Code:
import java.util.List;

public interface Processor<T,E extends Exception> {
	void process(List<T> resultCollector) throws E;
}

import java.util.ArrayList;
import java.util.List;

public class ProcessRunner<T, E extends Exception> extends
		ArrayList<Processor<T, E>> {
	List<T> processAll() throws E {
		List<T> resultCollector = new ArrayList<T>();
		for (Processor<T, E> processor : this)
			processor.process(resultCollector);
		return resultCollector;
	}
}



public class FailureImpl extends Exception {	
}

import java.util.List;

public class ProcessorImpl implements Processor<String,FailureImpl> {
	static int count = 3; 

	@Override
	public void process(List<String> resultCollector) 
	throws FailureImpl {
		if(count-- > 1) resultCollector.add("Hep!");
		else resultCollector.add("Ho!");
		if(count < 0) throw new FailureImpl();		
	}
}

In the listing above, we create an interface Processor that performs a process( ) and throws an exception of type E. The result of the implementation of process( ) is stored in the collecting parameter List<T> resultCollector. Finally the ProcessRunner has a processAll( ) method that loops through every Process object that it holds, and returns the resultCollector. If it was not possible to parameterize the exceptions that are thrown, you would be unable to write this code in a generic manner because of the checked exceptions.

Java Code:
public class FailureImplE extends Exception {

}

import java.util.List;

public class ProcessorImplE implements Processor<Integer,FailureImplE> {
	static int count = 2;
	
	@Override
	public void process(List<Integer> resultCollector) throws FailureImplE {
		if(count-- == 0) resultCollector.add(47);
		else { resultCollector.add(11);
		} if(count < 0)
		throw new FailureImplE();		
	}
}

public class ThrowGenericException {
	public static void main(String[] args) {
		ProcessRunner<String,FailureImpl> runner = 
			new ProcessRunner<String,FailureImpl>();
		for(int i = 0; i < 3; i++) runner.add(new ProcessorImpl());
		try { System.out.println(runner.processAll());
		} catch(FailureImpl e) { System.out.println(e);
		}
		ProcessRunner<Integer,FailureImplE> runner2 = 
			new ProcessRunner<Integer,FailureImplE>();
		for(int i = 0; i < 3; i++) runner2.add(new ProcessorImplE());
		try { System.out.println(runner2.processAll());
		} catch(FailureImplE e) { System.out.println(e);
		}
	}
}

Submit "Generics - Exceptions" to Facebook Submit "Generics - Exceptions" to Digg Submit "Generics - Exceptions" to del.icio.us Submit "Generics - Exceptions" to StumbleUpon Submit "Generics - Exceptions" to Google

Comments