投稿

2008の投稿を表示しています

Javaのクロージャをいじってみた。(8)

何か、closureの引数でワイルドカード使うとエラーになる。 詳しく調べてないけど、以下のコードはエラーになった。 (BGGA 2008-08-11版のclosure.jarでやってエラーになった)  // × コンパイルエラー  // "? supre T"の周辺で6つぐらいエラーが出る。  public Integer calc({? super T,Integer} func) {   // ありゃエラーになる。  }  // ○ コンパイル/実行可能  public Integer calc(Function<? super T,Integer> func) {   // これはOK  } んー これは何か理由あっての制限なのかな。 それともこのバージョンは未完のためエラーになってしまうのかな。 英語だからってBGGAのページのドキュメントを読むのサボったから 見落としたのかな...。汗    

Java Genericsが難しい(5.1)

ジェネリクスと配列の組み合わせは相性が悪い。 という件は、2007年のJavaOneのセッション「Effective Java Reloaded: This Time It's Not for Real」で言ってるね。 ちゃんと読み直せばO'Reillyの「Java Generics and Collections」にも 書いてあるかも。    

Java Genericsが難しい(5)

ジェネリクスと配列の組み合わせは相性が悪い。 大抵のコードはエラーになる。色々調べたが、そういうものらしい。 それでも納得いかないコードもある。 ArrayList<string>[] = new ArrayList<string>[]; これもエラーになる。これはあんまりだと思う。 これはコンパイル通っていいんじゃない? 次のバージョンでコンパイル通るよう、直すべきだー。 そんなある日、ClassのAPI見てて気づいたのだけど、 Class#getClasses()の戻り値はClass<?>[]なのよ。 つまり、"ArrayList<string>[] ="の部分は問題ないと。 そこで思いついたのが、effective java second editionの手法や、 Google CollectionsのListsやMapsクラスの手法をちっと拡張した 生成用補助メソッド。 但し、ジェネリクスと配列の組み合わせでどうしてもワーニングが発生する。 そこはあきらめ、少なくとも@SuppressWarnings("unchecked")を書くコードと 書かないコードを切り分ける。 書かざるを得ないなら、コードに散在させず、まとめておく。 で作ったのがこれ。 // 定義側 public class ArrayUtils {   ;  @SuppressWarnings("unchecked")  private static <T> LinkedList<T>[] newLinkedListArray(int size) {   return new LinkedList[size];  }   ; } // 利用側 public class Main {   public static void main(String... args) {    ArrayList<Integer>[] temp = ArrayUtils.newArrayLists();    temp[1] = new ArrayList<Integer>();    temp[2] = new ArrayList<Integer>...

「日本語版Effective Java 第2版」のAmazon予約開始

訳者の柴田 芳樹氏のブログによると「日本語版Effective Java 第2版」が Amazonで予約可能になったようですね。 予約すべきか、Sun Tech Daysでやるかもしれない会場販売で買うべきか (オマケ期待)。 ううむ… あと、値段思ったより安いのね。ずいぶん厚くなったから4000円越えると 思ってた。 円高のおかげ?関係ねぇか。    

Arrays.asList()のジェネリクスの仕組み

以前、 ジェネリクスについて書いた とき、引数型に(T...)を利用するのは 相性悪いと書いた。 このときは、引数型(T...)を持つ、インタフェースを継承し利用したときを 例にした。 でも、JavaPlatformAPIの中にはArrays.asList(T... t)というメソッドもあった。 そこで、OpenJDKを開いてasList()のソースを調べてみた。 public static <T> List<T> asList(T... a) {   return new ArrayList<T>(a); } あれ?配列受け取る引数のコンストラクタなんてArrayList持ってたっけ? と思ったらArraysコード内で同名の実装クラスを持ってった。 おおう。 List<T>が戻り値なのでこれを満たせば十分と。 なるほど。 このクラスの中身を見たところ、ジェネリクス配列そのものを内部に持ち、 単純なラッパークラスでした。 ArrayList<T>の様なコンテナとしての利用はOKでComparator<T>みたな 継承前提インタフェースでの引数型に(T...)を利用するのはアウトということか? ふうむ... 余談ですが、Arrays.asList()の利用方法は、可変長引数からListクラスを 作るだけでなく、配列のラッパークラス生成の便利メソッドとしての 利用もよさそう。    

きました。

