- PR -

特集「私がJavaからC#に乗り換えた10の理由」について

投稿者投稿内容
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-07-20 20:28
引用:

Ken-Labさんの書き込み (2003-07-20 19:07) より:
C#がDLLの上に構築されているのに対し


.NET のアセンブリが実行ファイルや DLL の形をしているのは、形式的な理由だったと思います。Java では Java VM という座布団の上にあるのと同じように、C# の場合は CLI という座布団の上にあります。メソッド参照とオブジェクトの違いは、英-Ran さんがおっしゃるとおりで、政治的な理由と考えるのが素直ですね。
#私が少し前に書いた「API/COM」の話は、(これが正しいかどうかはわかりませんが、正しい
#とすれば)政治的な理由の 1 つといえます。

引用:

英-Ranさんの書き込み (2003-07-20 19:32) より:
C#のCLIってJava VMと同じ役割を果たすものだと私は認識していたのですが、もしかして違うのかな?


上の記述から明らかでしょうが、その認識であっているはずです。
#少なくとも私はそのように認識しています。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2003-07-20 21:09
JavaのInnerClassについての個人的な質問なんですが(Javaはあまり詳しくないんです)。
C++で実現するならば、以下のようになるんでしょうか?

コード:

/*--------- sample.h ----------*/
class SamplesXXXListener : public IXXXListener {
private:
shared_ptr<Sample> p;
public:
SamplesXXXListener(shared_ptr<Sample> _p);

void Listen(...);
};


class Sample
{
friend class XXXListener;
...
}


コード:

/*-------- sample.cpp ---------*/
#include "sample.h"

SamplesXXXListener::SamplesXXXListener(shared_ptr<Sample> _p) {
this->p = _p;
}

SamplesXXXListener::Listen(...) {
...
}



無名ではありませんが、C++だと無名クラスは作れないのでご容赦ください(同じくクラス参照の隠蔽性とListenerでのSampleクラスアクセスに「p->」がいるのも)。
ちなみにtemplateを使えばもうちょいいい実装にできそうですが、それはまぁ後回しということで。

もしこれでいいのなら少し思うところがあります。

