Javaセキュアコーディングスタンダードを読んでいて、Class.newInstance()は使うべきではないことを知りました。
理由は、チェック例外を宣言なしに送出できてしまうからのようです。もちろん、チェック例外をthrows宣言なしに送出できるわけで、コンパイラでもチェックすることはできません。
気になってJavaDoc見てみたらちゃんと注意点として書かれてますね。ぶっちゃけ、何年もJava書いてきたけど知りませんでした・・・。
http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance()
簡単なコードを書いて、Class.newInstance()とConstructor.newInstanceで動作の違いを確認してみました。
Class.newInstance()
上のコードを実行すると、以下のスタックトレースが出力されます。
invokeは、throws宣言がないにもかかわらずIOExceptionが呼び出し元に送出されていることがわかります。
Exception in thread "main" java.io.IOException at NewInstanceInClass.<init>(NewInstanceInClass.java:7) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:525) at java.lang.Class.newInstance0(Class.java:372) at java.lang.Class.newInstance(Class.java:325) at NewInstanceInClass.invoke(NewInstanceInClass.java:18) at NewInstanceInClass.main(NewInstanceInClass.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Constructor.newInstance()
上のコードを実行すると、チェック例外のIOExceptionがInvocationTargetExceptionでラップされて送出されていることがわかります。
InvocationTargetExceptionは、チェック例外で必ずキャッチ(throws)しないといけないので、コンパイル時に安全にチェックできるわけです。
java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:525) at NewInstanceInConstructor.invoke(NewInstanceInConstructor.java:20) at NewInstanceInConstructor.main(NewInstanceInConstructor.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: java.io.IOException at NewInstanceInConstructor.<init>(NewInstanceInConstructor.java:9) ... 11 more
Javaセキュアコーディングスタンダード CERT/ Oracle版
posted with amazlet at 12.05.15
Fred Long Dhruv Mohindra Robert C. Seacord Dean F. Sutherland David Svoboda
アスキー・メディアワークス
売り上げランキング: 364986
アスキー・メディアワークス
売り上げランキング: 364986