2008年6月13日金曜日

Javaでprivateなメンバーにアクセスする方法

前回はprivate変数へのアクセスを簡単に解説したんだけど、みんなやっぱりその辺気になるみたいで結構アクセスがあるので二匹目のドジョウを狙ってもう少し詳しく調べてみた。
前回の記事はこちら
Javaでprivateなインスタンス変数にアクセスする方法

陽気な外人の翻訳風に書いてみる。

AccessibleObject

まずAccessibleObjectクラスについてみてみよう。
AccessibleObjectクラスは前回触れたFieldクラスの抽象クラスで(親クラスともいうね。ここで抽象クラスって言ったのは複数のサブクラスが存在していてそれらを使う場合にこの型を使って抽象的に書けることを強調したいからなんだ。)、アクセス権に関するメソッド群が定義されている。
ドキュメントにはこう書かれている。(これを探すのに何分も掛かった。Sunはドキュメントを見せない事で議論を活発にさせJavaを普及させようとしてるんだlol)



AccessibleObject クラスは、Field オブジェクト、Method オブジェクト、および Constructor オブジェクトの基底クラスです。このクラスを使うと、リフレクトされたオブジェクトの使用時に、デフォルトの Java 言語アクセス制御チェックを抑制するかどうかのフラグ設定を行えます。アクセスチェックは、次の場合に public、デフォルト (package) アクセス、protected、および private メンバーに対して実行されます。 つまり、フィールドの設定または取得に Field が使用される場合、メソッドの呼び出しに Method が使用される場合、あるいはクラスの新しいインスタンスの生成および初期化に Constructor が使用される場合です。



リフレクトされたオブジェクトで accessible フラグを設定すると、十分な特権を持つ高度なアプリケーション (Java のオブジェクトの直列化やその他の持続性機構など) は、通常は禁止されている方法でオブジェクトを操作できます。



AccessibleObject (Java Platform SE 6) から引用

publicでないメソッドにアクセスする際のチェックを抑制する事で目的のメンバー(変数、メソッド、内部クラス等クラス内に定義されている物なんかをメンバーと呼ぶんだ。クラスは一つのチームだと考えるといいかもね、いろんな奴が集まってるからprivateなシャイな奴もいるってわけ。もちろん冗談だけどねlol)へのアクセスをできる。
そして、AccessibleObjectにはField,Method,Constructorの三つのサブクラスがあり、それぞれがフィールド変数(インスタンス変数やクラス変数などクラスが直接持っている変数。それに対しメソッド内に定義された物がローカル変数。ローカル変数は本当に恥ずかしがりやだから話しかける(アクセスする)事は本当に難しいかも)、メソッド、コンストラクタに対応している。
前回はインスタンス変数にアクセスするためにFieldクラスを使用したけど、ほかのメンバーにアクセスしたい時はそれに対応したクラスを使うことでできるようになるんだ。(そう、女の子に合わせて口説き型を変えるみたいな感じかなlol)
じゃ~今回はこれを利用してprivateなコンストラクタが定義されたクラスをインスタンス化する方法を紹介しよう。


シャイなあの子のハート(コンストラクタ)をこじ開けろ!!

privateなコンストラクタを持ったクラスをインスタンス化できないのは何故だろう?
それはprivateは自クラスからしかアクセスできない事を表す修飾子でそれがコンストラクタに付いてるって事は、インスタンス化する際に初期化ができないからなんだ。
じゃ~なんでそんな事ができるかって?
それはstaticなメソッドが定義されたユーティリティークラスでインスタンス化しないで使えるクラスや、シングルトンパターンを適応したクラスなんかで使われるからさ。

// シングルトンパターン
public class Singleton {
private static Singleton singleton;
// static変数でこのクラスの型

private Singleton() {}
// privateなコンストラクタ

public static Singleton newInstance() {
// インスタンス化をするpublicなstaticメソッド
// このメソッド内でインスタンス化するのでprivateコンストラクタであっても
// インスタンス化することができる

if (singleton == null) {
// null チェックをしてまだインスタンス化していないかを確認して
// インスタンス化していなければnewする
singleton = new Singleton();
}
return singleton;
}
}


