Java Abuse – Ternary Try/Catch

We often discuss Java limitations on IRC and try to come up with (sometimes silly) workarounds. Unfortunately after time passes it’s often easy to forget the outcome, and lose code snippets. So I thought I’d start blogging some of them so I don’t lose them, and other people might suggest other ways of doing things that we’ve overlooked.

This particular problem occurs when you want to assign the result of a method that can throw an exception to a final variable. For example:

final Customer c;
try
{
	c = getCustomer(id);
} catch (CustomerNotFoundException e)
{
	c = createNewCustomer();
}

This will fail to compile with “variable c might already have been assigned”. Of course making c not final would solve the problem, but that’s no fun.

If we were not using Exceptions, Java provides a useful ternary operator “?:” that lets us do things like:

final Customer c = customerExists(id) ? getCustomer(id) : createNewCustomer();

Which is nice and clean, but means that getCustomer is going to have to return null or throw a RuntimeException in the case that there is no matching customer, which is undesirable. Also customerExists() may be expensive.

We could also possibly use something along the lines of

final Option<Customer> c = getCustomer();

Both of these alternatives, however, require changing the API you’re consuming, and avoiding Exceptions. It would be nice if there was an equivalent of “?:” for try/catch so that you could assign the result to a final variable. The best I can manage in Java is below, can anyone do better?

import java.lang.reflect.ParameterizedType;
 
abstract class TryCatch<T, U extends Exception>
{
	public T value()
	{
		try
		{
			return Try();
		} catch (Exception e)
		{
			if (getTypeOfU().isAssignableFrom(e.getClass()))
			{
				return Catch();
			} else
			{
				throw new RuntimeException(e);
			}
		}
	}
 
	@SuppressWarnings("unchecked")
	private Class<U> getTypeOfU()
	{
		return (Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
	}
 
	public abstract T Try() throws U;
 
	public abstract T Catch();
}
 
//Example
public class Main
{
	private static CustomerRepo repo = new CustomerRepo();
 
	public static void main(String[] args) 
	{
		final Customer c = new TryCatch<Customer, CustomerNotFoundException>()
		{
			public Customer Try() throws CustomerNotFoundException
			{
				System.out.println("in try");
				return repo.getCustomer(1);
			}
 
			public Customer Catch()
			{
				System.out.println("in catch");
				return repo.createCustomer();
			}
		}.value();
	}
 
}
 
class CustomerRepo
{
 
	public Customer getCustomer(int id) throws CustomerNotFoundException
	{
		throw new CustomerNotFoundException();
	}
 
	public Customer createCustomer()
	{
		return new Customer();
	}
}
 
class Customer
{
}
 
class CustomerNotFoundException extends Exception
{
}

In C# we don’t run into the same problem since readonly is much less useful than Java’s final. However, if we wanted to try/catch at the same time we can do a bit better. Here’s an alternative in C#:

using System;
 
public class Example
{
	public static void Main()
	{
		Example t = new Example();
		t.Foo();
	}
 
	public void Foo()
	{
		String result1 = this.Try(() => GetBar(true)).Catch<BarException>(() => "Caught a BarException");
		String result2 = this.Try(() => GetBar(false)).Catch<BarException>(() => "Caught a BarException");
		Console.WriteLine(result1);
		Console.WriteLine(result2);
	}
 
	public String GetBar(bool succeed)
	{
		if (succeed)
			return "Success!";
		else
			throw new BarException();
	}
}
 
public class BarException : Exception {}
 
public class Tryer<TResult>
{
	private readonly Func<TResult> toTry;
	internal Tryer(Func<TResult> toTry)
	{
		this.toTry = toTry;
	}
 
	public TResult Catch<TException>(Func<TResult> whenCaught)
		where TException : Exception
	{
		try
		{
			return toTry();
		} catch (TException)
		{
			return whenCaught();
		}
	}
}
 
namespace System
{
	public static class ProvidesTry
	{
		public static Tryer<TResult> Try<T,TResult>(this T other, Func<TResult> toTry)
		{
			return new Tryer<TResult>(toTry);
		} 
	}
}
This entry was posted in Java, Uncategorized and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

22 Comments

  1. mullet
    Posted June 14, 2009 at 5:21 pm | Permalink

