Java言語

似たもの技術:サーバサイドJavaとメインフレーム

似てると言っても、サーバサイドJavaのXMLによる面倒くさい設定とメインフレームにおけるJCLの面倒くさい記述が似てるなぁと思っただけなんだけど。

JavaとC

SPECjvm98の_201_compressをC言語に移植して性能を測定した。移植したソースはここに載せるとマズいと思うので秘密。Javaで書かれたプログラムをCに移植する際に色々とやり方はあると思うが、とりあえずJavaのクラスは構造体とした。compressはオブジェクト…

メソッド内で定義されている内部クラスがメソッドのローカル変数を参照する場合、その変数はfinalでなければならない

しかし、Java言語の内部クラスを設計している最中は「finalでなくともよい」という選択肢も検討されたようだ。その場合、ローカル変数はスタックでなくヒープに割り当てないといけない*1。当時のJava言語は明示的にnewする以外はヒープからのメモリ確保はし…

フィールドは final かつ volatile にはできない

JLS2 8.3.1.4 より。 class FinalVolatileField { final volatile int i = 0; // コンパイルエラー }

メンバクラスは他のメンバクラスの private フィールドを参照できる

JLS2 6.6.1, 8.3 より。 class InnerPrivateField { class Inner1 { private int i; } class Inner2 { int test() { Inner1 obj = new Inner1(); return obj.i; // OK } } }この例の場合、Inner1 クラスの privateフィールド i のスコープは外側のクラスであ…

同じシグネチャの複数のメソッドを一つのメソッドで実装してもよい

JLS2 8.1.4 より。 interface SameSigInterface1 { int test(); } interface SameSigInterface2 { int test(); } class SameSigInterfaceImpl implements SameSigInterface1, SameSigInterface2 { public int test() { return 0; } }

継承関係のループは可能な限りコンパイル時にチェックされる

JLS2 8.1.3 より。 // コンパイルエラー class ClassCircularity1 extends ClassCircularity2 { } class ClassCircularity2 extends ClassCircularity1 { }コンパイル時にチェックできなかった継承関係のループは実行時に ClassCircularityError として検出…

static コンテキストについて

JLS2 8.1.2 より。static コンテキスト内で定義された内部クラスは外側のクラスへの参照を持たないので、例えば外側のクラスのインスタンス変数などへはアクセスできない。 class StaticContext { // static コンテキストではない Object o1 = new Object() …

インタフェース内で定義されたメンバクラスは static と見なされる

JLS2 9.5 より。 interface ClassInInterface { class Inner { } } class ClassInInterfaceImpl implements ClassInInterface { static void test() { Inner obj = new Inner(); // OK } }

ローカルクラスがローカル変数を参照する場合、final でなければならない

JLS2 8.1.2 より。ローカルクラスの生存期間はそれを囲むブロックの生存期間より長い可能性があるから。 class LocalClass { void test(final int arg) { final int i = 100; class Inner { // Inner クラスのコンストラクタは // 外側のオブジェクトへの参…

たとえ static コンテキストで宣言されていても、内部クラスは内部クラスなので static メンバを持つことはできない

JLS2 8.1.2 より。ネストクラスでも内部クラスでなければ static メンバを持つことができる。内部クラスでないネストクラスとは、static 宣言されているメンバクラスか、メンバインタフェースのこと。 class StaticButInner { static class NotInner { stati…

内部クラスは static メンバを持てないが、親クラスから継承はできる

JLS2 8.1.2 より。 class InnerStaticInheritence { static int i; } class InnerStaticInheritenceOuter { class Inner extends InnerStaticInheritence { // コンパイルエラー static int i; } int test() { return Inner.i; } }内部クラスがなんで static…

実装できないような abstract クラスは作れない

JLS2 8.1.1.1 より。当たり前といえば当たり前だが。 interface CannotImplementIntf1 { void test(); } interface CannotImplementIntf2 { int test(); } abstract class CannotImplement implements CannotImplementIntf1 { // コンパイルエラー public ab…

ある名前が型名とフィールド名の両方で解釈できる場合、フィールド名としての解釈が優先される

JLS2 6.3.2, 6.5 より。 package foo; class ObscuredName { Inner foo = new Inner(); static int i = 0 ; int test() { // ObsucuredName#i ではなく、Inner2#i へのアクセスと解釈される。 // foo.ObscuredName を解釈する際に型の名前よりも // フィール…

private なメンバはその宣言を囲むトップレベルクラスの中で参照できる

JLS2 6.6.1 より。 class PrivateField { private int private_i; private void private_meth() { } int test() { Internal obj = new Internal(); return obj.private_j; } class Inner { private int private_j; int read() { return private_i; } void wr…

たとえ子クラスからでもprotectedフィールドに無制限にアクセスできるわけではない

JLS2 6.6.2, 6.6.7 より。 package foo; public class ProtectedField { protected int i; }package bar; import foo.ProtectedField; public class ProtectedFieldChild extends ProtectedField { int test(ProtectedFieldChild p) { // OK return p.i; } i…

protected なコンストラクタは子クラスから単純な new ではアクセスできない

JLS2 6.6.2.2 より。でも、super() や無名クラス生成を通じてはアクセスできる。 package foo; public class ProtectedConstructor { protected ProtectedConstructor() { } }package bar; import foo.ProtectedConstructor; class ProtectedConstructorChil…

enclosingクラスと同じ名前の内部クラスは定義できない

JLS2 6.3 より。でもなぜ? class SameNameType { // コンパイルエラー class SameNameType { } void test() { // コンパイルエラー class SameNameType { } } }

メンバは同じ名前でもよい

JLS2 6.4.2 より。 class SameNameMembers { int hello; void hello() { } class hello { } }研修の合間を縫ってJava言語規格(JLS)を読んでみる。JavaVM規格は何回も読んだけどJLSを真面目に読むのは初めて。