だから普通はprivateなコンストラクタを持っていたとしてもそれは必要だからそうしているのであって、無理に変更してインスタンス化するなんて事はあまり無いんだけど、何事も経験だから(経験無しにいきなり本番じゃ~焦るのも無理ないからね)今回はチャレンジしてみよう。

public class PrivateConstructor {

  // privateなコンストラクタ
private PrivateConstructor() {
System.out.println("え、やだっそんな無理やりインスタンス化なんて・・・らめぇええええ");
}

public void helloObject() {
System.out.println("ちょ、ちょっと!!なに勝手にインスタンス化してんのよ!!");
System.out.println("・・・別にアンタのためにインスタンス化したわけじゃないんだからねっ!///");
}
}


これがprivateなコンストラクタを持ったクラス。なんか書いてあるけど気にしないでコンストラクタがprivateになっているのを確認してほしい。
そしてこれを呼び出す側のコード。

public class Main {
public static void main(String[] args) throws Exception {
// PrivateConstructor pConstructor = new PrivateConstructor();
// コンストラクタをprivateにするとインスタンス化できるのはそのクラスだけなので
// このコードはコンパイルエラーとなる

Constructor constructor =
PrivateConstructor.class.getDeclaredConstructor(new Class[]{});
// まず前回同様にClass#getDeclared~メソッドを使ってprivateなメンバーを取得する
// 引数にはコンストラクタで指定されている引数の型のクラスを渡す
// 今回の用に無い場合は空の配列でおk

constructor.setAccessible(true);
// Accessibleフラグをtrueにしアクセス権チェックを抑制する

PrivateConstructor pConstractor = constructor.newInstance(new Object[]{});
// newInstanceメソッドを使ってインスタンス化する
// このnewInstanceメソッドの戻り方はconstructor変数の宣言時にしていした
// 総称型(ジェネリック)型になる

pConstractor.helloObject();
// インスタンス化できてメソッドにアクセスできている
}
}

そして呼び出した結果がこれ

え、やだっそんな無理やりインスタンス化なんて・・・らめぇええええ
ちょ、ちょっと!!なに勝手にインスタンス化してんのよ!!
・・・別にアンタのためにインスタンス化したわけじゃないんだからねっ!///


ね?簡単でしょ?
今回はprivateなコンストラクタにアクセスする方法を紹介したけどどうだったかな?
このコードでクラスとインスタンス、クラスに定義されたメンバーその辺りの関係が少しは見えてきたと思う。
一番のポイントはClassクラスの存在でクラス自体もJVM上にインスタンスとして存在していてそれに対して動的にアクセスしたりもできるって事。
Javaは静的型付けを強く意識しているのでこういうことはしないほうがいいんだろうけど、できなくもないんだよね。

2008年6月10日火曜日

よく考えると

早い、はやすぐる!!もう6月、今年も後半に突入!
今年の初めに変な勢いで始めたブログも思ったより更新してる気がする。
当初は三日坊主で終わると思ってたのに(Python記事とかは三日坊主だけど)意外や意外、50エントリーに近づきつつある。
とりあえず、今年の目標として100エントリーを目指して、少しづつ記事の内容も濃い物にしていければいいなぁっとおもってる。

そして昨日AppleのWWDCでiPhoneの発売が7月11日に決まったみたい!
まさか、こんなにすぐ発売されるとは思わなくってうれしい誤算。
Willcomの解約方法も調べたし、あとは発売を待つだけだ~。
誕生日が八日なので今年は自分へのプレゼントとしてiPhoneで決まりだね。



米国や日本など世界の22カ国で7月11日から発売する。価格も従来機よりも大幅に下げた。米国での価格は8GBモデルが199ドル(約2万1000円),16GBモデルが299ドル(約3万2000円)となっている。



米アップルがHSDPA対応のiPhone 3Gを発表,日本発売は7月11日:ITpro から引用

2008年6月8日日曜日

今日の購入物

