|







Microsoft MVP for Visual Developer - J# |
|
- 拡張クラスからその基底クラスの内部クラスを参照できない。下記の例では、Application クラスの"Derived.Inner
I2 = D1.GetInner();"の行で、Derived.Inner という表現がエラーになる。
public class Parent {
public static class Inner {
Inner() {
}
}
public Inner GetInner() {
return new Inner();
}
}
public class Derived extends Parent {
public void DoSomething() {
/* OK Inner class of parent is
visible here */
Inner I1 = GetInner();
}
}
public class Application {
public void DoSomething() {
Parent P1 = new Parent();
/* OK, Inner class visible through
parent */
Parent.Inner I1 = P1.GetInner();
Derived D1 = new Derived();
/* NOT OK, error VJS1161: Cannot find
class 'Derived.Inner' error here */
Derived.Inner I2 = D1.GetInner();
}
}
- イニシャライズ部にバグがあるコードのエラーを検出しない。次のコードは、コンパイルに失敗すべき。(FDBK49016)
Workaround --- プログラムのバグを修正する。
public class Program {
public static final int A = 10;
public static final int B;
public static final int A_PLUS_B = A + B;
static {
B = 100;
}
public static void main(String[] args) {
System.out.println(A);
System.out.println(B);
System.out.println(A_PLUS_B);
}
}
- あるクラスが別のパッケージ
を拡張し、その基本クラスと拡張クラスに戻り値のシグナチャのみが異なるパッケージローカルのメンバがある場合に、コンパイルに失敗する。(FDBK48950)
Workaround --- どちらかのメソッドの名前を変更する。
package package1;
public class Program extends package2.BaseClass {
public static void main(String[] args) {
System.out.println(new
Program().method());
}
int method() {
return 0;
}
}
package package2;
public class BaseClass {
boolean method() {
return false;
}
}
- パッケージローカルクラス(AbstractClass)を拡張(ExtendedClass)した場合、AbstractClassから継承したメソッドを呼び出すコードがVJS1161:
Cannot find type 'ujihara.ExtendedClass' エラーになる。(FDBK41396)
Workaround --- AbstractClassをパブリッククラスとする。
public class Program { public static void main(String[] args) { new ujihara.ExtendedClass().method(); } }
package ujihara; public class ExtendedClass extends AbstractClass { }
package ujihara; abstract class AbstractClass { public void method() { System.out.println("method called."); } }
- 内部クラスが外部クラスを継承している場合に、間違ったILを生成する場合がある。たとえば、次のプログラムは、2 3 を出力すべきであるが、実際には、1 3を出力する。(FDBK41674)
public class Program {
int field = 0;
public Program.Inner createInner() {
return new Inner();
}
public static void main(String[] args) throws Exception {
Program p = new Program();
p.field = 1;
Program.Inner i = p.createInner();
i.field = 2;
i.setField(3);
System.out.println(p.field);
System.out.println(i.field);
}
public class Inner extends Program {
void setField(int v) {
Program.this.field
= v;
}
}
}
- カスタムモディファイアを持った型(C++/CLRのlongなど WinFx2.0で導入)を参照すると、間違ったILを出力する。(FDBK40805)
a.cpp:
#using <mscorlib.dll>
#include <stdio.h>
using namespace System;
namespace AA {
public ref class A {
public:
unsigned long Print() {
printf("Hello\n");
return 0;
}
};
}
b.jsl:
import AA.*;
public class Test {
public static void main(String[] args) {
A a = new A();
a.Print();
}
}
- 次のようなコードでは、太字の m は B.m と解釈されるべきだが、A.m と解釈し、それがアクセスできないというエラーが発生する。
(FDBK38703)
Workaround --- mがどのクラスに属しているのかを明示的に指定する。
public class A { private String m = "A.m"; }
public class B { private String m = "B.m"; // public int m; でも同じ結果
public class C extends A { public String method() { return m; //
mが参照できないというエラーが発生。 } } }
- 次のように、同じ名前の内部インターフェースを同時にインプリメントしているコードをコンパイルすると InterfaceName
が2回実装されているというエラーが発生する。 (FDBK38702)
Workaround --- どちらかのインターフェースの名前を変更する。
public class Class1 {
public interface InterfaceName {
}
}
public class Class2 {
public interface InterfaceName {
}
}
public class Program implements Class1.InterfaceName, Class2.InterfaceName
{
public static void main(String[] args) {
}
}
- interface を extends しても、派生クラスで、再定義する必要がある場合がある。(実証コード探索中)
- staticフィールドの初期化がされないことがある。(実証コード探索中)
- 巨大なプロジェクト(特に、エラーが含まれている場合)は、コンパイル中に落ちる。
シリアル化
- java.io.Serializable ンターフェースを実装していないクラスのClassオブジェクト(クラスのオブジェクトではない)
は、シリアル化できるが、逆シリア
ル化できない。(FDBK168674)
import java.io.*;
public class Program {
public static void main(String[] args) throws Exception
{
ByteArrayOutputStream buffer = new
ByteArrayOutputStream();
ObjectOutputStream out = new
ObjectOutputStream(buffer);
out.writeObject(Class1.class);
out.writeObject(Program.class);
out.close();
ByteArrayInputStream bias = new
ByteArrayInputStream(buffer.toByteArray());
ObjectInputStream in = new ObjectInputStream(bias);
in.readObject(); // Class1.class can deserialize.
in.readObject(); // But, Program.class is not.
NullReferenceException is thrown here.
in.close();
}
}
class Class1 implements Serializable {
}
- 他にも、うまく動作しない場合多数。
java.lang.String
- 実体は System.String のシノニムである。
- Comparableにキャストすると、com.ms.vjsharp.lang.Wrapper.ComparableWrapperForStringというラッパークラスとなる。
これに関連して、次のバグが発生。
- ((Object)"abc").equals((Comparable)"abc")
returns false. (FDBK41211)
- getBytesがない。
- .NETでStringにないメソッドは、実際にはヘルパークラスの静的メソッドの呼び出しになる。 これらのメソッドに関連するバグ
- String.CASE_INSENSITIVE_ORDER.compare("abc",
"ABC") により System.FieldAccessException
が発生する。
(FDBK41209)
java.math
- java.math.BigInterger#shiftLeft(int)
のバイトを超える繰り上がりが、負の場合、正常に動作しない。たとえば、new BigInteger("-1").shiftLeft(8)
は例外を発生し、new BigInteger("-2").shiftLeft(7) は、0
を返す(正しくは、-256)。
java.net
java.net.URL
- new URL(String url) のurlとして、file:filename.txt のようなフォーマットをうまく処理しない。
- new URL(URL context, String spec) の spec 中に .. が含まれている場合に、toString()
の値が正規化されていない。具体的には、new URL(new URL("http://test.com/a/b.c"),
"../d.e") が、http://test.com/d.e ではなく http://test.com/a/../d.e
となる。(FDBK169492)
- URL のデフォルトポート番号を正常に扱わない。たとえば、new URL("http://test.com:80/").equals(new
URL("http://test.com/")) は、true を返すべきだが、VJ#では false となる。(FDBK170511)
javax.swing.JTree
- setModel(TreeModel newModel) で newModel を null とすると IllegalArgumentException
が発生する。(FDBK38683)
java.text.DateFormat
java.text.StringCharacterIterator
- new java.text.StringCharacterIterator("ABC", 0, 3,
0).setIndex(3) throws IllegalArgumentException.(FDBK168924)
java.util.ArrayList
java.util.GregorianCalendar
- 次のコードで、Java は、(eD, eM) = (28, 1) を返すが、J#では、(3, 2) を返す。(FDBK98510)
GregorianCalendar gcal = new GregorianCalendar(2006, 0, 31);
gcal.add(GregorianCalendar.MONTH, 1);
int eD = gcal.get(GregorianCalendar.DAY_OF_MONTH);
int eM = gcal.get(GregorianCalendar.MONTH);
java.util.TreeMap
- 正常に動作しない。
Workaround --- new TreeMap(...) を、new jp.ujihara.jsharp.util.TreeMap(...)とする。
|