java:例外発生後に例外のメッセージを書き変える

例外オブジェクトにはメッセージが格納されており、getMessage()メソッドでそのメッセージを取得することができます。
しかし、このメッセージはコンストラクタでのみ設定可能であり、メッセージを後で変更するメソッドは用意されていないため、例外クラスに用意されている手段では例外発生後にメッセージを書き変えることはできません。

しかし、リフレクションを使用することで、メッセージを後で書き変えることが可能です。
メッセージはThrowableクラスのprivateのクラス変数”detailMessage”に保持されるため、これをリフレクションで書き変えます。

サンプルコードは以下の通りです。

【サンプルコード】

・ExceptionTest.java

【実行結果】

・コンソール(標準出力)

・コンソール(標準エラー出力)


ちなみに、リフレクション時に発生してしまう標準エラー出力ですが、(試していませんが)Java8では出ないようです。
筆者の環境(Java10)だと出てしまいます。

そこで以下の2つの手段を試しましたが、何れもエラー抑止はできませんでした。

1.JVM引数で抑止

“–illegal-access=deny”を指定したら逆に異常終了するようになってしまいました。

2.標準エラー出力の出力ストリームを変更

通常、”System.setErr(自作PrintStreamオブジェクト);”を記述することで標準エラー出力の出力先を変更し、コンソールに出力されないようにすることができるのですが、今回のケースではそれができませんでした。
“System.err.close();”を記述した場合はコンソールへの出力を抑止することができたので、リフレクション時のWARNINGメッセージでは”System.err”を直接使用しているのではないかと思います。
なお、”System.err”はクローズしたらリオープンすることができないので、”System.err.close();”を実行してしまうと、以降は予期せぬ例外等が発生しても標準エラー出力として出力できなくなってしまいます。
(”System.err.close();”を実行した後に”System.setErr(System.out);”を実行して、予期せぬ例外等も全て標準出力として出力することならできますが…)


いかがでしたでしょうか。

今回の記事では、例外発生時のメッセージを後から書き変えられることを確認しましたが、標準エラー出力が出力されることを考えると、このようなソースコードはできる限り書くべきではないと思います。
どうしても書き変え可能な変数を伝播させたいのであれば、独自例外クラスに独自のクラス変数を定義してそれを伝播させる等の工夫をするべきだと思います。

java:例外を先に生成して後でthrowする

通常のjavaのソースコードでは、例外を発生させると同時にthrowしていると思います。
しかし、例外クラスもクラスの一つであり、newするとオブジェクトが生成されますので、先に例外クラスのオブジェクトを生成し、オブジェクトとしてやりとりした後、後でthrowすることが可能です。

以下、サンプルコードです。
FileNotFoundExceptionを生成した後にIOExceptionを生成・上書きし、IOExceptionを返すというサンプルコードです。

【サンプルコード】

・ExceptionTest.java

【実行結果】


いかがでしたでしょうか。

今回の記事では、先に例外クラスのオブジェクトを生成して後でthrowできることを確認しました。
しかし、通常、後でthrowするようなソースコードは書かないと思います。
少なくとも、今回のような例では、フラグ変数でどの例外を返すかの情報を保持し、後で例外オブジェクトを1回だけ生成するべきです(オブジェクトの生成にはリソースが必要なため)。

実務の中で後からthrowしたいという話が出たので、そもそもできるのかというのを確認したのですが、できたとしてもトリッキーな印象は否めないので、このようなソースコードを書くことには慎重になった方が良いと思います。

Vue.jsに出てくるコロン(v-bind)とアットマーク(v-on)について

Vue.jsのコードに時折コロン(:)やアットマーク(@)が出てきて戸惑う人がいるかもしれませんが、これは省略記法です。
それぞれ、v-bind、v-onを指しています。

Vueオブジェクトの変数や関数をHTML側から参照するために、v-bindやv-onを使用します。

以下、サンプルコードです。

【サンプルコード(v-bind)】

【実行結果(v-bind)】

以下のように、Vueオブジェクトの変数の値とHTMLを結びつけることができます。

【サンプルコード(v-on)】

【実行結果(v-on)】

以下のように、Vueオブジェクトの関数を呼び出すことができます。
これは、ボタン1とボタン2の両方で同じ動きになります。


いかがでしたでしょうか。

省略記法は公式チュートリアルにて説明されていますが、忘れた時に実務で出くわすと戸惑うと思います。
“:”は”v-bind”、”@”は”v-on”、というのは覚えておくと良いでしょう。

JavaScriptのasync・awaitのサンプルコード

JavaScriptでは、通常は非同期処理となり、重い関数が終わるまで待つということをせず、次の関数に先に制御が移ってしまいます。
そのため、API呼び出しやIO(ファイルの読み書きやDBの読み書き)を伴う関数を呼び出した後に、その結果を元に次の処理を行う、というフローを行うためには一工夫必要です。

これを簡単に書くために、JavaScriptにはasync/awaitという文法が用意されています。
この記事では、非同期処理のサンプルコードと、async/awaitを用いて同期処理にするサンプルコードを用意しているので、そのサンプルコードを読めば使い方は理解できると思います。

async/awaitを使う上での注意点として、promiseやresolveとセットで使う必要があるという点があります。
これをセットで使用しないと、同期処理にならない、待った後の処理が実行できない、等のバグになります。
async/awaitはpromiseオブジェクトを簡単に扱うための文法でもあるので、promiseについては別途Webで調べるとより理解が深まると思います。

【サンプルコード(非同期処理)】

【処理結果(非同期処理)】

【サンプルコード(同期処理)】

【処理結果(同期処理)】


いかがでしたでしょうか。

JavaScriptのフレームワークを使いこなすには、まずJavaScript自体のことについて知る必要があります。
JavaScriptでは意識してコードを書かないと非同期処理になってしまうので、ここは意外と落とし穴になるのではないかと思っています。

Chromeの拡張機能を使用した文字列置換

以前の記事で、URLからJavaScriptを読みこむことでブラウザに表示される文字の変換を試みました。
しかし、URLから読み込ませる方法だと、大量の文字列置換はできません。

そこで、今回はChromeの拡張機能を使用した文字列置換を試みました。
以下、サンプルコードです。

manifest.jsonは、「https://developer.mozilla.org/ja/docs/Web/JavaScript」にアクセスした際に「content.js」が実行される記述としています。
最小限の記述であるため、実際に配布する際には説明を入れたりアイコンをつけたりすると良いでしょう。

【構成】

【サンプルコード】

・manifest.json

・content.js

【動作確認】

1.Chromeを開き、下記から「拡張機能の管理」を選択

2.「デベロッパーモード」をONにし、「パッケージ化されていない拡張機能を読み込む」を選択

3.サンプルコードが存在するフォルダを選択

4.manifest.jsonに記述したサイトにアクセスすると、自動で文字列置換が行われる

5.取り込んだ拡張機能の削除は、「Chromeから削除」を選択することで行う


いかがでしたでしょうか?

今回は文字列置換を例として挙げましたが、他にも、リンクの埋め込み、広告の削除、といったことが可能です。
Chromeの拡張機能は既に色々な機能が公開されていますので、どのようなことができるのかを既存の拡張機能を見て調べても良いかもしれません。