イメージ
RRoD。 これが出てやっと一人前の360ユーザー。   とはいえ、 来週、大規模アップデートあるのにこの時期はねーだろ。ヽ(`Д´)ノ ところでこの写真、HAL9000ぽく撮れてたんだけどかっこよくね?    

Javaのリフレクションの勉強

私はJavaの基本機能は一通りは理解していると思っていたのですが、 最近、理解していないことが沢山あることに気づきました。 とりあえず、理解不足が集中しているのがリフレクション・クラスロード関連・ あとシリアライズ関連。わんくま同盟の方のblogを見てまだまだ知らないことが 沢山有ることを知り猛省。 リフレクションについては、アノテーション関連で必須になるので理解して おかないとなあ。 インナークラスから、エンクロージングクラスの参照(this)取得する方法とか つい先日知ったよ! .thisだって! へー。   そんなレベル。        

JJUG CCC 2008 Fall行ってきた。

JJUG CCC 2008 Fall行ってきた。(いつの話だ...) がんばっている方々の姿を見てモチベーション上げようとか思ったのに 皆さんスゴすぎて、逆にベッコリへこんできました。 今回は論文発表のようなセッションが多く、実装ベースのものは 多くなかったような感覚がします。気のせい?以前に比べ普段着の人多かった ので学生なのかなあと。まあサラリーマンには平日はやっぱ厳しいですよね。 Hudsonの川口氏はviユーザー? サラッと利用したエディタがviだった。 他には、ペアプログラミングのライブするセッションではHHKとemacsの 組み合わせとかあったな。後でJJUGプレゼンされた方のblogを見て 回ったけど、中にはHHKをモバイルと一緒に持ち歩っている人もいるようで。 すげえ。昔あこがれたなあ。 あとHHKは意外とガチャガチャうるさいのね。以前会社の席の近い人に 言われたことがあるけど、人が打っているの見て初めてわかった。 たまたまマイクが近くだった音が大きかっただけだろうか? Scala 最後Scalaセッションは、マイブームど真ん中なので大変興味深かった ですね。挙手アンケートで多くの人が「触ったことがある」とのことで、 注目されている言語のようですね。俺も置いてきぼり食らわない よう勉強しないと。 ギーク 日本で一般にギークという単語が認知されたのは、「小飼弾氏のアルファ ギークに逢ってきた」という本あたりなのかしら。 なんだかギークという言葉の解釈に違和感を感じました。 私は 技術系オタ = ギークという感覚をもっています。 /. や engadget の出オチ記事を読んで面白いと思える人、ネタを作れる人が ギークというか...。 個人的には、ホリデープログラマ向けのネタ的プログラミング セッションもほしいなあと。 Androidのセッションはゲイナーとかあって、「作ってみた」的ネタが 期待できるんだけど、まだまだこれからみたい。 平日からそんなことしても人集まらないのかしら。あとスポンサーも。 そもそもJJUG等のイベントに対して、私の求めているもの自体が 間違っているのかな...。汗 ※1 LLと書くのとLL言語って書くのどちらがいいだろ?   LL言語の方が分かり易いと思うけど「Lightweight Language言語」   だもんなあ。I...

effective java 第2版の日本語訳

翻訳が完了したそうで。 英語版は持っていますが、英語がダメダメのメな私なので 読みこぼした部分も多いと思います。だから買いますよ。 「今年のSunTechDaysの会場で販売されるかも」とのことですが、 先行販売とかそういうわけではないのですかね? もしそうなら予算大目に用意して今年のSunTechDaysに 望まないといけないなあ。 あ、JJUGCrossCommunityConferenceも事前登録開始されてる。 申し込んでおこう...。

Javaのクロージャをいじってみた。(7)

unrestructured closureなるものが出てきた。キーワード==>とか。 このunrestructured closureの書きっぷり、Rubyのブロックっぽいな。 unrestructured closureを見てまずひらめくのは、多次元配列や コレクションのforeachメソッドかな。多次元でもひとつのforeach()で すべての要素をイテレーションする。 ↓こんな感じの。 //定義側 package xxxx; public class Matrix3 {   public int[][] elements;   public static void foreach(Matrix3 mat,                {int==>int} closure) {     int[] row = null;     int element = 0;     for (int i=0; i<elements.length; i++) {       for (int j=0; j<elements[i].length; j++) {         elements[i][j] = closure.invoke(elements[i][j]);       }     }   }   public Matrix3() {     elements = new int[3][3];     for (int i=0; i<elements.length; i++) {       for (int j=0; j<elements[i].length; j++) {         elements[i][j] = 0;       }     }   } } //利用側 import xxxx.Matrix3; import static xxxx.Matrix3.foreach;   ; void func() {   Matrix3 mat = new Matrix3();   foreach(int element : mat) {     element = 10;   } } というような感じ。 呼び出し側の記述は、":"の右側がforeach()の引数、左側は クロージャ==...

C++テンプレート宣言と定義

1.クラステンプレートを利用したクラスの書き方 C++テンプレートを利用したクラスを初めて書いてみた。 とろが、リンクでエラー。 いくつか存在するC++のサイトサンプルに従い作ったがうまくいかない。 色々調べた結果、以下のことがわかった。  ・クラステンプレートを利用したい場合、よくやるクラスメンバの   定義と異なりクラスメンバの定義もヘッダファイルに記述する   必要がある。(-->要はヘッダで完結しソースファイルを作らない)  ・externをつけるとソースファイル(.cpp)に書くことも可能らしい。   但し、externに対応しているコンパイラが多くないため、いい方法では   ないらしい。(VisualStudio2005はだめらしい) これは知らないとプログラムがビルドできない知識なのに、書いていない サイト(書籍)が結構ある。んーなんでだろ? とりあえず自分がリファレンスとして利用している 手元の書籍には書いて 無いっぽい。C++の言語仕様が複雑なため、網羅し切れていないケースも 少ないということなのか? Effective C++など有名な書籍を読めばそれくらいのこと書いてあるのかな。 例: // ★クラステンプレートの利用(ヘッダファイルで完結する必要がある) // .hppファイル template<int R, int C> class Matrix { public:  Matrix();  ~Matrix();  void func(); }; template<int R, int C> Matrix<R, C>::Matrix() { // コンストラクタ } template<int R, int C> Matrix<R, C>::~Matrix() {  // デストラクタ } template<int R, int C> void Matrix<R, C>::func() {  // メンバ関数 } // .hppファイル終わり そういえば、テンプレートはデストラクタ関連で何か制限があるとか どこかに書いてあったような...。なんだっけなあ...。 2.ヘッダファイル拡張子 ヘッダファイル拡張子の慣習の中には、以下のような慣習があるらしい。...

Javaのクロージャをいじってみた(6)

(※updated 2008-08-11のBGGAクロージャライブラリ使用) 1.return の記述 いまさら気づいたんだけど、returnのないクロージャの場合、 最後のステートメントは ; つける必要があるみたいね。 逆にこれがついていない場合はreturnがあるものとみなされるみたい。 // ○ 成功する {String str => System.out.println("Hello " + str); } // × コンパイルでエラーになる // [cannot use a void expression as a closure result]というエラー {String str => System.out.println("Hello " + str) } 2.戻り値無しのクロージャ型記述 あとクロージャの型はvoid型戻り値の場合、明示的にvoidを記述する必要が あるっぽい。引数は空でいいのに。 ...昔のblog記事見直すと{String=>}とか書いているので、 BGGAクロージャライブラリのバージョンによって違うのかも。 // ○ 成功する {String=>void} print; // × コンパイルでエラーになる // [required a type; found a lambda]というエラー {String=>} print; // これはOK {=>String} print; 戻り値として渡したいステートメントは、最後尾で ; が ついていないことが目印なのかも。(想像) {=>} とかいう型の書き方はなくなっちゃうのね。void型ぐらい無記名でも いいと思うんだけどなあ。 {=>void} ってリフレクションやJNIで利用する シグネチャの書式 ()V っぽいな。      

最近の流行のJNI

最近の流行はJNI 現在仕事で.netを利用しており、度々ネイティブコードを 呼ぶ必要が出てきており、P/Invokeのお世話になっている。 そんなときjavaではネイティブコードとの連携はどうなのよ? という疑問がふと起きまして、調べている。 JNIってJavaプラットフォームを構築するなくてはならない基盤技術だと 思うけど案外情報が少ない気がする。 OpenJDK読むにはこの知識必須っぽいよ? 単に調べ足りないだけかな?海外のサイトならたくさんあるのかな。 とりあえずsunのJavaのリファレンスマニュアルと、日本語で数少ない ピアソン・エデュケーションのJNI本を買って読んでる。 C/C++相手なので、メモリ管理やマルチスレッドに対する記述について、 安全なお決まりの書き方のようなものがあれば知りたいと思ったのだけど、 具体的なサンプルコードはweb上ではあまり見つからなかった。 サンプルコードで手に入ったのはOpenJDKだったので、ちょろっと読んで みた。意外だったのは、Stringクラスのネイティブコード部分が意外に 少なかったこと。見間違えでなければJNIの関数は1つしかなかった。   【2008/09/22追記】   ↑よくよく見たらネイティブコード(hotspotのコード)に    java_lang_Stringクラスとかある。 …ん~わからん。 投 昔Stringクラスは高速化のためネイティブコードを 活用しているようなこと聞いた気がするんだけどなあ。 バージョンによって違うのかな? 私のような初心者にはまだ早すぎたようです...。出直します。 気を取り直し、まずは購入したJNIの本を読んでみことにする。 JNIは前世紀でほぼ固まった仕様っぽく、購入した本も1998年初版の 本だけど、新宿紀伊国屋で買ったこの本はやけにきれいだった。 焼けて黄ばんでいるかと思ったけどそんなことなく。 やっぱり需要はあって、コンスタントに売れているのかも。      

P/Invokeで深いため息がでた。

1.P/Invokeについて 仕事で.netからWIN32API呼び出しする処理を書くことになり (P/Invokeというやつ?)構造体定義でウンザリしているところ。 API呼び出しなんて誰が書いても同じになると思うんだけど、 なんでそんなこといちいち定義を書き起こす必要があるのかと。 ...何のためのMicrosoft.Win32ネームスペースなのかと。 こう...深いため息が...。 ...。 pinvoke.net なるサイトがあることを知る。常識? ...。 2.VisualStudio2003の悲しさ あと、同じ仕事場の人がExcel(OfficeXP)から、ASP.NETの webサービスにアクセスするシステムの作成で苦労されている。 問題を困難にしているのは実行/開発環境の縛りがあることかなと。 具体的には   実行環境 WinXP, OfficeXP, .net1.1   開発環境 WinXP, VS.NET2003, .net1.1 客先の環境がこれなので仕方ないのだけど...こういうのってやるせないね。 Office2007あたりなら新しい連携のAPIとかもあって.netとの連携も スムーズかもしれないし、VS2005ならC++/CLRがあるのでネイティブからの 連携も十分ありの選択肢だと思うけど、そのどちらもできない。 マネージ拡張は2005でC++/CLRに取って代わるのに、1から勉強する気に ならないしー。 そこまでしなくてもなにか方法あるのかしら? 3.VisualStudio2003のVB.NETには unsignedの型ないのね。 わたくしてっきり.netなら言い回しこそ違えど、C#と同じ文法を提供していると 思ってましたよ。まして基本型の種類なんて。 Win32APIの引数や戻り値って結構unsigned intな値が良く利用されているので 困った。 戻り値でDWORD型を返す関数を利用することがあり、Long型で受け取った のだけど、使うとなぜか処理成功のでありながら成功"0"を戻さないという 問題にぶつかる。(処理は正常に動いているっぽい) 戻り値を切ったり張ったりずらしたりしたけど、適当な値が取れなかったので すっぱりあきらめC#で書くことにした。汗 原因はたぶん100%私のミスだと思うけど、原因を調べて直...

Javaのクロージャをいじってみた(5)

(※updated 2008-08-11のBGGAクロージャライブラリ使用) 6.static初期化ブロックに見えてこまる クラスのメンバにパッケージスコープのクラス変数として クロージャを宣言すると、static初期化ブロックと一瞬見間違える。 慣れの問題か? class Test { //たとえばこんな記述。static初期化ブロックに見えなくね? static { int, int => int } plus() { return {int x, int y => x+y}; } } 個人的なクロージャの記述スタイルの好みとしては、クロージャ型宣言の 記述スタイルは下のようなスペースを入れない方が好きだなあ。   {int,int=>int} // { int, int => int }   でもクロージャ本体の{}はスペース入れる派かも。 こちらの{}は普通のブロックと同じ意味と考えてるので。   // こんな感じ。 int sum = {int x, int y => x + y }.invoke(3, 4);   ちなみに私のC言語のポインタ記述は以下のとおり。   char* text; // char *text;   このポインタの例で私がクロージャ型宣言の記述スタイルについて 言わんとしていること、わかっていただけるでしょうか。 一種の"型"という意味の強調と、ブロックとしての{}と混同しない様にする ことが目的です。

OpenJDKのオープンソースライセンスについて

大変いまさらな話ですが、OpenJDKのオープンソースライセンスについて よく知らなかったので調べてみた。 Q: なんでOpenJDKはGPLなのに、これを利用するアプリケーションはGPLが 継承(いわゆるGPLのウイルス性)されないの? A: VM以下OpenJDKに含まれるツールは "GPL" で、その他classライブラリやツールが 提供する公開インタフェースは "GPL-Classpath特例(例外)" というライセンスを 適用しているのだそうな。 このClasspath特例によって、javaAPIを利用したプログラムもGPLになる制約 はないみたい。 へー そういえば、Java7でjamとかsuperpackageとか(今は名称変わった?)が 出てくるけどこれを適用したcom.sun~クラスなどは、調べた内容から考えると 非公開インタフェースとなるので"GPL-Classpath特例(例外)"ではなく、 ただの"GPL"が適用されることになるかも? 参考URL: http://www.sun.com/software/opensource/java/faq.jsp#g http://www.gnu.org/software/classpath/license.html http://d.hatena.ne.jp/t_yano/20061113/1163440273    

thikpad X60のキーボード交換した

thinkpadを購入するときから決めていた英語キーボード化。 ついに交換しだぜ! 既存の日本語配列がへたってからとか、x60のパームレスト右側が ものすごく熱いのでx200に近いうち乗り換えるからもったいないとか。 今まで色々理由をつけて見送っていました。 でもよくよく考えてみると、週一程度しかthinkpadに触らない人間が、 キーボードがへたるって何時の話だよとか、x200は新しすぎて値段が 高くすぐには手が出ないじゃんとか、直販で英語キーボード版販売 という話を聞いたけど、x200は英語キーボード選択できないじゃん…。 ということで、熱いの我慢して当分こいつ(X60)と付き合っていく 方針を固めたわけです。 幸い秋葉原の"若松通商"にキーボードの在庫ある様子。 早速アキバへGO。買ってきました。 自宅PCのキーボードは英語配列のHHKなので、まあすぐなれるじゃろ。 thinkpad買ったのはこれがやりたかったからに他ならない。 thinkpad本領発揮!!みたいな。 それにしてもパームレストの熱、いらつくなあ。 今この書き込み書いているそばから、右側が熱くなってきた…。 無線モジュールはBIOSで無効にしているんだけど、やっぱり暖かいわ。 x200であれだけ冷却に関して改良され/冷却についてアピールている ところを見ると、相当数のユーザーからのクレームや要望があったん だろうなあ。 x200系の今後は大いに期待。値段が安くなったら絶対乗り換えるぜ。 ところで、あまった日本語キーボードどうすりゃいいだろ? じゃんぱらとかSofmap辺りなら中古パーツの買取もOKかな? 後でググってみよう。    

Javaのクロージャいじってみた(4)

6.関数参照(Function Reference)   新しい記述が導入されるみたい。   クラス/インスタンスメンバへの参照は、"."演算子だが、   関数参照として新しく"#"演算子(みたいの)が導入されている。   このときは引数は型のみ記述している。メソッドを呼び出すというより、   クロージャとして取得したいメソッドのシグネチャを指定している感じ。   .netのデリゲート生成と似ている気がする。   例)   関数参照のコード String str = "Hello World !!"; {int,int=>String} subString = str#substring(int,int); // 引数も"型"を指定する --> ~~~~~~ System.out.println("subString=" + subString.invoke(0, 5)); // 出力:subString=Hello   逆コンパイルしたコード    finalも@Sharedも無しでコンパイルできたのは自動でfinal代入コードが   挿入されるためと判明。 String s = "Hello World !!"; final String binding = s; // このコードが自動挿入され変数がクロージャに渡される OII oii = new OII() { public final String _2B_invoke(int i, int j) { return binding.substring(i, j); } public final String invoke(int i, int j) { return _2B_invoke(i, j); } public volatile Object invoke(int i, int j) throws Throwable { return invoke(i, j); } final String val$binding; {...

関数型言語の勉強必要かも

関数型言語について知っておくと、boostとかC#3.0とかRubyとか javaに限らず色々役に立つかもしれないので、Haskellの本読み始めた。 仕組みが全く違っていて難しい。 なんというか、こう...日本語配列と英語配列キーボードの違いがc/c++,c#, javaの違いなら、関数型言語はdevorak配列のような違いがある。 読みきる前に他の本に浮気しそう。(汗 この遅延評価というのが…ん?んんー??んんんーー!? ……とりあえずモナドはUNIXコマンドのパイプなイメージで。 そういえば、Fork-Join Frameworkのメソッド名とかHaskellで見覚えのある キーワードだった。(withFilter()とかwithMapping()とか) 影響受けているのかね。 む。BGGAのクロージャサイトのプロトタイプまた新しくなってる。  → (updated 2008-08-04)   

Javaのクロージャいじってみた(3)

5.カリー化   メソッド内無名クラス定義ではfinal修飾子をつけたローカル変数を   無名クラス内部で利用することができるが、これを利用して   カリー化を実現している...みたい。   マイコミジャーナルの記事 にクロージャ内で利用したいローカル   変数には@Sharedアノテーションをつけることで利用可能になる   という記述があった。   へー   てっきり無名クラスのシンタックスシュガーだからfinalにしないと   駄目かと思っていたけど、ちょっと違うのね。   ……?あれ?私の試しているクロージャ実装(*1)ではfinalにも@Shared   つけなくてもコンパイル通るぞ??このバージョンの実装では文句は   言わないのかな?それとも@Sharedはクロージャのための機能じゃない   からjava7入れないとだめとか?   (*1 JDK1.6.0_10_bate, BGGAプロトタイプ実装2008-07-07版)   例)   javaクロージャでカリー化 //int local = 2; final int local = 2; {int=>int} func = { => {int num => num / local } }.invoke(); func.invoke(10); // 結果=5   上記コードの逆コンパイルコード final byte local = 2; II ii = (II)(new O() { public final II _2B_invoke() { return new II() { public final int _2B_invoke(int i) { return i / local; } public final int invoke(int i) { return _2B_invoke(i); } ...

Javaのクロージャいじってみた。(2)

4.自動でインタフェース継承  ・型推論   クロージャで記述すると自動的にインタフェースを継承してくれる。   いわゆる型推論ていうの?   いじってみた限りでは、以下の2つの記述で自動的に継承してくれる   ことは確認した。他のケースはしらん。     (1) 引数埋め込みで記述。     (2) クロージャの戻り値の型を継承したいインタフェース型で記述。   ・継承した場合メソッドはクロージャ型のinvoke()ではなく、    各インタフェースのメソッドとして扱われる。(内部処理的にはinvoke()    ぽいメソッドが生成されている模様。)   ・継承(実装)できるのはインタフェースだけで、抽象クラス/クラスは    継承できなかった。(コンパイルエラーになる)   ソースコード Functor<Integer> func = {Integer i => (int)(i * 2.4 + 68)};   逆コンパイルコード   // 呼び出し側   obj._fld1 = _2B_INSTANCE0; // 定義側 // 定数メンバとして定義される public static final _cls2 _2B_INSTANCE0 = new Functor() { // 戻り値型に継承されてる --> ~~~~~~~~~ public final int _2B_invoke(Integer integer) { return (int)((double)integer.intValue() * 2.39...9D + 68D); }     // ジェネリクスの場合、ブリッジメソッドもちゃんと生成されてる。 public final Integer calc(Integer integer) { return Integer.valueOf(_2B_invoke(integer)); } public volatile Object calc(Object obj) { return calc((Integer)obj); ...

クロージャ、java7での導入厳しいのかしら?

クロージャはjava7での導入の見込み薄い という書き込みを見かけた。 ソースを手繰るとjava7のメーリングリストっぽい。 ガーン。 BGGAのクロージャ実装、色々調べたのにー。 言語仕様の変化が大きすぎるのかー!? ……ん、ただのシンタックスシュガーだし関係ないか…。 (ここのClosure日記は、jdk1.6.0_10-bataでコンパイル/実行してる) だから逆に「そんなシンタックスシュガーごときいらん」 ということなのかな。ラムダ式楽しいぜ? Effective Java Second Edition に"Item21: Use function objects to represent strategies"という項目が増えてたりして、 Third EditionでのClosure項目追加の布石かしら? とか期待していたんだけどなあ。 でも一方でどこか安心している自分もいたり…。言語仕様の拡張を 好まないところはjavaらしいかなと。私がjavaを好む理由のひとつは 言語仕様拡張よりライブラリ提供での機能拡張を好むところだし。 まだ決まったわけじゃないし、来年のJavaOneの内容を楽しみに 待ちますかー。    

Javaのクロージャをいじってみた。(1)

イメージ
BGGAのクロージャサイト(http://javac.info/) の プロトタイプ実装をいじってみた。 マイコミジャーナルに概要を書いた記事があるようです。 今回いじってみたのは2008-07-07版と2008-07-13版のプロトタイプ実装。 JSRもドキュメントもちゃんと読まずにいじっているけど まあいいや。 1.単純実装の逆コンパイルして中身見る ・クロージャを用いたjavaコード public class SimpleClosure {   public static void main(String[] args) {     int sum = { int x, int y => x + y }.invoke(3, 4); // return 7     System.out.println(sum);   } } ・下のコードは上記コードをコンパイルし、jadで逆コンパイルしたコード import java.io.PrintStream; import javax.lang.function.III; public class SimpleClosure {   public SimpleClosure() {}   public static void main(String args[]) {     static class _cls1 implements III {       public final int _2B_invoke(int j, int k) {         return j + k;       }              public final int invoke(int j, int k) {         return _2B_invoke(j, k);       }     }     int i = _2B_INSTANCE0.invoke(3, 4);     System.out.println(i);   }   // ↓クロージャの実体(staticのメンバとして記述される)   public static final _cls1 _2B_INSTANCE0 = new _cls1(); } 逆コンパイルで気づいた点  ・クロージャの場合実際はstaticメンバとして宣言されるため...

丸め誤差で散々悩む

Rhinoを使ってスクリプティングをちょっと試してたところ、妙な計算結果に遭遇。 (100.5-30.4)*15.2=1065.5199999999998 掛け算しかしていないんですけど…。 全く原因がわかららず、   windowsの電卓 誤差無し   Ruby(1.8.5)   誤差無し   ActivePerl    誤差無し で試してみる。でも正しく計算されてしまいました。 これってRhinoのバグかしら。Bugzillaの使い方覚えなくちゃかしら。 とか考えるほど混乱。 頭を冷やすため、それからしばらくこの件は放置していました。 先日Firefox3のβをいじっていたところ、不意にこの件を思い出し、 javascriptの処理系が違ったら…ということで調べてみることに。 Firefox3とIE7で同じ計算をさせたところ、同じ誤差が発生し バグでないことが判明しました。 これ何なのさ…と調べ、"2進数表現による丸め誤差" という結論に たどり着きました。 長かった…。 ついでに手元にある他の処理系で試してみた。 【誤差有り】   java(6)   jruby(1.1 java6) (javaの影響)   Firefox(3 bate5)   IE(7) 【誤差無し】   C#(C#3.0)   C++(VC++9.0) C++で丸め誤差が発生しないのはびっくり。古めの言語だから逆に仕様として Javaのように丸め誤差が残っているものと思っていたのに。 Microsoftが気を利かせたのか、ISOの標準C++とかだとOKなのか。 面倒臭がって調べていない。 JavaはBigDecimalとかのクラスによって解決法を提供しているため、 言語仕様では(わざと?)誤差が残っているみたい。    

Blogger Syntax Highlighterテスト

前からやりたかったコードの表示、「クリボウの Blogger Tips」さんの記事に すごいのがあったので早速導入。& テスト。 public class HelloWorld {   public static void main(String[] args) {     System.out.println("Hello World!");   } } 今まで作成した日記も書き直そうか、どうしよう。    

Effective Java Second Editionが届きました。

イメージ
予約してから1ヶ月待たされてました。それが今日amazonからやっと届きました。 明日はJavaOne報告会に行ってきます。 ITProの記事で櫻庭祐一氏が書かれているJava 7情報。 同氏のJavaSE最新情報が聞けるので、期待して行ってきます。    

Java Genericsが難しい(4)

3.ジェネリクスと可変長引数と継承 以下のコードをコンパイル,実行すると、実行時エラー(ClassCastException)になる。 class Plus {   R apply(T... t) {     return t[0] + t[1];   } } class Client {   public void main(String[] args) {     Plus <Integer,Integer> p = new Plus< Integer,Integer > ();     Integer result = p.apply(1,2);        :        :   } } 私はjad使ってイレイジャの処理を見ていたのですぐにわかったが、 ソースコードだけ見て原因を特定できる人はすごいと思う。 jadで逆コンパイルすると以下のコードになる。 class Plus {   Object apply(Ojbect[] t) {     return apply((Integer[]) t); //   }   Integer apply(Integer[] t) {     return t[0] + t[1];   } } class Client {   public void main(String[] args) {     Plus p = new Plus ();     Integer result =       p.apply(new Object[] {1,2}); //        :   } } イレイジャ処理で生成されたブリッジメソッドに対し、可変長引数の処理が 行われるためブリッジメソッド内部で無理やりキャストする処理でエラーになる。 ブリッジメソッド、可変長引数など自動生成されるコード内でのエラーのため これははまると解決が大変なエラーだと思う。 ということで可変長引数とジェネリクスの組み合わせは良くない組み合わせ だと思う。    

Java Genericsが難しい(3)

2.ジェネリクスとオーバーロード 既存の方法で、何とか演算処理をさせたく少し試してみた。 Genericsメソッド内から、型だけ異なるオーバーロードメソッドの 呼び出してみた。 class Plus T,R > implements Function T,R > {   R apply(T arg1, T arg2) {     return apply(arg1,arg2);   }   Integer apply(Integer arg1, Integer arg2) {     return arg1 + arg2;   }   Double apply(Double arg1, Double arg2) {     return arg1 + arg2;   } } 結果はコンパイルエラー。 イレイジャ処理でObject型になってしまうので、IntegerともDoubleとも 合わない適当なメソッドが無い、とコンパイラが文句言う。 そもそもこのコードがうまくいったとしても、折角Genericsを利用しているのに オーバーロードメソッド定義していたらGenerics使っている意味無いし。 (Genericsなんか使わずオーバーロードメソッドで十分と)    

java7のBigDecimalの演算子オーバーロードに関する希望

「わんくま同盟」の方のサイトにあったC#の例のような、 演算子ラッパーメソッドとか提供されるとうれしいな。 java7が以下のような感じの実装とか希望。 abstract class Operator extends Number {   T add( T t){} // +   T negate( T t){} // -   T divide( T t){} // /   T mulutipry( T t){} // *   T modify(T t){} // % } class Integer extends Operator {   ... } 上記のようなOperatorインタフェースを継承すると演算子で記述しても 以下のメソッドに展開し処理する仕組み希望。 コンパイラは以下のインタフェースを継承以外は演算子として解釈しない とか。 そしたらこんなファンクタ作れるかも? interface Function {   R apply(T); } class Plus implements Function {   R apply(T t) {     return t + t;   } } class Client {   public void main(String[] args) {     Loop.foreach(new Integer[] {1,2,3,4}, new Plus ());     Loop.foreach(new Double[] {1.1,2.2,3.3,4.4}, new Plus ());   } } jadでPlus.classファイル開くとこんなイメージ。 class Plus implements Function {   Object apply(Object t) {     return this.apply((Operator)t);   }   Operator apply(Operator t) {     return t.add(t);   } } だったらいいなあ。 大体、BigDecimalにある演算子のラッパーメソッドを他の プリミティブ型ラッパークラスに用意してくれれば、演算子オーバーロードはいらないのだけど。    

Java Genericsが難しい(2)

1.ジェネリクスと四則演算 以下のような記述がしたかったのだけど、javaではできません。(コンパイルエラー) C++Templateならこんな感じでもいけるはず。 class Plus < T extends Number,R extends Number >     implements Function < T,R > {   R apply(T arg1, T arg2) {     return arg1 + arg2;   } } ”このインタフェースを継承するとコンパイルのときboxing/unboxingが働くよ” というマーカーインタフェースがない(Numberクラスはダメ)ので、ジェネリクス型で 記述した変数に対し演算子を用いて演算することはできない。 「ジェネリクスと四則演算」の組み合わせはC#(.net)でも利用できないようで、 「わんくま同盟」の方のblogにその辺の記事をみかけた。 でも演算子オーバーロードのあるC#(.net)は将来に希望を持てそうでうらやましい。    

Java Genericsが難しい(1)

javaのジェネリクスが思うように書けず苦労してます。 jsr166y/zソースコードやJava7 Closureのサイトを見てからファンクタに興味を持ち、 ファンクタをジェネリクスを使って書いてみたのですが、うまく書けない。 ジェネリクスに関したエラーに遭遇し悩んだのは以下の組み合わせ。 ジェネリクスと四則演算 ジェネリクスとオーバーロード ジェネリクスと可変長引数と継承 C++のテンプレートのような振る舞いを期待しながらコーディングすると あっさりコンパイルエラーになる。 各項の詳細を今後書いていこうかなと思います。    

JJUG Cross Community Conference

今日は仕事休んで JJUG Cross Community Conference 2008 spring に行ってきました。 気になっていたAndroidの話も聞け、有意義な一日でした。    

画像テスト

イメージ
画像貼り付けてみる。 うんむ。 コンテンツ無い人間てだめね。(主に私) 画像ファイルといっても画面のキャプチャだよ…。

初投稿

顔が見える会社のSNSはちょっとやなので、こちらに書いてみる。 今まで書き込みをしたことのない人間なので、まずは書き込みになれる。