質問
2 つのクラスがあり、一方のクラスの静的インスタンスをもう一方のクラスの中に含めて、最初のクラスを介して 2 番目のクラスから静的フィールドにアクセスしたいと考えています。
これは、同じ名前を持つ異なるインスタンスを作成できるようにするためです。
Class A
{
public static package1.Foo foo;
}
Class B
{
public static package2.Foo foo;
}
//package1
Foo
{
public final static int bar = 1;
}
// package2
Foo
{
public final static int bar = 2;
}
// usage
assertEquals(A.foo.bar, 1);
assertEquals(B.foo.bar, 2);
これは機能しますが、「静的フィールド Foo.bar には静的方法でアクセスする必要があります」という警告が表示されます。誰かがその理由を説明し、「正しい」実装を提供してもらえませんか。
静的インスタンスに直接アクセスできることはわかっていますが、パッケージ階層が長い場合、それは見苦しくなります。
assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
解決
あなたがおそらくこれについて間違った方法で考えているという他の人たちに私も同意します。さて、静的メンバーのみにアクセスする場合、これはうまくいくかもしれません。
public class A {
public static class Foo extends package1.Foo {}
}
public class B {
public static class Foo extends package2.Foo {}
}
他のヒント
以下を使用する必要があります。
Foo.bar
そしてそうではありません:
A.foo.bar
それが警告の意味です。
その理由は、 bar
のメンバーではありません 実例 の Foo
. 。それよりも、 bar
グローバル、クラス上です Foo
. 。コンパイラは、インスタンスのメンバーであるかのように振る舞うのではなく、グローバルに参照することを要求します。
静的メンバーにアクセスするだけであれば、これら 2 つの静的変数をクラスに配置しても意味がありません。コンパイラは、次のようなクラス名プレフィックスを介してアクセスすることを期待しています。
package1.Foo.bar
package2.Foo.bar
オブジェクトを作成したら、次のようにします。
public static package1.Foo foo;
静的な方法でアクセスされていません。クラスをアドレス指定するには、クラス名と、もちろん完全なパッケージ名を使用する必要があります。クラスは異なるパッケージで同じ名前を持っているためです。
Foo インスタンスが Foo の静的フィールドにアクセスできるのは事実ですが、「静的」という言葉について考えてみましょう。少なくともこの場合、それは「静的にバインドされる」ことを意味します。A.foo は Foo 型であるため、「A.foo.bar」はオブジェクトに「bar」を要求せず、直接クラスにアクセスします。つまり、サブクラスに「bar」という静的フィールドがあり、foo がそのサブクラスのインスタンスである場合でも、FooSubclass.bar ではなく Foo.bar が取得されます。したがって、継承を利用しようとすると大変なことになるため、クラス名で参照することをお勧めします。