2012-01-01から1年間の記事一覧

ジェネリックな数値キャスト(プリミティブ拡大変換、縮小変換)

概要 今日は、ジェネリックな数値キャストをします。 やりたいこと プリミティブ型の数値キャスト(プリミティブ拡大変換、縮小変換)と呼ばれる演算があります。 たとえば、double型をshort型に変換する場合 short s = (short)3.0;これをジェネリックにするに…

ボクシングする方法あれこれ

動機 プリミティブ型の式(たとえば数値リテラル)はオブジェクトではないので、メソッドを呼び出すことはできません。 // コンパイルエラー 100.intValue(); そこで簡単な式でボクシング変換を起こす方法をいくつか紹介します。 たとえばメソッドチェイン中で…

短そうな方法でラッパー型とプリミティブ型の相互変換

概要 今日は、ラッパー型のClassオブジェクトとプリミティブ型のClassオブジェクトを相互に変換してみます。 ラッパー→プリミティブ staticフィールドであるInteger.TYPE はint.classを返します。 他のラッパークラスにも同名のフィールドがあるので、リフレ…

変数のデフォルト値(主にプリミティブの)取得の抽象化

概要 Classオブジェクト(特にプリミティブ型)から、変数のデフォルト値を取得する。 前提 static変数、インスタンス変数、配列の要素はデフォルト値で初期化されます。 Each class variable, instance variable, or array component is initialized with a d…

クレイジーなfinallyをどうにかしたい

概要 finallyのネストをフラットにする。 動機 以下の理由で、finallyの中でtry-catch-finallyを書かなくてはならないことがあります。 finally ブロックの中で呼び出されるメソッドは例外をスローすることがある。そのような例外をキャッチして処理しないと…

アンボクシングのち拡大変換

