静的ネストクラスと非静的ネストクラスの違いは何ですか?
8 に答える
内部クラスは、定義上、静的にすることはできないので、「静的なネストされたクラスと静的でないネストされたクラスの違いは何ですか?」として質問を書き直します。
非静的のネストされたクラスは、ネストされているクラスのメンバーに完全にアクセスできます。静的にネストされたクラスにはネストされたインスタンスへの参照がないため、静的にネストされたクラスは、非静的メソッドを呼び出したり、ネストされたクラスのインスタンスの非静的フィールドにアクセスしたりすることはできません。
そのような質問の知恵の源を見てみましょう:ジョシュア・ブロックの効果的なJava:
技術的には、静的内部クラスのようなものはありません。効果的なJavaによると、正しい用語は静的にネストされたクラスです。非静的なネストされたクラスは、匿名クラスやローカルクラスとともに、実際には内部クラスです。
そして今引用する:
非静的ネストされたクラスの各インスタンスは、それを含むクラスの囲んでいるインスタンスに暗黙的に関連付けられています...囲んでいるインスタンスでメソッドを呼び出すことができます。
静的にネストされたクラスは、それを囲むインスタンスにアクセスできません。スペースも少なくて済みます。
静的内部クラスと非静的内部クラスには2つの違いがあります。
メンバーのフィールドとメソッドを宣言する場合、非静的内部クラスに静的フィールドとメソッドを含めることはできません。ただし、静的内部クラスの場合、静的および非静的フィールドとメソッドを持つことができます。
非静的内部クラスのインスタンスは、それが定義した外部クラスのオブジェクトの参照を使用して作成されます。これは、インスタンスを囲むことを意味します。ただし、静的内部クラスのインスタンスは、外部クラスの参照なしで作成されます。つまり、それを囲むインスタンスはありません。
この例を参照してください
class A
{
class B
{
// static int x; not allowed here
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A a = new A();
// Non-Static Inner Class
// Requires enclosing instance
A.B obj1 = a.new B();
// Static Inner Class
// No need for reference of object to the outer class
A.C obj2 = new A.C();
}
}
静的内部クラスは、それを囲むクラスの非静的メンバーにアクセスできません。オブジェクトを作成せずに値を取得する手続き型と同じように、クラスを囲む静的メンバー(インスタンスフィールドとメソッド)に直接アクセスできます。
静的内部クラスは、静的メンバーと非静的メンバーの両方を宣言できます。静的メソッドは、メインクラスの静的メンバーにアクセスできます。ただし、非静的内部クラスメンバーにはアクセスできません。非静的内部クラスのメンバーにアクセスするには、非静的内部クラスのオブジェクトを作成する必要があります。
非静的内部クラスは、静的フィールドと静的メソッドを宣言できません。静的タイプまたはトップレベルタイプのいずれかで宣言する必要があります。「静的フィールドは静的タイプまたは最上位タイプでのみ宣言されます」と言うと、このエラーが発生します。
非静的内部クラスは、値を取得する手続き型スタイルで、囲んでいるクラスの静的メンバーと非静的メンバーの両方にアクセスできますが、静的内部クラスのメンバーにはアクセスできません。
囲んでいるクラスは、内部クラスのオブジェクトを作成するまで、内部クラスのメンバーにアクセスできません。非静的クラスのメンバーにアクセスする際のメインクラスの場合、非静的内部クラスのオブジェクトを作成できます。
静的内部クラスのメンバーにアクセスするメインクラスの場合、次の2つのケースがあります。
- ケース1:静的メンバーの場合、静的内部クラスのクラス名を使用できます
- ケース2:非静的メンバーの場合、静的内部クラスのインスタンスを作成できます。
ネストされたクラスについて議論しています...
違いは、静的でもあるネストされたクラス宣言は、それを囲むクラスの外部でインスタンス化できることです。
静的ではないネストされたクラス宣言がある場合、Javaでは、囲んでいるクラスを経由する場合を除いて、それをインスタンス化できません。内部クラスから作成されたオブジェクトは、外部クラスから作成されたオブジェクトにリンクされているため、内部クラスは外部のフィールドを参照できます。
ただし、静的である場合、リンクは存在せず、外部フィールドにアクセスできません(他のオブジェクトのような通常の参照を介する場合を除く)。したがって、ネストされたクラスを単独でインスタンス化できます。
静的内部クラス:静的メンバーと非静的メンバーを宣言できますが、その親クラスの静的メンバーにのみアクセスできます。
非静的内部クラス:非静的メンバーのみを宣言できますが、その親クラスの静的および非静的メンバーにアクセスできます。
内部クラスは静的にすることはできないので、「静的ネストクラスと非静的ネストクラスの違いは何ですか?」という質問を書き直します。
あなたがここで言ったように、内部クラスは静的であってはなりません...私は静的に与えられている以下のコードを見つけました....理由?またはどちらが正しいか....
はい、静的ネスト型のセマンティクスには、それを妨げるものは何もありません。このスニペットは正常に実行されます。
public class MultipleInner {
static class Inner {
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Inner();
}
}
}
これはこのウェブサイトに投稿されたコードです...
質問の場合--->静的ネストされたクラスを複数回インスタンス化できますか?
答えは--->
もちろん、ネストされた型は独自のインスタンス制御(たとえば、プライベートコンストラクター、シングルトンパターンなど)を実行できますが、それはネストされた型であるという事実とは何の関係もありません。また、ネストされた型が静的列挙型である場合、もちろん、それをインスタンス化することはできません。
しかし、一般的に、はい、静的にネストされたタイプは複数回インスタンス化できます。
技術的には、静的ネスト型は「内部」型ではないことに注意してください。
静的にネストされたクラスは、他のトップレベルクラスと同じように、その外部クラス(および他のクラス)のインスタンスメンバーと対話します。事実上、静的にネストされたクラスは、動作上、パッケージ化の便宜のために別のトップレベルクラスにネストされたトップレベルクラスです。