静的ネストクラスを複数回インスタンス化できますか?
-
01-10-2019 - |
質問
プログラミングの他のすべてのタイプの静的機能について私が知っていることを考えると、答えは「いいえ」だと思います。ただし、ようなステートメントを見ています OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
不思議に思う。
解決
はい、のセマンティクスには何もありません static
あなたがそれをするのを止めるネストされたタイプ。このスニペットは正常に実行されます。
public class MultipleNested {
static class Nested {
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Nested();
}
}
}
参照してください
public static interface Map.Entry<K,V>
public static class AbstractMap.SimpleEntry<K,V>
- おそらく最も有名なネストされたタイプ。明らかに複数回インスタンス化されています。
今、もちろん、ネストされたタイプは独自のインスタンス制御を行うことができます(例: private
コンストラクター、シングルトンパターンなど)が、それはネストされたタイプであるという事実とは何の関係もありません。また、ネストされたタイプがaの場合 static enum
, 、もちろん、まったくインスタンス化することはできません。
しかし、一般的に、はい、a static
ネストされたタイプは複数回インスタンス化できます。
技術的には、a static
ネストされたタイプは「内部」タイプではありません。
JLS 8.1.3内部クラスと囲いインスタンス
an 内側 クラスは、明示的または暗黙的に宣言されていないネストされたクラスです
static
.
つまり、JLS用語によると、 内側 クラスはそうではないものです static
. 。もし static
, 、それは単なるネストされたタイプです。
だから何をしますか static
平均?
static
単に、ネストされたタイプがインスタンス化されるために囲まれたタイプのインスタンスを必要としないことを意味します。
参照してください
他のヒント
@PolyGenElubricants:しかし、一般的に、はい、静的ネストされたタイプは複数回インスタンス化できます。
その100%を確実に確認するために、私はあなたのスニペットを拡張しました:
public class MultipleInner {
static class Inner {
private int state;
public int getState() { return state; }
public void setState(int state) { this.state = state; }
}
public static void main(String[] args) {
List<Inner> inners = new ArrayList<Inner>();
for (int i = 0; i < 100; i++) {
Inner inner = new Inner();
inner.setState(i);
inners.add(inner);
}
for (Inner inner : inners) {
System.out.println(inner.getState());
}
}
}
そしてもちろん、結果は次のとおりです。
0
1
2
3
.
.
.
97
98
99
合法です。内側のクラスが静的であるという事実は、ここであなたに利益をもたらします。そのインスタンスは、含まれるクラスのどのインスタンスにもバインドされていないため、アクセス予選で許可されている限り)自由にインスタンス化できます。
ただし、価格は、内部クラスでは、含まれるクラスの非静的メンバー/メソッドを使用できないことです。
ええ、あなたはあなたが望むだけ何度もそれのインスタンスを作ることができます。
たぶん、あなたがそれを見る理由は、プログラムがどこかに参照を保存することを考えていたからです。私はあなたに同意しますが、奇妙に思えます:s
内部クラスは、クラスを含む非静的メンバー/方法を使用できます。囲まれたクラスのオブジェクト参照を介してのみ使用できます -
public class MultipleInner {
private int outerstate =10;
static class Inner {
private int state;
public int getState() { return state; }
public void setState(int state) { this.state = state; }
}
public static void main(String[] args) {
Inner inner = new Inner();
inner.setState(new MultipleInner().outerstate);
System.out.println(inner.getState());
}
}
したがって、内部クラスは、囲まれたクラスの静的なメンバーにアクセスできないという価格を支払う必要はありません。
静的ネストされたクラスは確かにインスタンスです - 言われているように、「アウター」クラスの名前空間に住むトップレベルのクラスであり、「外側」クラスへの参照を尊重する静的セマンティクスに従います。このコードサンプルは次のことを示しています。
public class OuterClass {
String outerStr = "this is the outer class!!" ;
public static class StaticNestedClass {
String innerStr = "default / first instance" ;
}
public static void main(String[] args) {
OuterClass.StaticNestedClass nestedObject1 = new OuterClass.StaticNestedClass();
OuterClass.StaticNestedClass nestedObject2 = new OuterClass.StaticNestedClass();
nestedObject2.innerStr = "second instance" ;
System.out.println(nestedObject1.innerStr) ;
System.out.println(nestedObject2.innerStr) ;
}
}
output:
default / first instance
second instance