ミラーサイト作りました。今後はそちらをメインにするかも知れません。よろしくお願いします。

あれこれ備忘録 〜はてなブログ支店〜

もしもドロップシッピング」で販売サイト作ってみました。
あれこれ商店

画期的な無料家計簿アプリでお金の流れが一目で分かる

2011年07月27日

オートボクシングの落とし穴

Integer i1 = 1;
Integer i2 = 1;
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i1 == i2);
System.out.println(i3 == i4);


これは最初のprintlnはtrueになり、二つ目の出力はfalseになります。

何故でしょう。

それはオートボクシング(auto-boxing)という機能のせいだそうです。

javaはオブジェクト指向のプログラミング言語ですが、すべてをオブジェクトとして扱うとパフォーマンスの低下を招くなどの理由でintなど一部の変数の型としてプリミティブ型というオブジェクトではない型の変数を扱えるようにしてあります。
byte・short・int・long・float・double・char・booleanがプリミティブ型です。

これをオブジェクトとして扱うときにはint型の場合、
Integer intObj1 = new Integer(100);
Integer intObj2 = Integer.valueOf(2);


などといった形で100や2の値を持つIntegerクラスのオブジェクトを作って、これを例えばリストに格納したりします。

しかし、結構これは面倒です。

これを使ってもう一度整数の値として取り出して、計算などに使おうと思ったときには

int primitiveInt1 = intObj1.intValue();


などとします。

別のInteger型の変数に値だけ代入する場合には、

intObj2 = Integer.valueOf(intObj2.intValue());


これを計算で必要になる度にするのは面倒ですよね。

これを

intObj2 = primitiveInt1


のようにできるのがオートボクシング機能です。


しかし、これが落とし穴になるらしいのです。
もう一度見てみましょう。

Integer i1 = 1;
Integer i2 = 1;
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i1 == i2);
System.out.println(i3 == i4);



(i1 == i2)はtrueになるのに、(i3 == i4)はfalseになる。

これは何故か。

実は、そもそも(i1 == i2)も本来はfalseになるはずなのです。

(i1 == i2)というのはi1というオブジェクトとi2というオブジェクトは同じか?という判定を行っています。

i1とi2は別のオブジェクトなので本来はfalseなのですが、オートボクシングが効くとキャッシュされたIntegerが使われるそうで、

最初の

Integer i1 = 1


のときに、Integer.valueOf(1)で作られて返されたInteger型がキャッシュされていて、i2についても同じように定義されているので、このキャッシュされたものが使われるらしいのです。

だからこの場合、i1とi2は同じオブジェクトになるということです。

では、もう一方の(i3 == i4)はどうかというと、キャッシュが効く範囲がintの場合、-128から127なのでその範囲外の場合は別のオブジェクトとして定義されてしまいます。

その結果、(i3 == i4)はfalseになるのですね。


そういえば、今はどうか分かりませんが、以前はjavaの高速化手法として-128から127の範囲では

i++


よりも

i = i + 1


のほうが高速であるというのがありました。これはJVMで動くバイトコードが違うからだったと思います。


さて、もとの問題ですが、そもそも==をこの様に使うのは問題なので

i1.equals(i2);


のようにすると値を比較する方法としては正しく動きます。


Javaパフォーマンステクニック―サーバサイドプログラミングの最適化 (Java Performance and Scalability Vo)

Javaパフォーマンス戦略―高速プログラムの高速開発のためのイディオム集

Javaプラットフォームパフォーマンス―コードレベルのチューニングと開発プロセスへの統合 (The Java Series)

プロフェッショナルAndroidゲームプログラミング JavaとCによるハイパフォーマンスなゲームの作り方

posted by まっさん at 20:41 | Comment(0) | java | このブログの読者になる | 更新情報をチェックする

2011年07月11日

Android携帯メーカーはOracleにお金を払うのか?

オラクル、Android端末メーカーにライセンス料を請求か

AndroidはGoogle主導で作られたオープンソースのOSで各メーカーはこれに基づいてスマートフォンやタブレットPCを作っています。

なぜオラクルが出てくるのか?というと。。。

Oracleが「AndroidはJavaの知的所有権を侵害」とGoogleを訴える

最大で61億ドルにも - オラクル、AndroidによるJava特許侵害の被害額を算出


Androidの実行環境の技術はJavaの技術を侵害しているというのがオラクルの主張です。

Javaでコードを組んでいるのは問題ないが、それを使ってバイトコードを作ったりそれを実行する仮想マシンの技術はOracleが買収したSunのJava技術を利用しているのではないか?

ということでOracleはGoogleを訴えている訳です。


そして今回のニュースでは裁判の結果が出る前に、Android携帯を製造・販売しているメーカーにライセンス料を払えとオラクルが要求しているらしいということらしいのです。


Javaを巡るMicrosoftとSunの訴訟とどうちがうのでしょうか?

またChaiやKaffeなどのサードパーティ製のVMの扱いとどのような違いがあるのでしょうか?


GoogleはOracleのパテント訴訟を根拠レスと一蹴, オープンソースいじめの悪行と呼ぶ

Googleは当然AndroidはSunのJava技術を使っていないといって反論、反訴しているということですが、この記事の中で紹介されているように噂レベルの話として

Googleは事前にOracleかSunとJavaのライセンスに関して協議していて、決裂したあとでAndroidを発表した、ということになるとOracleにも理があるということですね。


