<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shadow &#38; Honnix &#187; apply</title>
	<atom:link href="http://honnix.com/blog/archives/tag/apply/feed" rel="self" type="application/rss+xml" />
	<link>http://honnix.com/blog</link>
	<description>she&#039;s growing up</description>
	<lastBuildDate>Sun, 15 Jan 2012 10:44:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>我是如何用Scala定义新异常类型的</title>
		<link>http://honnix.com/blog/archives/412</link>
		<comments>http://honnix.com/blog/archives/412#comments</comments>
		<pubDate>Sun, 09 Aug 2009 02:41:30 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[Exception]]></category>
		<category><![CDATA[extends]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[override]]></category>
		<category><![CDATA[trait]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=412</guid>
		<description><![CDATA[Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。 例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。 1 2 3 4 5 class MyException&#40;message: String, cause: Throwable&#41; extends Exception&#40;message, cause&#41; &#123; def this&#40;message: String&#41;: = this&#40;message, null&#41; def this&#40;cause: Throwable&#41;: = this&#40;null, cause&#41; def this: = this&#40;null, null&#41; &#125; 当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。 所以我就想出了下面的怪招。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19&#8230;]]></description>
			<content:encoded><![CDATA[<p>Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。</p>
<p>例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。</p>

<div class="wp_codebox"><table><tr id="p4123"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p412code3"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> MyException<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, cause<span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。<br />
所以我就想出了下面的怪招。</p>

<div class="wp_codebox"><table><tr id="p4124"><td class="line_numbers"><pre>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
</pre></td><td class="code" id="p412code4"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> SpcException <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException4<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
<span style="color: #F78811;">&#125;</span>
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">trait</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException4 <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException</pre></td></tr></table></div>

<p>基本思想是定义一个trait，然后定义四种异常，每种都从该trait扩展并提供不同的默认构造方法，同时定义一个singleton，提供四种不同的apply方法用来构造四种不同的异常。这样就可以解决之前的问题，虽然不怎么好看。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/412/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

