aboutsummaryrefslogtreecommitdiff
path: root/website/features/SneakyThrows.html
blob: ec7d09c5b901bda0dcbb2c1330bfed2ae849639e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<!DOCTYPE html>
<html><head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<link rel="stylesheet" type="text/css" href="../logi/reset.css" />
	<link rel="stylesheet" type="text/css" href="features.css" />
	<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
	<meta name="description" content="Spice up your java" />
	<title>@SneakyThrows</title>
</head><body><div id="pepper">
	<div class="minimumHeight"></div>
	<div class="meat">
		<div class="header"><a href="../index.html">Project Lombok</a></div>
		<h1>@SneakyThrows</h1>
		<div class="byline">To boldly throw checked exceptions where no one has thrown them before!</div>
		<div class="overview">
			<h3>Overview</h3>
			<p>
			<code>@SneakyThrows</code> can be used to sneakily throw checked exceptions without actually declaring this in your method's <code>throws</code>
			clause. This somewhat contentious ability should be used carefully, of course. The code generated by lombok will not ignore, wrap, replace,
			or otherwise modify the thrown checked exception; it simply fakes out the compiler. On the JVM (class file) level, all exceptions, checked or not,
			can be thrown regardless of the <code>throws</code> clause of your methods, which is why this works.
			</p><p>
			<em><strong>CAREFUL: </strong></em>Unlike other lombok transformations, you need to put <strong>lombok.jar</strong> on your classpath when
			you run your program.
			</p><p>
			Common use cases for when you want to opt out of the checked exception mechanism center around 2 situations:<br /><ul>
			<li>A needlessly strict interface, such as <code>Runnable</code> - whatever exception propagates out of your <code>run()</code> method,
				checked or not, it will be passed to the <code>Thread</code>'s unhandled exception handler. Catching a checked exception and wrapping it
				in some sort of <code>RuntimeException</code> is only obscuring the real cause of the issue.</li>
			<li>An 'impossible' exception. For example, <code>new String(someByteArray, "UTF-8");</code> declares that it can throw an
				<code>UnsupportedEncodingException</code> but according to the JVM specification, UTF-8 <em>must</em> always be available. An
				<code>UnsupportedEncodingException</code> here is about as likely as a <code>ClassNotFoundError</code> when you use a String object,
				and you don't catch those either!</li></ul>
			</p><p>
			Be aware that it is <em>impossible</em> to catch sneakily thrown checked types directly, as javac will not let you write a catch block
			for an exception type that no method call in the try body declares as thrown. This problem is not relevant in either of the use cases listed
			above, so let this serve as a warning that you should not use the <code>@SneakyThrows</code> mechanism without some deliberation!
			</p><p>
			You can pass any number of exceptions to the <code>@SneakyThrows</code> annotation. If you pass no exceptions, you may throw any
			exception sneakily.
		</div>
		<div class="snippets">
			<div class="pre">
				<h3>With Lombok</h3>
				<div class="snippet">@HTML_PRE@</div>
			</div>
			<div class="sep"></div>
			<div class="post">
				<h3>Vanilla Java</h3>
				<div class="snippet">@HTML_POST@</div>
			</div>
		</div>
		<div style="clear: left;"></div>
		<div class="overview">
			<h3>Small print</h3><div class="smallprint">
				<p>
				<code>@SneakyThrows</code> is an implementation of this feature request: <a href="http://bugs.sun.com/view_bug.do?bug_id=6534270">http://bugs.sun.com/view_bug.do?bug_id=6534270</a>.
				</p><p>
				Because <code>@SneakyThrows</code> is an implementation detail and not part of your method signature, it is an error if you try to
				declare a checked exception as sneakily thrown when you don't call any methods that throw this exception. (Doing so is perfectly legal
				for <code>throws</code> statements to accomodate subclasses). Similarly, <code>@SneakyThrows</code> does not inherit.
				</p><p>
				For the nay-sayers in the crowd: Out of the box, Eclipse will offer a 'quick-fix' for uncaught exceptions that wraps the offending
				statement in a try/catch block with just <code>e.printStackTrace()</code> in the catch block. This is so spectacularly non-productive
				compared to just sneakily throwing the exception onwards, that Roel and Reinier feel more than justified in claiming that the
				checked exception system is far from perfect, and thus an opt-out mechanism is warranted.
				</p><p>
				Currently usage of <code>@SneakyThrows</code> requires you to have <code>lombok.jar</code> in the classpath at runtime. However, in the future
				we will attempt to eliminate this requirement - when we figure out how we can do that. If anyone has a good idea on how to make that happen, let us know!
				</p>
			</div>
		</div>
		<div class="footer">
			<a href="index.html">Back to features</a> | <a href="Synchronized.html">Previous feature (@Synchronized)</a> | <span class="disabled">Next feature</span><br />
			<a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009 Reinier Zwitserloot and Roel Spilker, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
		</div>
		<div style="clear: both;"></div>
	</div>
</div>
<script type="text/javascript">
	var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
	document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
	try {
		var pageTracker = _gat._getTracker("UA-9884254-1");
		pageTracker._trackPageview();
	} catch(err) {}
</script>
</body></html>