    My initial thought was – why not just take the simplest route and assign to a non-final variable, then re-assign that to a final behaviour? Of course that leaks state, and so is an unacceptable solution. Consequently I am inclined to consider the following:

    final Customer c = new Object() {
    Customer value; {
    try {
    value = repo.getCustomer(1);
    } catch (CustomerNotFoundException e) {
    value = repo.createCustomer();
    }
    }}.value;

    Essentially we simply hide the temporary variable \’value\’ by wrapping it up in an object. I\’m not that its a better solution to your, but I offer it as an alternative.

    Advantages:
    1. Simpler for the person who coded it to understand, since it looks more like a normal try/catch block.
    2. If the \’getCustomer\’ method throws a RuntimeException then you will simply get it straight away, where as it gets wrapped in another RuntimeException with your solution.
    3. No requirement for reflection hacks, that have potentially negative performance impact, and would require more knowledge on behalf of the reader.
    4. Easier to Extend – chaining TryCatch instances would result in some pretty horrific nested inner class declarations, though I suppose one could build a TryCatch2, TryCatch3 etc. and abstract some of the mess a bit. In my solution you simply add another catch block.

    Disadvantages:
    1. Your approach encourages better code reuse, since you have built a generic try/catch abstraction, rather than requiring a one-off construct.
    2. Uncertain where to place the braces. My placement of braces above would break the code style guidelines in many projects, but reflects my intuition that \’value\’ is really part of the method, and being wrapped in an object is simply there to hide the state. Which is correct is really up to you.
    3. Anonymous Constructors look weird in Java.
    4. The introduction of temporary state is still a crime against humanity, even if it is cleanly abstracted.

  2. Paczesiowa
    Posted June 15, 2009 at 7:40 am | Permalink

    public class Test {

    public static void main(String[] args) {
    final CustomerRepo r = new CustomerRepo();
    final Customer c = getCustomer2(r, 1337);
    }

    public static Customer getCustomer2(CustomerRepo r, int id) {
    try {
    return r.getCustomer(id);
    } catch (CustomerNotFoundException e) {
    return r.createCustomer();
    }
    }
    }

    you could also create that method in anonymous class like mullet wrote, but you wouldn\’t have to create non-final variables.

  3. robermann79
    Posted June 15, 2009 at 11:18 am | Permalink

    Why do you have necessity to keep “final” that pointer? How are you going to use it?
    Not knowing your real purpose, here’s my way:
    String temp;
    try{
    temp = “ok”;
    }catch(Throwable t){
    temp = “ko”;
    }
    final String def = temp;
    //Then, if you wish:
    temp = null;

  4. Posted August 16, 2010 at 3:51 am | Permalink

    Classic exposition, I have also mentioned it in my blog article. But it is a pity that almost no frienddiscussed it with me. I am very happy to see your article.

  5. Posted August 27, 2010 at 10:13 am | Permalink

    final Customer c = new Object() {
    Customer value; {
    try {
    value = repo.getCustomer(1);
    } catch (CustomerNotFoundException e) {
    value = repo.createCustomer();
    }
    }}.value;

  6. Posted September 8, 2010 at 1:33 pm | Permalink

    I have also mentioned it in my blog article. But it is a pity that almost no frienddiscussed it with me. I am very happy to see your article.

  7. Posted October 15, 2010 at 10:33 am | Permalink

    Manolo Blahnik design inspiration comes from the movie, master loves female star and the places etc. Manolo Blahnik is worth mentioning, love to his favorite star names for his shoes, even after Jessica shoes have even, The model has Evangelista\’m carp leather shoes.

  8. Posted October 15, 2010 at 10:36 am | Permalink

    Ed Hardy (Ed) often use embroidery, paints and splash-ink skill, builds a decadent and mi li, combine the Tattoo in written by master, tiger, camellia skeleton, devil, daggers and naked female Tattoo pattern etc, creating a series of tide of fashion.

  9. Posted October 15, 2010 at 10:38 am | Permalink