今日は天気もよかったのでいろいろとお買い物をしてきました。

まずはこれ。

オオタニヨシミさんの独特のデザインで描かれた魔法瓶です。
節約生活ということで、明日からはお茶を入れて持ってこうかと。
一ヶ月でだいたい元は取れると思うから安いもんだよね。

あとは本四冊。




前から欲しいと思っていたJythonの本をようやく見つけたのでPythonの勉強を再開しようと思います。
ちかくに夜カフェが開店してたので、本を持って行ってみようかなぁ。

2008年6月6日金曜日

GoogleReaderにはてブ数を表示するグリモンが止まってしまう問題の応急処置

はてな民でGoogleReager愛用者には無くてはならないグリモンといえばid:nozomさんが公開されているGoogleReaderにはてブ数を表示するグリモンです。



id:kei-sさんのGoogle Readerでfaviconを表示させるGreasemonkeyスクリプト公開に触発されて、Google Readerにはてなブックマーク件数とブックマークアイコンを表示するGreasemonkeyスクリプトをバージョンアップした。



grb+-20061113.user.js



grb+-20061113.user.js - ヒビノキロク から引用

はてブ数とコメントが気になってしょうがない僕にはめちゃくちゃ便利でこれ無しではもうRSSのチェックはやってられないんですが、たまにダイアログが出て動作が止まってはてブ数が反映されなくなってしまって困ってました。
で、あまり深くは追ってないですが、対処法を書いておきます。

スクリプトをエディターで開いて106行目