Oracleが勝つかもしれないということが現実味を帯びてくると、いまのうちにOracleに対してライセンス料を払っておいた方が得だというメーカーも出てくるということでしょうし、Oracleもそれを狙ってのことなんでしょうかね。

さて、どうなるのでしょうか?

android用のゲーム、エミュレータを楽しみたい人のゲーム機
posted by まっさん at 16:56 | Comment(0) | java | このブログの読者になる | 更新情報をチェックする

2011年06月10日

非同期にはAsyncTwitterを使おう twitter4j

twitter4jでタイムラインを取得するとき、取得までの間処理が止まってしまうのが気になる場合はスレッドを作ってそこで処理してたのですが、AsyncTwitterクラスに非同期で処理を行う仕組みが用意されているそうです。

Twitter twitter = new TwitterFactory(confbuilder.build()).getInstance();

の代わりに

AsyncTwitter asyncTwitter = new AsyncTwitterFactory(confbuilder.build()).getInstance();

でAsyncTwitterクラスのインスタンスを作り、

asyncTwitter.addListener()

でTwitterListenerやそのアダプタークラスのTwitterAdapterをaddし、そこで非同期に処理された結果を使った操作を行うということだそうです。

ま、いずれにしろGUI(Swing)操作関係の処理はSwingWorkerやSwingUtilities.invokeLaterを使わなくてはいけないのは変わらないですけども。


参考URL
Twitter4Jの使い方‎ > ‎AsyncTwitter 陽昇れども地の底に光届かず

twitter4j-examples/src/main/java/twitter4j/examples/async/AsyncUpdate.java at master from yusuke/twitter4j - GitHub
posted by まっさん at 06:26 | Comment(0) | java | このブログの読者になる | 更新情報をチェックする

2011年06月09日

イベント処理や内部クラスでメンバー変数にアクセスする

イベント処理で何か処理をするときにメンバー変数にアクセスしたいときがあるとすると

Class classA
{
int variable;

add***Listener(new ***Adapter() {
public void someMethodInListenerClass(***Event e) {
variable = 10;
}
});
}

のような感じではダメで、

variable = 10;



classA.this.variable = 10;

にしなくてはいけない。


これを避けたい場合、classAに目的のListenerクラスをimplementsして、メソッドをオーバーライドするか、

Class classA implements ***Listener
{
int variable;

add***Listener(this);

public void someMethodInListenerClass(***Event e) {
variable = 10;
}
}


ほとんど同じようなものかもしれないが、メソッドを新たに作って内部クラスから呼び出すといい。

Class classA
{
int variable;

add***Listener(new ***Adapter() {
public void someMethodInListenerClass(***Event e) {
methodA(10);
}
});

void methodA(int i) {
variable = i;
}
}


MacでJava! Macに付属のXcodeで始めるJavaプログラミング入門 Java primer for Macintosh users 内容説明:Macintoshユーザを対象としたJava言語入門書。Javaを使って自分でプログラムを記述することを目的とする。プログラミング言語をMacintoshを使って学ぼうという人に最適。

アテイン Java講座入門編 上巻 ATTE-570 Java講座入門編 上巻 

アテイン Java講座入門編 中巻 ATTE-571 Java講座入門編 中巻

アテイン Java講座入門編 下巻 ATTE-572 Java講座入門編 下巻

新Java言語入門 シニア編 (Java言語実用マスターシリーズ) Java言語はC++をモデルに、あまりに多機能すぎる部分を解消し、メモリ管理などのクリティカルな部分はできるだけプログラマーが管理しないように設計された言語である。

Javaプログラミングのエッセンス Webアプリケーションを作って学ぶJava入門 Java以外の言語には多少経験があるもののJavaに関しては初心者だという読者を対象に書かれたチュートリアル。Webアプリケーションを構築しながら、Javaの基本的な機能をわかりやすく解説する。
posted by まっさん at 05:13 | Comment(0) | java | このブログの読者になる | 更新情報をチェックする

Swingのコンポーネント変更・再描画

Swingのコンポーネントの大きさを変更したり、文字を表示させたり、画像を更新したりするときにはイベントディスパッチスレッドで行われなければならないそうです。

別スレッドで何か処理をした結果をコンポーネントに反映させようと思ったとき、このことが問題になります。

Swing とスレッド

[java][swing] Swingスレッド処理-004(SwingWorkerについて) いろいろ備忘録日記

[Java][Swing] イベントディスパッチスレッド以外のスレッドからのイベントディスパッチスレッドへのアクセス yuu_nkjm blog

ということで、結論としては

SwingUtilities.invokeLater()を使うか、SwingWorkerを継承したクラスを作ってここで処理したいものをdoInBackground()で、その後のコンポーネントの変更処理をdone()で定義して使う。

ということになるのでしょう。

ある大元のクラスでJFrameを呼び出して、大元のクラスで処理された結果をJFrameで渡すときにはどうするのでしょうか?

JFrameを継承したSomeFrame frameを作って、処理結果を

frame.doSomething(String someVariable);


のようにして、渡すとき

doSomething(String str) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setTitle(str);
}
});
}


のような感じにすると、new Runnable()という内部クラスでfinalでない変数strを参照できないというエラーになります。

これはどうすればいいのでしょうか?

こういうことを考えなければいけないようなクラスの作り方をしている事自体がダメなんでしょうが。。。
posted by まっさん at 01:01 | Comment(0) | java | このブログの読者になる | 更新情報をチェックする

iPagerank ブログランキング・にほんブログ村へ
にほんブログ村 ランキングはこちらをクリック!

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。