変数に値を代入する際に、アンボクシング→プリミティブ拡大変換は起こる*1が プリミティブ拡大変換→ボクシングは起こらないので、 intはLongになるがIntegerはlongにならない。 @SuppressWarnings("unused") public static void main(final String[] args) {…

1文で2種類の例外をスローする

メソッドの引数を検査する時など、何種類かの例外を投げ分けたい場合があります。 これはなるべく短くしたいですね。そこで1文で書いてみましょう。 package test; public class Throw2Test { @SuppressWarnings("serial") static class HogeException exten…

仮型引数に実型引数を「渡す」と何が起こるか

概要 ジェネリッククラス/インターフェースに実型引数を与えた際のメンバの型の仕様 http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.5.2 の勉強。よく分かっていない 本文 仮型引数に実型引数を「渡す」ことはinvocationでした。→ 実型…

キャストなしでスーパークラス型のthis参照を表す式

概要 super参照っぽいものを作ります。 前提 thisは参照を表す式として使えますが、superは参照を表す式として使えません。 // thisは参照 System.out.println(this); // コンパイルエラー。superは参照ではない // System.out.println(super); 隠蔽と式の型…

左辺で分岐しよう

フィールド代入の際に、代入の対象となるフィールドを持っているオブジェクトは 条件式 (conditional expression) 等*1を使えば分岐できる。 これと、例外スローを式にするテクニック 実行時例外スローを式に を使って左辺でnon-nullアサーションができるよ…

fieldにfieldが代入できないぜぇ ワイルドカードだろ〜?

概要 wild.field に wild.fieldが代入できなくなる やり方 型変数TをもつクラスCを用意します。 CはT型のフィールドfieldをもちます。 C型の変数wildを用意すると、wild.fieldにはwild.fieldが代入できません package test; public class CaptureConversionT…

null typeって何

概要 null typeをちゃんと読む 仕様 Java言語仕様にはnull typeがあります。 There is also a special null type, the type of the expression null (§3.10.7, §15.8.1), which has no name. http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#j…

intersection typeと型変数のupper bound

言語仕様にintersection typeは型変数のupper boundと似ているが、違うと書いてあるのでメモ。 型変数のupper boundはintersection typeをもたらすが、intersection typeの方がより広いものを含むということらしい。 An intersection type takes the form T1…

実行時例外スローを式に

Javaのthrow文は文なので、使い勝手が悪いことがあります。 そこで、式にしてみます。(検査例外は面倒なので実行時例外限定) やり方 実行時例外を引数にとり、それをスローするだけのpublic staticメソッドを用意します。 どの文脈でも使えるように戻り値型…

実型引数を仮型引数に「渡す」

先日のエントリー 仮型引数と実型引数の混同に関する考察 で仮型引数 (type parameter) と実型引数 (type argument) の話をしました。 では、実型引数を仮型引数に「渡す」ことは仕様では何と呼ぶのでしょうか。 The type argument list denotes a particula…

仮型引数と実型引数の混同に関する考察

Javaジェネリクス初心者は と Hoge>の違いが分からない! とよく混乱します。前者はtype parameter*1として、後者はtype argumentとして使われる表現で、出てくる文脈が違うものです。では、なぜこの2つは混同されるのでしょうか? 一つの原因はどちらも<>と…

見えなくても型はついている

private(package private、protectedでも可能)メンバクラスをそれよりも可視性の高いアクセス修飾子をもつメソッドの戻り値型や引数型にすると、使う側で「何だこの型は?」という不思議なメソッド*1になる。簡単な実験で、スーパークラスやインターフェース…

upper boundを上限境界と訳すのが心苦しい

upper bound, lower boundは順序集合の文脈で「上界」「下界」と訳されます。 参考: Wikipedia http://ja.wikipedia.org/wiki/%E9%A0%86%E5%BA%8F%E9%9B%86%E5%90%88 ところがJavaの型の文脈では「上限(境界)」「下限(境界)」と訳されます。 参考: TypeVaria…

ジェネリックコンストラクタの使いどころ

メソッドと同じく、コントストラクタをジェネリックにする(型パラメータをとる)ことができる。 ところがコンストラクタの型パラメータの使い途がよく分からない。参考: コンストラクタジェネリック - カタヤマンがプログラマチックに今日もコードアシスト En…

Eclipseで見えるワイルドカード配列

概要 Eclipseでは、メソッド呼び出しの式の型が見える。 そこでは、ワイルドカード配列らしきものが見える。 package test; public class WildcardTest { // 型パラメータT static class C<T> { public T getT() { return null; } public T[] getTArray() { ret</t>…

リフレクションでのローカルクラスのコンストラクタ引数

ローカルクラスは定義されたメソッド*1のローカル変数を参照することができる。 バイトコード上どうなってるの?と知りたかったのでリフレクションで簡単に調査。 まとめ ローカルクラス*2のコンストラクタ引数の型は、リフレクションで見ると (non-static c…

ジェネリックmain

mainをジェネリックメソッドにしても問題なく実行できます。 以上。 package test; public class MainTest { private static interface Love {/**/} private static interface Peace {/**/} public static <T extends Love & Peace> void main(final String[] args) { System.out.pri</t>…

定数なしenumに抽象メソッド

定数なしenumに抽象メソッドを宣言するとコンパイルが通らなくなる。 どうやら抽象メソッドを宣言するだけではenumは抽象クラスにならないらしい。 package test; import java.lang.reflect.Modifier; public class EnumAbstractTest { private enum E1 { //…

ワイルドカード + 内部クラス + 無名クラス拡張 = ?

型パラメータつきのクラスに定義された内部クラスを、 型パラメータがワイルドカードの変数で参照されるインスタンスをエンクロージングインスタンスとして、 無名クラスで拡張すると、 Class.getGenericSuperClass() がGenericSignatureFormatErrorで落ちる…

ParameterizedType実装クラスのtoStringおかしくない?

staticネストクラスを含むParameterizedType(インターフェースなので実装があるはず)を取得すると、toString()がよくわからない文字列になる。 読み方がわかる方、教えてください。 package test; import java.lang.reflect.ParameterizedType; public class…

要素型から配列型を取得

要素型から配列型を取得したい。 Array.newInstanceで配列を生成してgetClassで取得できる。 package test; import java.lang.reflect.Array; public class GetArrayTypeTest { @SuppressWarnings("unchecked") public static <T> Class<T[]> getArrayType(final Cla</t[]></t>…

リフレクションでのEnum継承クラスのコンストラクタ

enumキーワードで宣言されるEnum継承クラス(ここではE)のコンストラクタは、リフレクションで調べると… package test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class EnumConstructorTest { pri…

共変戻り値型に使えるワイルドカード

clone()の戻り値型は、共変戻り値型 (covariant return type) が使えることを利用して、定義されたクラスの型にするのがよいとされている。参考: http://www.ne.jp/asahi/hishidama/home/tech/java/clone.html#h2_covariantでは、コピーをリストで複数返した…

void配列はありません

Javaでよく遊んでいるのでメモ。 void.classが取れるならvoid[].classも取れるのでは?と思ったが取れなかった。 リフレクションでもvoid配列は作れなかった。 package test; import java.lang.reflect.Array; public class VoidArrayTest { public static v…