Java中的嵌套类、内部类、静态内部类

18人阅读 评论(0) 收藏 举报
分类:
在Java中我们在一个类的内部再定义一个类,如下所示:
  1. class OuterClass {  
  2.     …  
  3.     class NestedClass {  
  4.         …  
  5.     }  
  6. }  
class OuterClass {
    ...
    class NestedClass {
        ...
    }
}

那么在上面的例子中我们称OuterClass为外围类(enclosing class),里面的那个类称之为嵌套类(Nested Class).

嵌套类可以分为两种,静态的和非静态的,即静态嵌套类和非静态嵌套类。非静态嵌套类又叫做内部类(Inner Class)。我们通常所说的静态内部类其实是不严格的,严格的说应该叫做静态嵌套类(Static Nested Class)。

  1. class OuterClass {  
  2.     …  
  3.     class InnerClass {  
  4.         …  
  5.     }  
  6.   
  7.     static class StaticNestedClass {  
  8.         …  
  9.     }      
  10. }  
class OuterClass {
    ...
    class InnerClass {
        ...
    }

    static class StaticNestedClass {
        ...
    }    
}

上述代码中的InnerClass就是内部类,StaticNestedClass就是静态嵌套类。

内部类与静态嵌套类虽然都是嵌套类,但在使用上是有一些区别的。


内部类

比如有如下内部类的定义,

  1. class OuterClass {  
  2.     …  
  3.     class InnerClass {  
  4.         …  
  5.     }  
  6. }  
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
OuterClass是InnerClass的外围类,InnerClass是OuterClass的内部类。内部类的实例对象都会绑定一个外围类的实例对象,并且InnerClass可以访问其所绑定的OuterClass的所有成员属性以及方法,包括私有成员属性以及方法。在InnerClass中通过OuterClass.this显式的引用其所绑定的OuterClass的实例。要实例化内部类InnerClass,必须首先实例化其外围类OuterClass,然后用如下的语法创建内部类的实例:

  1. OuterClass outerObject = new OuterClass();  
  2. OuterClass.InnerClass innerObject = outerObject.new InnerClass();  
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
注意,上面写得是outerObject.new InnerClass(),而不是new OuterClass.InnerClass(); 
我们在执行代码OuterClass.InnerClass innerObject = outerObject.new InnerClass()的时候,其实做了两件事,一件事是创建一个内部类的实例innerObject,第二件事是让innerObject绑定outerObject作为其外围类的实例。这样innerObject就可以访问outerObject内的所有成员属性以及方法了。
那如果想直接跳过外围类去初始化内部类会怎么样呢?代码如下所示:

如果执行代码InnerClass innerObject = new InnerClass(),会出现如下的编译错误:
No enclosing instance of type OuterClass is accessible. Must qualify the allocation with an enclosing instance of type OuterClass (e.g. x.new A() where x is an instance of OuterClass).
编译器给出的错误提示很明确,就是我们没有外围类OuterClass的实例就去初始化内部类了。要写成x.new InnerClass()的形式,其中x是外围类OuterClass的一个实例对象。

静态嵌套类
有些人把静态嵌套类成为静态内部类,其实静态内部类这个称呼不严谨,因为内部类都是非静态的。静态嵌套类与内部类有很大的不同,静态嵌套类说到底就是一个静态类,只不过是其位置位于某个类的内部罢了。
假设有如下静态嵌套类的定义:
  1. class OuterClass {  
  2.     …  
  3.     static class StaticNestedClass {  
  4.         …  
  5.     }  
  6. }  
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
}
那么我可以像正常使用一个一般的静态类那样使用一个静态嵌套类,只不过要通过其外围类的名字来访问静态嵌套类的名字。所以,外围类更像是静态嵌套类的命名空间。比如要获取静态嵌套类,要使用OuterClass.StaticNestedClass。
如果要创建静态嵌套类的实力对象,使用如下的语法:
  1. OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();  
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
由于静态嵌套类的本质就是一个静态类,所以其实例对象的初始化不需要也不能像内部类那样需要绑定一个外围类对象。由于静态嵌套类没有像内部类那样绑定外部类对象,所以也就不存在静态嵌套类不能访问其外围类的成员这种说法。
如果我们像初始化内部类那样初始化静态嵌套类,也就是在创建静态嵌套类的时候给其绑定其外围类的实例对象,会怎么样呢?代码如下所示:


可以发现,如果我们在初始化静态嵌套类时强行给其绑定外围类的实例对象,编译器就会报错:
Illegal enclosing instance specification for type OuterClass.StaticNestedClass
我们给静态嵌套类OuterClass.StaticNestedClass指定了非法的外围类的实例。

综上所述,虽然内部类和静态嵌套类都属于嵌套类,但是二者有本质区别:内部类的实例化对象需要绑定一个外围类的实例化对象,而静态嵌套类的实例化对象不能也无法绑定外围类的实例化对象。

转载自https://blog.csdn.net/iispring/article/details/46490319

查看评论

静态内部类的使用场景

在实际的工作开发中,使用普通的内部类的场景比较多,似乎静态内部类并不常用,但是它也有其特定的使用场景。 比如说我们学习JAVA的时候,的main方法,它是static 方法,是程序的入口,但不需要每...
  • yclfdn2004
  • yclfdn2004
  • 2015-09-08 16:11:32
  • 1359

关于java内部类(静态内部类和普通内部类)

java 静态内部类 只有在是静态内部类的情况下才能把static修复符放在类前,其他任何时候static都是不能修饰类的。      //定义张三这个人       Person p...
  • lxxxzzl
  • lxxxzzl
  • 2014-10-23 16:53:02
  • 1425

从反编译深入理解JAVA内部类类结构以及final关键字

1.为什么成员内部类可以无条件访问外部类的成员? 2.为什么局部内部类和匿名内部类只能访问局部final变量? 3.静态内部类有特殊的地方吗?...
  • Davidluo001
  • Davidluo001
  • 2015-12-22 10:13:44
  • 1493

Kotlin-16.嵌套类/内部类(Nested Classes/Inner classes)

嵌套类(Nested Classes),类可以嵌套在其他类中,不能访问外部类成员,相当于java的static 静态内部类;内部类(Inner classes),类标记为inner,可以访问外部类成员...
  • qq_32115439
  • qq_32115439
  • 2017-06-24 15:09:00
  • 1662

java嵌套类和内部类、匿名类

java嵌套类和内部类、匿名类 1、嵌套类和内部类定义 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最...
  • andychen314
  • andychen314
  • 2016-03-10 16:08:13
  • 796

深入理解java嵌套类和内部类、匿名类

深入理解java嵌套类和内部类、匿名类 一、什么是嵌套类及内部类   可以在一个类的内部定义另一个类,这种类称为嵌套类(nested cla...
  • leixiongbo
  • leixiongbo
  • 2016-08-09 13:36:39
  • 886

java 双重检查单例和静态内部类单例

最近在看imageLoader 源码的时候,看到单例采用的双重检查机制,但是在看其他大牛写的代码的时候,采用的是静态的内部类作为单例,在此研究下。下面是单例的相关内容: 懒汉式 //懒汉式单例类.在第...
  • android_freshman
  • android_freshman
  • 2016-03-31 18:15:23
  • 2473

关于java中的静态内部类和非静态内部类

最近在做mapreduce的时候突然对内部类有了疑问,于是翻书做测试算是搞明白一些了,记录下来备以后查阅。 ----------------------------------------------...
  • coder_farmer_2015
  • coder_farmer_2015
  • 2015-03-24 10:12:54
  • 1989

静态内部类和成员内部类的区别

如果你不需要内部类对象与其外围类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested class)。Static Nested Class是被声明为静态(static)的...
  • scyatcs
  • scyatcs
  • 2014-03-24 11:39:39
  • 3434

Java 静态内部类 与 非静态内部类的区别?什么时候用静态内部类,又是什么时候用非静态内部类?

Java中内部类加载时间:一般是只有运到了才会初始化,而不是外部内加载的时候(不管是静态还是非静态内部类)。 注意到一个问题: 内部类只有是静态的,其内部类中才能有静态属性和静态方法; 如果内部类...
  • wolf_fang
  • wolf_fang
  • 2016-09-25 16:11:09
  • 2873
    个人资料
    等级:
    访问量: 364
    积分: 64
    排名: 161万+
    文章存档