Java知多少(36)内部类及其实例化

在 Java 中,允许在一个类(或方法、语句块)的内部定义另一个类,称为内部类(Inner Class),有时也称为嵌套类(Nested Class)。

内部类和外层封装它的类之间存在逻辑上的所属关系,一般只用在定义它的类或语句块之内,实现一些没有通用意义的功能逻辑,在外部引用它时必须给出完整的名称。

使用内部类的主要原因有:

  • 内部类可以访问外部类中的数据,包括私有的数据。
  • 内部类可以对同一个包中的其他类隐藏起来。
  • 当想要定义一个回调函数且不想编写大量代码时,使用匿名(anonymous)内部类比较便捷。
  • 减少类的命名冲突。

请看下面的例子:

 1 public class Outer {
 2     private int size;
 3     public class Inner {
 4         private int counter = 10;
 5         public void doStuff() {
 6             size++;
 7         }
 8     }
 9     public static void main(String args[]) {
10         Outer outer = new Outer();
11         Inner inner = outer.new Inner();
12         inner.doStuff();
13         System.out.println(outer.size);
14         System.out.println(inner.counter);
15         // 编译错误,外部类不能访问内部类的变量
16         System.out.println(counter);
17     }
18 }

这段代码定义了一个外部类 Outer,它包含了一个内部类 Inner。将错误语句注释掉,编译,会生成两个 .class 文件:Outer.class 和 Outer$Inner.class。也就是说,内部类会被编译成独立的字节码文件。

内部类是一种编译器现象,与虚拟机无关。编译器将会把内部类翻译成用 $ 符号分隔外部类名与内部类名的常规类文件,而虚拟机则对此一无所知。

注意:必须先有外部类的对象才能生成内部类的对象,因为内部类需要访问外部类中的成员变量,成员变量必须实例化才有意义。

内部类是 Java 1.1 的新增特性,有些程序员认为这是一个值得称赞的进步,但是内部类的语法很复杂,严重破坏了良好的代码结构, 违背了Java要比C++更加简单的设计理念。

内部类看似增加了—些优美有趣,实属没必要的特性,这是不是也让Java开始走上了许多语言饱受折磨的毁灭性道路呢?本教程并不打算就这个问题给予一个肯定的答案。

系列文章:

Java知多少(1)语言概述

Java知多少(2)虚拟机(JVM)以及跨平台原理

Java知多少(3) 就业方向

Java知多少(4)J2SE、J2EE、J2ME的区别

Java知多少(5) Java开发环境的搭建

Java知多少(6)第一个程序示例

Java知多少(7)类与对象

Java知多少(8)类库及其组织结构

Java知多少(9) import及Java类的搜索路径

Java知多少(10)数据类型及变量

Java知多少(11)数据类型转换

Java知多少(12)运算符

Java知多少(13)流程控制

Java知多少(14)数组

Java知多少(15)字符串

Java知多少(16)StringBuffer与StringBuider

Java知多少(17)强调一下编程风格

Java知多少(18)类的定义及其实例化

Java知多少(19)访问修饰符(访问控制符)

Java知多少(20)变量的作用域

Java知多少(21)this关键字详解

Java知多少(22)方法重载

Java知多少(23)类的基本运行顺序

Java知多少(24)包装类、拆箱和装箱详解

Java知多少(25)再谈Java包

Java知多少(26)源文件的声明规则

Java知多少(27)继承的概念与实现

Java知多少(28)super关键字

Java知多少(29)覆盖和重载

Java知多少(30)多态和动态绑定

Java知多少(31)static关键字以及Java静态变量和静态方法

Java知多少(32)instanceof

Java知多少(33)多态对象的类型转换

Java知多少(34)final关键字:阻止继承和多态

Java知多少(35)Object类

Java知多少(36)内部类及其实例化

时间: 2024-12-26 13:20:03

Java知多少(36)内部类及其实例化的相关文章

Java知多少(37)静态内部类、匿名内部类、成员式内部类和局部内部类

