嵌套类分为四种:

  1. static member class 静态成员类
  2. nonstatic member class 非静态成员类
  3. anonymous class 匿名类
  4. local class 局部类

后三者统称为 inner class 内部类。

还有一种嵌套的形式叫 interfaces within classes 类内部接口,我们在最后介绍。

1. Static Member Class 静态成员类

//外围类
class EnclosingClass{
  private static int i; //私有静态属性
  //私有静态方法 m1
  private static void m1(){
    System.out.println(i);
  }
  //私有静态方法 m2,调用嵌套类里面的静态方法
  static void m2(){
    EnclosedClass.accessEnclosingClass();
  }
  //静态成员类
  static class EnclosedClass{
    //静态方法,调用外围类的静态方法和静态属性
    static void accessEnclosingClass(){
      i = 1;
      m1();
    }
    //非静态方法,调用外围类的静态方法
    void accessEnclosingClass2(){
      m2();
    }
  }
}

主函数:

class SMCDemo { 
  public static void main(String[] args) { 
    EnclosingClass.EnclosedClass.accessEnclosingClass(); // Output: 1       EnclosingClass.EnclosedClass ec = new EnclosingClass.EnclosedClass();     ec.accessEnclosingClass2(); // Output: 1
  }}

简单总结:

  • 外部类不可以是 static 的,所以静态的非嵌套类不存在。
  • 静态成员类跟静态方法一样,只能访问静态的成员变量和方法,不能访问非静态的方法和属性,但是普通内部类可以访问任意外部类的成员变量和方法。
  • 静态成员类可以声明普通成员变量和方法,而内部类不能声明static成员变量和方法。
  • 静态成员类可以直接实例化,不需要实例化外部类。比如 new Outer.Inner(); 但内部类需要外部类的实例。

2. Nonstatic Member Class 非静态成员类

非静态成员类是内部类的最普通的形式。

class EnclosingClass{
  private int i;
  private void m(){
    System.out.println(i);
  }
  class EnclosedClass{
    void accessEnclosingClass(){
      i = 1;
      m();
    }
  }
}

主函数:

class NSMCDemo{
  public static void main(String[] args){
  EnclosingClass ec = new EnclosingClass();
  ec.new EnclosedClass().accessEnclosingClass(); // Output: 1
  }
}

用 ec.new EnclosedClass() 这样的方法来创建非静态成员类对象并不常用。常用的情况是在外围类中结构体中或非静态方法中来调用此非静态成员类的构造方法。

非静态成员类可以访问外围类的静态和非静态属性和方法。

3. Anonymous Class 匿名类

匿名类是一个没有名字的类。理论上它属于一个非静态的内部类。需要注意:

new Thread(new Runnable(){  public void run(){
  }}
).start();

这里面的 Thread 部分可不是一个匿名类,它是一个 unreferenced object。而 Runnable 部分是。

匿名类的基本语法是:

new InterfaceName(){......}; 
//或者
new SuperclassName(){......};

匿名类的特点和作用:

  • 匿名类是一个继承某个类的子类或者一个接口的实现。
  • 匿名类在声明的同时创建一个此类的实例。
  • 匿名类常用于创建细小的类。比如匿名类继承一个汽车类,我们就可以创建非常多不同的汽车的子类而不必须去为每种汽车起名字(当然这可能不是一个非常理想的例子)。匿名类好处是定制化,可以自由的实现,而且不用去创建太多的小类而使得程序变得复杂难懂。
  • 匿名类没有构造函数,它调用父类(继承的时候)的构造方法。
  • 匿名类只能调用 final 的变量或参数。

4. Local Class 局部类

一个局部类可以在任何一个声明局部变量的地方被声明,它的作用域相当于一个局部变量。和匿名类的区别在于,它有名字,它也可以被重用。

局部类的实例只可以访问外围作用域的 final 的属性和参数。

class EnclosingClass{
  void m(final int x){
    final int y = x*2;
    class LocalClass{
      int a = x;
      int b = y;
    }
    LocalClass lc = new LocalClass();
    System.out.println(lc.a);
    System.out.println(lc.b);
  }
}

局部类让程序更清晰。局部类的一个有趣的例子见书中142页。

Interfaces Within Classes 类内部接口

class X{
  interface A{
  }
  static interface B{
  }
}

类内部接口不管是否声明为 static,默认都是 static 的。用法:

class C implements X.A {}
//或者
class D implements X.B {}

接口内部嵌套接口是应该避免的,我们以后会讨论这个问题。

《Beginning Java 7》 - 9 - Nested Types 嵌套类型的更多相关文章

  1. Java中的Nested Classes和Inner Classes

    Java中的Nested Classes和Inner Classes Java有嵌套类(Nested Classes)和内部类(Inner Classes)的概念. 嵌套类(Nested Classe ...

  2. 细述 Java垃圾回收机制→Types of Java Garbage Collectors

    细述 Java垃圾回收机制→Types of Java Garbage Collectors 转自:https://segmentfault.com/a/1190000006214497 本文非原创, ...

  3. swift 20 - Nested Types

    Nested Types 只是为了方便类型的整合和使用 struct BlackjackCard { // nested Suit enumeration enum Suit: Character { ...

  4. JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth

    java8新出的YearMonth可以方便的用来表示某个月.我的项目中使用springmvc来接收YearMonth类型的数据时发现 x-www-from-urlencoded 格式的数据可以使用&q ...

  5. Effective Java 26 Favor generic types

    Use generic types to replace the object declaration Add one or more type parameters to its declarati ...

  6. Java Inner class && nested class

    Java中,Inner Class(不被 static修饰)可以访问outer class 的所有成员(包括私有成员),同时,内部类 的创建必须经由外部类的实例! nested class 有stat ...

  7. Welcome-to-Swift-19类型嵌套(Nested Types)

    枚举类型常被用于实现特定类或结构体的功能.也能够在有多种变量类型的环境中,方便地定义通用类或结构体来使用,为了实现这种功能,Swift允许你定义类型嵌套,可以在枚举类型.类和结构体中定义支持嵌套的类型 ...

  8. Effective Java 49 Prefer primitive types to boxed primitives

    No. Primitives Boxed Primitives 1 Have their own values Have identities distinct from their values 2 ...

  9. Java中的Union Types和Intersection Types

    前言 Union Type和Intersection Type都是将多个类型结合起来的一个等价的"类型",它们并非是实际存在的类型. Union Type Union type(联 ...

随机推荐

  1. 修改kvm虚拟机镜像大小

    修改虚拟机镜像大小(qcow2/raw resize) 创建一个镜像文件,大小1G taw muxueqz@muxueqz /tmp $ qemu-img create -f raw t.raw 1G ...

  2. notepad++正则表达式删除所有行某字符开始之前或者之后所有字符

    删除S 之后的所有字符用:s.*$ 删除S 之前的所有字符用:^.*s

  3. glTexGen

    [glTexGen] Rather than having to explicitly provide a texture coordinate for each vertex, we can use ...

  4. JAVA中集合转数组遍历

    JAVA中集合的遍历的一种方法时集合转数组遍历,也是就调用Collection中的toArray(). 代码: public static void main(String[] args) {     ...

  5. rocketmq--push消费过程

    Rocketmq消费分为push和pull两种方式,push为被动消费类型,pull为主动消费类型,push方式最终还是会从broker中pull消息.不同于pull的是,push首先要注册消费监听器 ...

  6. Spring学习笔记(三)--Convert System设计

    一.概述 转换系统是不同范式系统间交互常常会需要碰到的,如WEB 中HTTP KV文本流到对象的转换和对象到http KV文本流的转换:还有对象到关系型DB和关系型DB到对象之间的转换(ORM). 一 ...

  7. 基于Linux服务器的性能分析与优化

    作为一名Linux系统管理员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行,但硬件问题.软件问题.网络环境等的复杂性和多变性,导致了对系统的优化变得异常复杂,如何定位性能问题出在哪个方面 ...

  8. &&与||的短路运算

    在谈&&和||两个运算符的短路运算之前,先看一段程序: #include <stdio.h> int main() { , para2 = , para3 = , para ...

  9. sqlserver服务器硬件性能瓶颈分析

    硬件性能瓶颈 内存 内存对SQL Server性能的影响胜过任何其他硬件.因此,对SQL Server系统的内存使用情况进行定期监视以确保内存的可用百分比高于20%是很有必要的.如果用户遭遇性能问题, ...

  10. python基础之-数据类型

    Python3 数字(Number) Python 数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变数字数据类型得值,将重新分配内存空间. 以下实例在变量赋值时 Number 对 ...