pythonまったく勉強していない今日この頃。ていうか日本語にエンコードできねーんだってばよ。
Pythonが日本で普及しないのは日本語がうまくエンコードできないからか?
だってwebから取得したリソースは化け化けだし、ファイルにはちゃんと保存できてるんだけど
コンソールで表示できないし。デバックできやせん。いちいちファイル開いてられっか。
そういう感じのこと解説してるサイトもないし・・・。
なんか変なファイルを書き換えて~とかもやってみたけどなおらん。
あとドキュメントの見方もよくわからんし、やりたい事がぱっと探せん。
正直JavaしかできないけどeclipseあったらJavaでも非コンパイル言語の用にすぐ実行できちゃうし
コンパイルする分速度速いし、Javaだけできてたらいいんじゃねーのって気がしてきた。
ドキュメントもちょー見やすいしさー。ドキュメント見つけるのが大変だけど・・・。
クラス単位だから別に全部しってなくても付け焼刃で動くんだぜーめっちゃ楽じゃん。
そりゃー完璧に把握して使ったほうが安心んだんだろうけど、
楽するためのプログラムにそんな労力つかいとーないわ。
っと、javaでYahooの日本語形態素解析いじくってて思った。
ポストのやり方もちょっとわかったし、ごにょごにょできるようなの書けそう。
次は2chのログ加工とかやってみる。
2008年7月24日木曜日
2008年7月15日火曜日
今日のブックマークてすと
以前言ってた言及したブックマークのみ取得して整形するコードを書いてみた。
Ahead one step: 今日のブックマーク(仮)
pythonじゃなくてjavaで。。。pythonはどうしても日本語エンコードができない;;
とりあえずテスト出力。もう少し整形したら公開してみよう。
Ahead one step: 今日のブックマーク(仮)
pythonじゃなくてjavaで。。。pythonはどうしても日本語エンコードができない;;
とりあえずテスト出力。もう少し整形したら公開してみよう。
2008年6月13日金曜日
Javaでprivateなメンバーにアクセスする方法
前回はprivate変数へのアクセスを簡単に解説したんだけど、みんなやっぱりその辺気になるみたいで結構アクセスがあるので二匹目のドジョウを狙ってもう少し詳しく調べてみた。
前回の記事はこちら
Javaでprivateなインスタンス変数にアクセスする方法
陽気な外人の翻訳風に書いてみる。
AccessibleObject
まずAccessibleObjectクラスについてみてみよう。
AccessibleObjectクラスは前回触れたFieldクラスの抽象クラスで(親クラスともいうね。ここで抽象クラスって言ったのは複数のサブクラスが存在していてそれらを使う場合にこの型を使って抽象的に書けることを強調したいからなんだ。)、アクセス権に関するメソッド群が定義されている。
ドキュメントにはこう書かれている。(これを探すのに何分も掛かった。Sunはドキュメントを見せない事で議論を活発にさせJavaを普及させようとしてるんだlol)
AccessibleObject (Java Platform SE 6) から引用
publicでないメソッドにアクセスする際のチェックを抑制する事で目的のメンバー(変数、メソッド、内部クラス等クラス内に定義されている物なんかをメンバーと呼ぶんだ。クラスは一つのチームだと考えるといいかもね、いろんな奴が集まってるからprivateなシャイな奴もいるってわけ。もちろん冗談だけどねlol)へのアクセスをできる。
そして、AccessibleObjectにはField,Method,Constructorの三つのサブクラスがあり、それぞれがフィールド変数(インスタンス変数やクラス変数などクラスが直接持っている変数。それに対しメソッド内に定義された物がローカル変数。ローカル変数は本当に恥ずかしがりやだから話しかける(アクセスする)事は本当に難しいかも)、メソッド、コンストラクタに対応している。
前回はインスタンス変数にアクセスするためにFieldクラスを使用したけど、ほかのメンバーにアクセスしたい時はそれに対応したクラスを使うことでできるようになるんだ。(そう、女の子に合わせて口説き型を変えるみたいな感じかなlol)
じゃ~今回はこれを利用してprivateなコンストラクタが定義されたクラスをインスタンス化する方法を紹介しよう。
シャイなあの子のハート(コンストラクタ)をこじ開けろ!!
privateなコンストラクタを持ったクラスをインスタンス化できないのは何故だろう?
それはprivateは自クラスからしかアクセスできない事を表す修飾子でそれがコンストラクタに付いてるって事は、インスタンス化する際に初期化ができないからなんだ。
じゃ~なんでそんな事ができるかって?
それはstaticなメソッドが定義されたユーティリティークラスでインスタンス化しないで使えるクラスや、シングルトンパターンを適応したクラスなんかで使われるからさ。
だから普通はprivateなコンストラクタを持っていたとしてもそれは必要だからそうしているのであって、無理に変更してインスタンス化するなんて事はあまり無いんだけど、何事も経験だから(経験無しにいきなり本番じゃ~焦るのも無理ないからね)今回はチャレンジしてみよう。
これがprivateなコンストラクタを持ったクラス。なんか書いてあるけど気にしないでコンストラクタがprivateになっているのを確認してほしい。
そしてこれを呼び出す側のコード。
そして呼び出した結果がこれ
ね?簡単でしょ?
今回はprivateなコンストラクタにアクセスする方法を紹介したけどどうだったかな?
このコードでクラスとインスタンス、クラスに定義されたメンバーその辺りの関係が少しは見えてきたと思う。
一番のポイントはClassクラスの存在でクラス自体もJVM上にインスタンスとして存在していてそれに対して動的にアクセスしたりもできるって事。
Javaは静的型付けを強く意識しているのでこういうことはしないほうがいいんだろうけど、できなくもないんだよね。
前回の記事はこちら
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にするとインスタンス化できるのはそのクラスだけなので
// このコードはコンパイルエラーとなる
Constructorconstructor =
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年4月25日金曜日
Javaでprivateなインスタンス変数にアクセスする方法
よくJUnitなどを使ってテストのテストケースでprivate変数の値をテストしたい場合があるけど、テストのためにクラス設計を変更するはあんましよくないし、回りまわって得られた結果でおkとするのもめんどくさいと思うことがよくあります。
そんなときはアクセス権を動的に変更して、private変数に直接アクセスしちゃいましょう!
こちらを参考にしました。
クラス Field
リフレクションの学習
サンプルコード:
上記のコードを実行するとコンソールに「実は俺・・・」と表示され、PrivateVariableクラスのprivate変数himituにアクセスできたことがわかります。
これでいちいち回りくどいユニットテストを書かずに、private変数にアクセスして単純なテストケースを書けるようになりました!
※注意事項
private変数にはアクセサ(private変数にアクセスするメソッド。要するにゲッター、セッター。)が用意されている場合この方法ではなくてアクセサを通して得た値でテストをしてください。アクセサのなかにはテストしたいオブジェクトの状態を持つprivate変数の値に影響を与えている物もあるからです。
そんなときはアクセス権を動的に変更して、private変数に直接アクセスしちゃいましょう!
こちらを参考にしました。
クラス Field
リフレクションの学習
サンプルコード:
// Test.java
public class Test {
public static main(String[] args) {
PrivateVariable pv = new PrivateVariable();
// System.out.print(pv.himitu);
// ↑このコードはprivateの変数を呼び出してるのでコンパイルエラー
Field field = pv.getClass().getDeclaredField("himitu");
// ↑対象のオブジェクトからクラスをとってgetDeclaredField()を使ってprivate変数を取得しています。渡している文字列は変数名です。
field.setAccessible(true);
// ↑取得したFieldオブジェクトのアクセスチェックするしないの指定。
//trueを渡すとアクセスチェックが抑制され、private変数も呼び出せるようになる。
System.out.print(field.get(pv));
// ↑Fieldオブジェクトにprivate変数があるオブジェクトを渡して値を取得する。
}
}
// PrivateVariable.java
public class PrivateVariable {
private String himitu = "実は俺・・・";
}
上記のコードを実行するとコンソールに「実は俺・・・」と表示され、PrivateVariableクラスのprivate変数himituにアクセスできたことがわかります。
これでいちいち回りくどいユニットテストを書かずに、private変数にアクセスして単純なテストケースを書けるようになりました!
※注意事項
private変数にはアクセサ(private変数にアクセスするメソッド。要するにゲッター、セッター。)が用意されている場合この方法ではなくてアクセサを通して得た値でテストをしてください。アクセサのなかにはテストしたいオブジェクトの状態を持つprivate変数の値に影響を与えている物もあるからです。
登録:
投稿 (Atom)