Java中内部类和静态嵌套类的主要区别是什么?设计/实现是否在选择其中一个方面发挥作用?


当前回答

Java中的内部类和嵌套静态类都是在另一个类中声明的类,在Java中称为顶级类。在Java术语中,如果您将嵌套类声明为静态的,则在Java中将其称为嵌套静态类,而非静态嵌套类则简称为内部类。

什么是Java中的内部类?

任何不是顶级或在另一个类中声明的类都称为嵌套类,在这些嵌套类中,声明为非静态的类在Java中称为内部类。Java中有三种内部类:

1) 本地内部类-在代码块或方法中声明。2) 匿名内部类-是一个没有名称可引用的类,并在创建它的同一位置初始化。3) 成员内部类-声明为外部类的非静态成员。

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in java");
        }
    }
}

什么是Java中的嵌套静态类?

嵌套静态类是另一个在类内部声明为成员并使其成为静态的类。嵌套的静态类也被声明为外部类的成员,并且可以像任何其他成员一样成为私有的、公共的或受保护的。嵌套静态类相对于内部类的主要优点之一是嵌套静态类的实例不附加到外部类的任何封闭实例。您也不需要任何外部类的实例来在Java中创建嵌套静态类的实例。

1) 它可以访问外部类(包括private)的静态数据成员。2) 静态嵌套类无法访问非静态(实例)数据成员或方法。

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in java");
        }
    }
}

参考:Java中的内部类和嵌套静态类及其示例

其他回答

嵌套类是一个非常通用的术语:每个不是顶级的类都是嵌套类。内部类是非静态嵌套类。约瑟夫·达西写了一篇关于嵌套、内部、成员和顶级课程的非常好的解释。

从Java教程:

嵌套类分为两类:静态类和非静态类。声明为静态的嵌套类简单地称为静态嵌套类。非静态嵌套类称为内部类。

使用封闭类名访问静态嵌套类:

OuterClass.StaticNestedClass

例如,要为静态嵌套类创建对象,请使用以下语法:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

作为内部类实例的对象存在于外部类的实例中。考虑以下类别:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

InnerClass实例只能存在于OuterClass实例中,并且可以直接访问其封闭实例的方法和字段。

要实例化内部类,必须首先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:

OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

请参见:Java教程-嵌套类

为了完整性,请注意还有这样一种东西,即没有封闭实例的内部类:

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

这里,new A(){…}是在静态上下文中定义的内部类,没有封闭实例。

我认为,通常遵循的惯例是:

顶级类中的静态类是嵌套类顶级类中的非静态类是内部类还有两种形式:本地类-在块(如方法或构造函数体)内部声明的类匿名类-在表达式和语句中创建实例的未命名类

然而,需要记住的其他几点是:

顶级类和静态嵌套类在语义上是相同的,只是在静态嵌套类的情况下,它可以对其外部〔父〕类的私有静态字段/方法进行静态引用,反之亦然。内部类可以访问外部[父]类的封闭实例的实例变量。然而,并不是所有的内部类都有封闭实例,例如静态上下文中的内部类,比如静态初始值设定项块中使用的匿名类。默认情况下,匿名类扩展父类或实现父接口,并且没有进一步的子句来扩展任何其他类或实现任何其他接口。所以新建YourClass(){};意味着类〔Anonymous〕扩展了YourClass{}新建YourInterface(){};表示类〔Anonymous〕实现YourInterface{}


我觉得还有一个更大的问题,那就是什么时候使用?这主要取决于你正在处理的场景,但阅读@jrudolph给出的回复可能会帮助你做出一些决定。

嵌套类:类内的类

类型:

静态嵌套类非静态嵌套类[内部类]

差异:

非静态嵌套类[内部类]

在非静态嵌套类中,内部类的对象存在于外部类的对象中。因此,内部类可以访问外部类的数据成员。所以要创建内部类的对象,我们必须首先创建外部类的对象。

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

静态嵌套类

在静态嵌套类中,内部类的对象不需要外部类的对象,因为单词“static”表示不需要创建对象。

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

如果要访问x,请在内部方法中写入以下内容

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);

静态嵌套类访问在其中定义的类的PRIVATE类级静态变量。从体系结构的角度来看,这可能是巨大的(即服务定位器模式在服务中使用嵌套的静态助手类),并可能帮助OP了解它们与内部类一起存在的原因。