[ メッセージ編集済み 編集者: ya 編集日時 2003-07-20 21:11 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-20 21:23
引用:

委譲処理でC#ではメソッド参照、Javaでは無名InnerClassなのは、
技術的な問題というより政治上の問題だと私は認識しています。


引用:

.NET のアセンブリが実行ファイルや DLL の形をしているのは、形式的な理由だったと思います。Java では Java VM という座布団の上にあるのと同じように、C# の場合は CLI という座布団の上にあります。メソッド参照とオブジェクトの違いは、英-Ran さんがおっしゃるとおりで、政治的な理由と考えるのが素直ですね。


英-Ranさん、IZUMIさん、解説ありがとうございました。
政治上の問題ですか。ちょっと拍子抜けです。しかし、無名inner classがわかりにくい
と判断したMicrosoftさんにはちょっと疑問が残りますね。

# 今日はMacOS XにCLI実装をやっています。一回ビルドに失敗してしまったんで、手土産は
# ございません。失礼しました。
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-20 22:21
うーん、私はメソッド参照とオブジェクトの違いは、政治的な理由ではないと思ってるのですが……(政治的理由でしょう?ってつっこみたくなる箇所は他に多々ありますし(笑))

ここの話になると、やはり「C#のdelegate」と「Javaのinner class」の比較議論になると思います。
今までの議論から、これら2つを比較したときに、「なにゆえ既存の概念の範囲内で実現できることを、わざわざ新しい概念を導入した手法で実現しようとしているか?」ですよね。

改めてその線で議論してみたいと思うのですがいかがでしょうか?

引用:

yaさんの書き込み (2003-07-20 21:09) より:
JavaのInnerClassについての個人的な質問なんですが(Javaはあまり詳しくないんです)。
C++で実現するならば、以下のようになるんでしょうか?


私もそうなると思います。以前の私の意見でありました、インナークラスはアウタークラスのインスタンスへの参照を隠し持っている、も表現できていますし。

引用:

Ken-Labさんの書き込み (2003-07-20 21:23) より:
政治上の問題ですか。ちょっと拍子抜けです。しかし、無名inner classがわかりにくい
と判断したMicrosoftさんにはちょっと疑問が残りますね。


私は、無名inner classをわかりにくい、と判断して採用しなかったのではないと思います。(実際、そんなにわかりにくい概念ではありませんし…)

では何を問題視したかというと、メソッド呼び出し直後のコンテキスト、だと思います。(inner classの場合、コンテキストはinner classのインスタンス。delegateの場合、Javaでいうところのouter classのインスタンスがコンテキストになります)

引用:
英-Ranさんの書き込み (2003-07-20 19:38) より:
うーむ、それってプログラマは楽だけど、メモリリークの原因になったりしないんだろうか。



すみません。そういう観点から考えてみたことがありませんでした。
一応、考えるだけ考えてみたのですがメモリリークの原因になりそうな理由が思いつきません。(たしかに委譲先への参照を保持していますが、それはデリゲートインスタンス自身への参照が失われるときに、同時に失われる参照ですから、直接的な参照とメモリ管理上は変わりありませんし…)

[ メッセージ編集済み 編集者: k-nak 編集日時 2003-07-20 22:23 ]
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-20 22:41
すいません。追記です。
inner classのコンテキストについてはあってると思うのですが、無名inner classの場合、たしか少々話が違ってくるんですよね? ここらへん整理して改めて意見させていただきます。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-20 23:25
k-nak様 >
引用:

うーん、私はメソッド参照とオブジェクトの違いは、政治的な理由ではないと思ってるのですが……(政治的理由でしょう?ってつっこみたくなる箇所は他に多々ありますし(笑))

ここの話になると、やはり「C#のdelegate」と「Javaのinner class」の比較議論になると思います。


政治的な理由の背景には歴史的な裏付けがあるのは事実ですし、それぞれ技術的な見解があったはずです。それにつきましては、私も下調べが必要ですので改めて議論したいと考えます。
# inner classで無名であることの意味は、確か継承先がないことから、記述を楽にする
# 目的で取り入れていると解釈していますが、裏をとっておきます。
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-07-21 04:34
yamasaです。

引用:

英-Ranさんの書き込み (2003-07-20 19:38) より:
うーむ、それってプログラマは楽だけど、メモリリークの原因になったりしないんだろうか。


むしろ、うっかりミスによりメモリリークの原因を作ってしまいがちなのは
Java の inner class の方でしょうね。

C# の delegate の場合、委譲先instanceへの参照を持つかどうかは
委譲されるメソッドが static として定義されているかどうかで決まります。

一方、Java の anonymous class および local class の場合、
enclosing instance への参照を持つかどうかは
それらが定義されているコンテキストが static か否かで決まります。
よって、たとえば enclosing instance への参照を持たない anonymous class を
非staticメソッドの中で宣言することは不可能ということになります。

また、Java の member class についても、うっかり static と宣言し忘れた場合は
不要な enclosing instance への参照を持つことになってしまいます。
ここら辺の事情は、"Effective Java" の「項目18:非staticのメンバークラスより
staticのメンバークラスを選ぶ」にて詳しく解説されています。
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-21 07:20
引用:

yamasaさんの書き込み (2003-07-21 04:34) より:
むしろ、うっかりミスによりメモリリークの原因を作ってしまいがちなのは
Java の inner class の方でしょうね。

(中略)

また、Java の member class についても、うっかり static と宣言し忘れた場合は
不要な enclosing instance への参照を持つことになってしまいます。
ここら辺の事情は、"Effective Java" の「項目18:非staticのメンバークラスより
staticのメンバークラスを選ぶ」にて詳しく解説されています。



よくよく考えてみたらその通りでした……
昨日、Inner Classがコンパイル時にどのように展開されるのを調べていて、インスタンスを保持していることに気付きました。

# 親クラスへの参照がソースコード中に書いてない場合には、コンパイラが
# 参照を持たないように変換するような話をどこかで聞いたような……

【追記】↑javapで調べる限り上記記述のような最適化は行われないようです(j2sdk1.4.2で確認)

local変数の参照の扱いとごっちゃになってたようです。なんかアホなこと書いてしまいましたね。そう考えると、コンテキストの扱いというのはそれほど難しい問題じゃないような気がしてきました(ようするに、私は親クラスが内部クラスより先に解放される場合があるので参照保持で工夫があるのではという誤解をしていたのです)。

# 無名Inner Classはメソッド内で生成できるのでローカル変数の値を参照できる
# が、参照する変数にはfinalが必要で内部クラスのインスタンス生成時の値の
# ローカルコピーを持ちます

[ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-21 08:29 ]

スキルアップ/キャリアアップ(JOB@IT)