内部类可以是静态(static)的,可以使用 public.protected 和 private 访问控制符,而外部类只能使用 public,或者默认. 成员式内部类 在外部类内部直接定义(不在方法内部或代码块内部)的类就是成员式内部类,它可以直接使用外部类的所有变量和方法,即使是 private 的.外部类要想访问内部类的成员变量和方法,则需要通过内部类的对象来获取. 请看下面的代码: 1 public class Outer{ 2 private int size; 3 public cl

Java知多少(18)类的定义及其实例化

类必须先定义才能使用.类是创建对象的模板,创建对象也叫类的实例化. 下面通过一个简单的例子来理解Java中类的定义: 1 public class Dog{ 2 String name; 3 int age; 4 5 void bark(){ // 汪汪叫 6 System.out.println("汪汪,不要过来"); 7 } 8 9 void hungry(){ // 饥饿 10 System.out.println("主人,我饿了"); 11 } 12 } 对

Java知多少(完结篇)

Java知多少(1)语言概述 Java知多少(2)虚拟机(JVM)以及跨平台原理 Java知多少(3) 就业方向 Java知多少(4)J2SE.J2EE.J2ME的区别 Java知多少(5) Java开发环境的搭建 Java知多少(6)第一个程序示例 Java知多少(7)类与对象 Java知多少(8)类库及其组织结构 Java知多少(9) import及Java类的搜索路径 Java知多少(10)数据类型及变量 Java知多少(11)数据类型转换 Java知多少(12)运算符 Java知多少(1

Java知多少(上)

ava知多少(1)语言概述 Java知多少(2)虚拟机(JVM)以及跨平台原理 Java知多少(3) 就业方向 Java知多少(4)J2SE.J2EE.J2ME的区别 Java知多少(5) Java开发环境的搭建 Java知多少(6)第一个程序示例 Java知多少(7)类与对象 Java知多少(8)类库及其组织结构 Java知多少(9) import及Java类的搜索路径 Java知多少(10)数据类型及变量 Java知多少(11)数据类型转换 Java知多少(12)运算符 Java知多少(13

Java知多少(38)抽象类的概念和使用

在自上而下的继承层次结构中,位于上层的类更具有通用性,甚至可能更加抽象.从某种角度看,祖先类更加通用,它只包含一些最基本的成员,人们只将它作为派生其他类的基类,而不会用来创建对象.甚至,你可以只给出方法的定义而不实现,由子类根据具体需求来具体实现. 这种只给出方法定义而不具体实现的方法被称为抽象方法,抽象方法是没有方法体的,在代码的表达上就是没有“{}”.包含一个或多个抽象方法的类也必须被声明为抽象类. 使用 abstract 修饰符来表示抽象方法和抽象类. 抽象类除了包含抽象方法外,还可以包含

Java知多少(41)泛型详解

我们知道,使用变量之前要定义,定义一个变量时必须要指明它的数据类型,什么样的数据类型赋给什么样的值. 假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数.小数和字符串,例如: 1 x = 10.y = 10 2 x = 12.88.y = 129.65 3 x = "东京180度".y = "北纬210度" 针对不同的数据类型,除了借助方法重载,还可以借助自动装箱和向上转型.我们知道,基本数据类型可以自动装箱,被转换成对应的包装类:Object 是所有

Java知多少(58)线程Runnable接口和Thread类详解

大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 创建线程的最简单的方法就是创建一个实现Runnable 接口的类.Runnable抽象了一个执行代码单元.你可以通过实现Runnable接口的方法创建每一个对象的线程.为实现Runnable 接口,一个类仅需实现一个run()的简单方法,该方法声明如下:    public void run( )

Java知多少(32)instanceof

多态性带来了一个问题,就是如何判断一个变量所实际引用的对象的类型 . C++使用runtime-type information(RTTI),Java 使用 instanceof 操作符. instanceof 运算符用来判断一个变量所引用的对象的实际类型,注意是它引用的对象的类型,不是变量的类型.请看下面的代码: 1 public final class Demo{ 2 public static void main(String[] args) { 3 // 引用 People 类的实例 4

Java知多少(39)interface接口

在抽象类中,可以包含一个或多个抽象方法:但在接口(interface)中,所有的方法必须都是抽象的,不能有方法体,它比抽象类更加“抽象”. 接口使用 interface 关键字来声明,可以看做是一种特殊的抽象类,可以指定一个类必须做什么,而不是规定它如何去做. 现实中也有很多接口的实例,比如说串口电脑硬盘,Serial ATA委员会指定了Serial ATA 2.0规范,这种规范就是接口.Serial ATA委员会不负责生产硬盘,只是指定通用的规范. 希捷.日立.三星等生产厂家会按照规范生产符合