    Fashion ring for bags of this “golden accessories” and would never think there is any slight concerns. In the just-concluded Fashion Week 2010 spring and summer, individual enthusiasm for the brand to continue to build ultra-high T’s arms this stage the “perfect supporting role.” With the development of young fashion, coach handbags were also glow with boundless energy, from the color to reveal the lovely appearance and lively, beautiful pink, peach, or the Department of tassels sway and movement as the infinite and customs, are very deeply fascinated.

  10. Posted October 15, 2010 at 10:40 am | Permalink

    For each Master is concerned.Authentic coach is not just a brand name, but also the crystallization of their efforts and commitment of transmission.Coach Signature handbags have to meet todays modern woman. Brand new coach sling bag with a still attached tag inside it. Buyers are welcome to bring it to our Coach stores to check its authenticity. We Sell,We Care.All Customers Are Always in Our Hearts!

  11. Posted October 15, 2010 at 10:42 am | Permalink

    MBT Shoes looks weird, but it does not mean they are not have a fashion functions. They definitely don’t look like a new style from adidas or Nike, but thanks to more recent attention to design, many of the styles have changed. More and more people would like to choose them. Specially, in the cold winter, people’s physical become weakness than before. It is necessary for us to protect our bodies.

  12. Posted January 6, 2011 at 8:50 am | Permalink

    Hermes brand image based on the consistent high-grade, high quality principles and unique style of French easily, and based on this, this is in popular factor product ever attractive reasons. Keep classics and high quality, first-class craft manufacture, durable practical performance and concise and elegant exquisite photograph union, Hermes not but identity and status symbols, but also reputed to make you life never out of fashion thing.

  13. Posted August 13, 2011 at 7:48 am | Permalink

    I want to bring out the secrets of nature and apply them for the happiness of man . I don“t know of any better service to offer for the short time we are in the world .(Thomas Edison , American inventor)

  14. Posted October 5, 2011 at 3:49 pm | Permalink

    Moncler down jackets brand in major cities across the country rely on queued snapped up, in the consumption obtained MONCLER website actions spread awareness, better reputation, is any civil documents and even advertising 。Womens Jackets ing the color red orange with so natural and comfortable, people swept away in the winsorld have well understood the seasonal needs and so have designed the wears whic.Moncler Kids h can keep a person warm during the freezing iciness. You would not only stay warm but also will look up to date and trendy.<a href=\

  15. Posted January 27, 2012 at 12:14 am | Permalink

    Bought for myself last week, Xerox -canon mf 4430, cartridge ran out and what to do now ?
    I called in different organizations , they said they could not help , we should only buy a new cartridge !
    Only found here – inexpensive compatible toner cartridge canon mf 4430.
    They can buy the cartridge canon mf 4430 factory quality !
    I bought a cartridge canon mf 4430, Quality is very happy !

  16. Posted January 28, 2012 at 12:33 am | Permalink

    Купила себе ксерокс – samsung CLP 315
    , картридж кончился и что теперь делать?
    Посоветуйте, может кто сталкивался с samsung?
    Картридж такой дорогой! Где подешевле найти картридж для
    Случайно купила здесь: заправка картриджей samsung CLP 315

  17. Posted January 28, 2012 at 5:27 pm | Permalink

    Купила себе принтер – samsung scx 4623F
    , картридж кончился и что теперь делать?
    Посоветуйте, может кто сталкивался с samsung?
    Картридж такой дорогой! Где подешевле найти картридж для
    Только здесь: заправка копира samsung scx 4623F

  18. Posted January 30, 2012 at 12:46 am | Permalink

    get chanel italy and get big save

  19. Posted February 1, 2012 at 8:23 pm | Permalink

    benjiweber.co.uk is well designed
    hair loss treatment

  20. Posted February 2, 2012 at 8:26 am | Permalink

    you definitely love new prada prada saffiano for more detail to get new coupon

  21. Posted February 5, 2012 at 9:03 pm | Permalink

    bugG6R pchbaiqnqmxp, [url=http://ejnesuctzapo.com/]ejnesuctzapo[/url], [link=http://pdnazgbroqju.com/]pdnazgbroqju[/link], http://drxpbzllgfxp.com/

  22. Posted February 6, 2012 at 3:09 am | Permalink

    comment3, brand viagra online, 70712, pfizer viagra online, yjh, viagra soft|viagra soft tabs|buy viagra soft tabs, =-OO,

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*