特集 J#の真実 Part 2

2.ライブラリの互換性(1)

株式会社ピーデー 川俣 晶
2001/11/16

Page1 Page2 Page3 Page4 Page5

ライブラリの互換性

 前ページにあるVS .NETの2つめの画面「不要なファイルをプロジェクトから取り除き、再ビルドしたときの画面」の“Stray semicolon”の羅列の下を見ると、“Can't find type 'MalformedInputException'”というメッセージが表示されている。MalformedInputExceptionという例外を知らないJavaプログラマも多いと思うが、これは標準クラス・ライブラリの一部ではなく、“sun.io.MalformedInputException”というフルネームから分かるとおり、通常は公開されていない、sunが実装に使うクラスである。本来なら、このようなクラスを使うべきではないのだが、この例外が発生するケースがあったので、やむなく対応した。この例外の機能は、文字コード変換を行うときに、変換すべき文字がないことを知らせるものである。実際に運用していると、異常データの入力時にこの例外が発生するので、対応はさぼれなかったのだ。

 このことから分かるのは、J#が持つJDK 1.1.4互換のクラス・ライブラリも、コンパイラ同様、新規に書き起こされたものらしいということだ。Sunのコードを継承していない。そのため、実装にのみ使われる内部的なクラスは再現されていないと考えられる。

 ともかく、この例外は発生しないものと考えて、その関係のコードはすべて取り除いた。そして、実行してみた。

 まだうまく動かない。次に食らったのは、UnsupportedEncodingExceptionだ。調べてみると、多くのエンコーディング名を使おうとするとUnsupportedEncodingExceptionが発生する。筆者が確かめた結果を以下に示す。

使用可能なエンコーディング名:

  • UTF8

使用不可能なエンコーディング名:

  • JIS
  • ISO-2022-JP
  • SJIS
  • Shift_JIS
  • EUC-JP
  • CP932
  • UTF-16
  • UTF-8

 ドキュメントを見ると、シフトJISなどはサポートしないということが明示されていた。これがベータ1だけの問題か、製品版にも適用される制約なのかは分からないが、少なくとも、シフトJISすらサポートしない製品になってしまうと、日本での実用性は限りなくゼロに等しくなるだろう。

 仕方がないので、自分で対策することに決めた。といっても、文字コード変換を全部自作するわけではない。.NET Framework自身が持っている文字コード変換を呼べばすむわけである。ここで発生する「混合言語問題」は次の項目で述べる。

 さて、具体的に文字列単位の文字コード変換として、こんなものを書いてみた。

 1: public class DotNetString
 2: {
 3:   private System.String s;
 4:   private String dotNetEncName( String encodingName ) throws java.io.UnsupportedEncodingException
 5:   {
 6:     if( encodingName.equalsIgnoreCase("SJIS") )
 7:     {
 8:       return "Shift_JIS";
 9:     }
10:     if( encodingName.equalsIgnoreCase("JIS") )
11:     {
12:       return "ISO-2022-JP";
13:     }
14:     if( encodingName.equalsIgnoreCase("8859_1") )
15:     {
16:       return "ISO-8859-1";
17:     }
18:     throw new java.io.UnsupportedEncodingException(encodingName);
19:   }
20:   public String toString()
21:   {
22:     return String.fromString(s);
23:   }
24:   public byte [] getBytes( String encodingName ) throws java.io.UnsupportedEncodingException
25:   {
26:     ubyte [] uar = System.Text.Encoding.GetEncoding( dotNetEncName( encodingName ) ).GetBytes(s);
27:     byte [] ar = new byte[uar.length];
28:     for( int i=0; i<uar.length; i++ )
29:     {
30:       ar[i] = (byte)uar[i];
31:     }
32:     return ar;
33:   }
34:   public DotNetString( byte [] ar, int offset, int count, String encodingName ) throws java.io.UnsupportedEncodingException
35:   {
36:     ubyte [] uar = new ubyte[count];
37:     for( int i=0; i<count; i++ )
38:     {
39:       uar[i] = (ubyte)ar[i+offset];
40:     }
41:     s = System.Text.Encoding.GetEncoding( dotNetEncName( encodingName ) ).GetString( uar );
42:   }
43:   public DotNetString( byte [] ar, String encodingName ) throws java.io.UnsupportedEncodingException
44:   {
45:     ubyte [] uar = new ubyte[ar.length];
46:     for( int i=0; i<ar.length; i++ )
47:     {
48:       uar[i] = (ubyte)ar[i];
49:     }
50:     s = System.Text.Encoding.GetEncoding( dotNetEncName( encodingName ) ).GetString( uar );
51:   }
52:   public DotNetString( String s )
53:   {
54:     this.s = s;
55:   }
56:   public DotNetString()
57:   {
58:     s = "";
59:   }
60: }
文字列単位の文字コード変換を行うクラスのソースコード
Java言語から.NET Frameworkのクラス・ライブラリにある文字コード変換を利用している。

 文字列ベースの変換時は、このクラスを使うようにコードを直せばよい。


 INDEX
  [特集]J#の真実
  Part 2 JavaからJ#へ:プログラム移植の実際
    1.Visual J++ 6.0からの移行とコンパイラの互換性
  2.ライブラリの互換性(1)
    3.ライブラリの互換性(2)
    4.Javaと他言語のインターフェイス
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間