if (response.responseText.match(/<fault>/)) {
// この中をコメントアウト
// clearInterval(timerID);
//alert("xmlrpc call failed: " + response.responseText + "\n" + "request: " + requestbody);
} else {

callXmlrpc()関数内のif文の処理をコメントアウトするだけです。
elseブロックはそのままにしておきます。
どうも、はてなAPIに問い合わせの返答に<fault>タグが混じっていた場合に更新を止めて、alert()で知らせているようなんですが、更新を止めてるのでここに来た以降はてブ数が表示されなくなります。
僕はそんなにJavaScriptに詳しくなくて何故こうなってるのかはわからないので、この修正で別の問題が起きる可能性がありますが、今のところはてブ数を加える処理が止まるということは無くなりました。
とりあえずこれで直るっぽいですが何が起きるかわからないので自己責任でお願いします><

追記 - 20080905
Ahead one step: grb+のちょっとした部分の修正

2008年6月4日水曜日

iPhoneの発売日と正式名称

ソフトバンクからiPhoneの発売が決まりましたね~。



この度、ソフトバンクモバイル株式会社は、今年中に日本国内において「iPhone」を発売することにつきまして、アップル社と契約を締結したことを発表いたします。



「iPhone」について | ソフトバンクモバイル株式会社 から引用


ソフトバンクは3日に新端末を発表したばかりなので、他のキャリアの顔を立てるためにも発売は半年後とかになるんじゃないでしょうか?
お財布携帯やワンセグなどが使えないと予想されるので、購入しようか迷ってる方もちらほらいるみたいですが、僕はwillcomユーザーで日本特有の携帯サービスに馴染んでいないので速攻で機種変更します。
さよなら、willcom。こんにちは、アイフォーン!!

ちなみにアイホンでもアイフォンでもなくて正式名称はアイフォーンみたいです。
言い難い・・・・。




Appleが携帯電話「iPhone」を日本で発売するにあたって、インターホン最大手の会社「アイホン」と商標に関する協議を続けたところ、ついに合意が成立したそうです。



これにより日本では「iPhone」を「アイフォーン」と読むことになる模様。



iPhoneは「アイフォーン」と読むそうです - GIGAZINE から引用

初見練習の成果

最近ピアノ練習の最初にチェルニーの初見練習をしている。
指の体操も含めてとにかくゆっくりでいいから両手でいきなり弾く。
暗譜してないからぎこちなくて、次の音を一つ一つ確認して弾くのが
イライラして気持ち悪いけど我慢して一つ一つ音符を拾って通して弾く。
曲の完成度は求めずとにかく一ページ弾ききる。
そんで弾きこまず次の日はまた違う曲というのを繰り返す。
今までの様に頭で覚えて弾くのを辞めるのだ。

この練習を初めて一週間で感じた事は、物凄く楽譜を見るようになった。
というか、楽譜を見ながら弾けるようになってきてるのが実感できる。
楽譜を見ながら指の移動ができるので、練習曲の初見部分も今までよりスムーズに弾ける。
こないだの練習会で教えて貰った弾けないところは音符を削って流れを掴む練習
(楽譜を縦に見ず横に見るらしい)もあいまって一回の練習で譜読みが結構進む。
こうなると俺かなり弾けてんじゃね?って気になって練習が楽しい。
楽しいと毎日練習するから上達が早くなり、また楽しくなって練習する。
この好循環はすごいいいんじゃないかと思う。

あと梅田本に書いてあったようにやりたいことのためにやらないことを決める。
ピアノを練習する時間が無いんじゃなくて無駄にやってる事が多すぎるのだ。
本当にやらなければいけない事かちゃんと見極めないといけない。

追記:
暗譜に関して興味深い論があったのでメモ。
暗譜無きに上達はありえないとのこと。
ただ、暗記するだけじゃなくて音楽理論を学んで体系的な事もわかった上で暗譜するのが大事のようですね。
その点では僕は暗譜してるけどそれは暗記しているだけなのでダメなんだと思う。



暗譜は必要か? 



 先日ピアノ好きの方から「リヒテルは暗譜しなくてもいいと言っていますけど本当なんですか?」というようなことを聞かれました。暗譜については思うところあるのですがなかなか書く事ができずにいます。ここではリヒテルの言葉に対する私の考えを書いておきたいと思います。リヒテルのドキュメタリーを見ているとやはり暗譜についての問答が出てくるのですが、リヒテルははっきり「楽譜の全てを覚えられるかい?」と暗譜演奏を否定しています。 しかし、私は絶対暗譜はすべきだと思います。



暗譜に関するひとこと から引用

2008年6月3日火曜日

楽譜情報共有サイト

おもしろそうなサービスを思いついたので記す。
すでにあったら教えてください。無ければ誰か作ってください。
ちなみにこれはアイデアなので楽譜は置いてありません、ごめんなさい。

楽譜情報共有サイト(仮)


楽譜は演奏されるための最低限の情報として音符、強弱、速さ、場合によっては具体的な弾き方の指示が記されているがあくまで最低限の情報なので、先生や自分で注意書きをしてそれを元に演奏する場合がほとんどだと思います。
このサイトではその注意書きを共有し、コミュニケーションを計るサイトです。
※注意書きは演奏指示や運指など様々な情報

サービス内容
・著作権の切れたクラシックの楽譜を共有する
・楽譜をアップロードした人は、楽譜に注意書きを書き込むことができる
・楽譜だけでなくその上に書いた演奏に関する注意書きを共有する事が目的
・注意書きは曲の解釈の仕方によって違うが、いろんな人の解釈を比較できる
・人が書いた注意書きを評価できるシステム
(直接の評価は荒れるので、表示回数、コメント数などで行う?)
・楽譜にタグが付けられ、また注意書きの記号も共有化し検索できる

問題点
・著作権の問題
(クラシックの楽譜の著作権はほとんど切れているが出版者が差し止めた例がある)

ビジネスモデル
・アドセンスやアソシエイトで楽譜の紹介などで利益を得る
・楽譜情報や注意書きの共有自体も利益
・センスのある注意書きを集めた本を出版する(注意書きのをした人の権利を尊重する)
・有料サービスで本物のレッスンを受けられ、自分の楽譜に注意書きをして貰える or 注意書きの詳しい説明をして貰える(一時間2000円くらい?安くする)


問題はやっぱり楽譜かなぁ・・・。
楽譜の共有が難しければ、注意書きだけ共有して、自分の楽譜にコピーする等も考えられるかなぁ。
誰か作ってくれないかなぁ~。(他力本願)