|









Microsoft MVP for Visual Developer - J# |
|
J#言語とは
- Java 言語を .NET Framework 上で利用することを目的とした言語です。.NET 用のキーワードを加え、Java
と .NET
との間でメソッド名が合わない部分については、メンバ関数を静的関数にするなどの方法によってその違いを吸収しようとします。
- Object、String
クラスは、どちらの処理系でも非常に重要であるが、メソッドの名前、数、機能に違いがある。この問題に対して、C#3.0 の
extended method と同等の手法でその違いを吸収しています。
- 逆アセンブルすると、初期化の違いの吸収のためのメソッド呼び出しをするなど、想像以上にいろいろなコードが挿入されていることが分かります。
- Visual Studio
に含まれる言語の中では、もっとも使われていませんが、もっとも高度な処理をしているコンパイラだと思います。ただし、重大なバグ
も数多く残っているだけに残念です。
- delegate、multicast 、ubyte、enum(JDK1.4以前と比較する場合)が、予約語である。
- ubyte --- 符号なし8ビット整数。CLR の System.Byte にあたるもの
- enum、delegate --- C#と同様
- multicast --- C#の event とほぼ同様
- protected や package scoped は、public としてコンパイルされる。
大きな問題ではないが、System.Reflection 名前空間のクラスによりリフレクションを行った場合に、protectedメソッドも得られてしまうという問題がある。(最近のIKVMも同様
)カスタム属性を見ることによりこれらの違いを知ることもできるが、仕様は非公開である。
ちなみに、C#の protected メンバは派生クラスからしか可視ではないが、Javaの protected
メンバは派生クラスからだけでなく同一パッケージ内のクラスからも可視となり C#
のそれよりも公開範囲が広い。C#でそれにあたる概念は protected internal である。
- Object型のメソッドのうち、toString, hashCode, cloneは、それぞれ、ToString, GetHashCode,
MemberwiseClone にコンパイル時に、変換されている。そのため、System.Reflection 名前空間のクラスを使ってリフレクションにより toString
メソッドを問い合わせても、そのようなメソッドがないと返される。
- String型にも、Object型と同じ問題がある。
- String型のメソッドのいくつかは、ヘルパー関数の静的メソッドとしてコンパイルされる(C#3.0 の extended method
を先取りしている)。
- 8ビットの値型について:J# の byte は符号付き(signed)であるが、C# の byte は
符号なし(unsigned)である。J# では符号なし8ビット値型は ubyte
というキーワードで表す。JavaとWinFxでは常用される8ビット値型が異なるため、特に配列を橋渡しする場合に面倒なことになる。.NET
Framework 1.1までは符号を変えた新たな配列を確保しコピーするしかなかったが、.NET
Framework 2.0 より、'(ubyte[])(Object)byteArray'のようにして、System.SByte[] と System.Byte[]
との間で相互変換を行うことができるようにな
り、容易かつ効率的に変換できるようになった(JIT後のコードでは、変換の実行時コストはない)。
あまり知られていないようだが、このテクニックは8ビット値型に限らず、列挙やValueType(C#ではstruct)でも使える。
- Systemという語が、CLR のSystem名前空間とjava.lang.Systemクラスの二つの意味で混在している
ため、J#で CLR の処理を記述すると、分かりにくいコードになる場合がある。
- CLR の interface は、それを実装しているクラスはそのインターフェースにキャストができるという意味であるが、Java の interface は、interface にあるメソッドを、それを実装しているクラスが implement しているということを意味している。
そのため、インターフェースの実装をprivateメソッドで行っているようなクラスは、J#からの利用に制限がある。
- Java では Erasure という仕組みを使って generic を実現している。そのため、オブジェクトそれ自体には
generic に関する情報は含まれていない。そのため、Java では List<Integer> と List<Float>
は実行時には同じクラスである。一方、CLR は generic 型もそれぞれが独立した型である。
- Java は、インターフェース中で、定数を宣言することができるし、J#、CLR でも可能だが、C#からこれを
簡単に参照する方法がない。別にクラス(内部クラス、abstract class でもよい)を作成してそこに宣言を移すなどの工夫が必要。
- Java は、ひとつのクラス中に同じ名前のフィールドとメソッドを共存させることができるが、そのようなメソッド・フィールドはC#から使
うことができない。
- C# の unsafe の機能はなくポインタをあつかうことができない。アンマネージドのメモリの操作は、J++からある com.ms.dll.DllLib
クラスの静的メソッド、IntPtr などを使う。
- ボックス化 - (System.Int32)(100)
- ボックス化解除 - (int)(System.Int32)(o)
- System.Byte - ubyte
- enum, delegate, eventなどのキーワード追加
- 構造体は、System.ValueType を拡張することにより、宣言可能。具体的には、final class
class-name extends System.ValueType のようにする。
- パラメータの参照渡しは、/** @ref */により可能。
- プロパティの宣言は、/** @property */により可能。
- BEANSプロパティは、/** @beansproperty */により CLR のプロパティとすることができる。
Tips
- AWT 関係も動作します。
- Swing も、VJSSupUILib を参照に追加することにより利用できます。
|