一, 什么是内部类

Java中所谓内部类, 就是定义在另1个类内的类.

例如:

class A{int a;class B{int b;}
}

上面类B就是类A的一个内部类.

但是下面的写法, B只是A的一个成员.

class A{private int a;B b;
}class B{int bb;
}

因为B的定义体在类A之外, 注意区别.

Java编译器编译后, 还是会把面的代码编译成两个class.

1个是A

另1个是 A$B

对于Jvm来讲,它们实际上还是两个单独的类.

二,内部类的好处.

的确, 内部类的写法的确会破坏Java代码的良好结构以及可读性.

但是内部类也有它存在的意义.

例如一部法拉利跑车类, 它里面包括了1个发动机, 而发动机本身也有很多方法(例如,启动, 变速等). 所以发动机本身也是1个类.

但是法拉利的发动机技术很好, 为了技术机密保护, 法拉利本身不想外部知道发动机的细节, 就可以把发动机作为1个内部类.

也就是说, 外部不能直接实例化1个法拉利发动机, 用在别的车上.

好处:

1. 限制外部世界对内部类的访问.

2. 内部类可以直接访问外部类的成员.

其中第2点很重要, 甚至比第一点还重要.

三,什么情况下需要用到内部类.

这里我举1个具体点的例子.

加入1个聊天窗口Form类.

有很多控件类对象成员(例如输入框, 显示框等).

现在要启动2个线程, 分别用于接受和发送消息.

问题来了, 启动线程必须要重写Thread类或实现Runable接口,总结要写新的类.

那么新的类写在哪里呢.

如果写在外面, 那么新的类必须写入很多控件类的成员.

如果写入在Form类里面, 就可以直接使用Form类的所有成员. 这样就方便很多.

而且这个两个类也不想被其他类使用, 所以内部类就很适合了.

四,内部类的种类.

没错, Java内部类也可以根据定义的位置和访问权限分成下面若干种内部类.

4.1 定义在另1个类的方法体外的内部类.

4.1.1 非私有内部类(非静态)

这种内部i类(B)虽然定义在另1个类(A)的内部, 但实际上它是被第三个类(C)实例化的.

不过C类想实例化类B. 则必须先实例化类A.

public class InternalClass1{public static void f(){A a = new A(3);A.B b = a.new B();b.print();A.B b2 = new A(4).new B();b2.print();}
}class A{private int i;public A(int i){this.i = i;}class B{public void print(){System.out.printf("A.i is %d\n",i);}}
}

上面的例子定义了外部类A和内部类B.

可以见到内部类B是无限制地访问A的私有成员的.

反过来, 类A也同样可以无限制的内部类B的私有成员. 

而B可以被第三个类(InternalClass1)实例化.

实例化的写法上面写了两种, 但是都必须事先实例化1个A对象.

也就是说Java必须为A的1个对象分配内存, 才能为A的内部类对象分配内存.

4.1.2 私有内部类(非静态)

私有内部类指的是private 修饰的内部类(注意外部类不能被private修饰)

这样的话

内部类B不能被第三方类C直接访问和实例化

但是能通过A的封装方法访问.

例子:

public class InternalClass2{public static void f(){//A2.B2 b = new A2(3).new B2(); //errorA2 a = new A2(3);a.f();}
}class A2{private int i;public A2(int i){this.i = i;}public void f(){B2 b = new B2();System.out.println(i + b.b);}private class B2{private int b =3;public void print(){System.out.printf("A.i is %d\n",i);}}
}

4.1.3 静态内部类

跟外部类不同, 内部类可以用static关键字来修饰. 代表这个是1个静态内部类.

静态内部类跟非静态内部类有两点不同.

1. 实例化1个非静态内部类之前必须实例化其外部类.   而静态内部类不需要. 可以直接被实例化, 也就是说静态内部类不需要1个外部类对象.

2. 同样地, 内部类只能访问其外部类的静态成员.  因为外部类的非静态成员依赖于外部类对象实例化.

例子:

public class InternalClass3{public static void f(){A3.printj(3);}
}class A3{private int i;private static int j;public static void printj(int j){B3 b = new B3(j);b.print();}private static class B3{public B3(int j){//A3.i= 3;//errorA3.j = j;}public void print(){System.out.printf("A.j is %d\n",j);}}
}

4.1.4 方法体内部类

下面开始恶心了,  就是内部类可以定义在方法体内.

假如B 是 A的方法f(int a)内的1个内部类.

1. B还是无限制访问A的所有成员.

2. A只能在方法f()内访问和使用B.

   假如B定义在f() 里面的if() 或 try{}字句内, 那么同样地, A只能在if,try的作用范围内使用B.

3. 在方法体f()内, 代码还是严格按照顺序执行的, 那就是说必须先定义内部体B, 再使用.

4. 假如B定义的内部使用到参数a 那么a必须用Final修饰.

例子:

public class InternalClass4{public static void f(){new A4(2).printB(3,6);}
}class A4{private int i;public A4(int i){this.i = i;}public void printB(final int x, int y){//class Bclass B4{public int getSum(){return i + x;}}        System.out.println(new B4().getSum() + y);}
}

例如上面的printB方法,  有两个参数x, y 但是内部类B只访问了x, 所以x必须用final修饰, 而y不用.

可以看出, 这个种内部类已经大大影响java代码的可读性了.

幸好这种内部类不可能被其他类访问. 作用域也只在方法体内. 但是起名字还是需要避免和同包内的其它类冲突.

4.1.5 匿名内部类

所谓匿名内部类就是定义1个内部类时不指定类名字

听起来不合常理啊.

在外部类A内定义1个匿名内部类B(注意B不是类名, 只是1个代号) 有两个必要天剑.

1.内部类B只能定义在A的方法体内.

2.内部类必须是继承自另1个类Bp(Bp是类名).  或者是实现另1个接口Bi(Bi是接口名).

而Bp和Bi必须事先定义.

对于第一种, 一般用于调用1个超类的重写工公共方法..  例如重写Thread类Run方法, 开启1个新进程.

public class InternalClass5{public static void f(){new A5().printB(3);}
}class A5{private int i = 100;public void printB(final int x){//a new internal class which inherits Thread new Thread(){public void run(){while(i > 0){System.out.println(i);i = i -x;}}}.start();}
}

对于第2种, 一般是返回1个接口的实现类对象:

例如:

public class InternalClass6{public static void f(){Ib b = new A6().GetIB(4);b.f();}
}class A6{private int i = 100;public Ib GetIB(final int x){//a new internal class which implements interface Ib return new Ib(){public void f(){System.out.println("this is a method implemented from a interface!");System.out.println(i+x);}};}
}interface Ib{void f();
}

注意这个接口必须是事先定义的.

匿名内部类的好处是随写随用, 而且无非担心命名冲突.

Java内部类简介.相关推荐

  1. Java 内部类简介,理解,特点,注意事项

    什么是内部类 内部类,顾名思义,就是在一个类当中再定义一个类.例如在python当中的闭包函数(函数内部再定义一个函数).Python闭包函数的理解 如果在类Outer的内部再定义一个类Inner,此 ...

  2. 看到如此详细的Java内部类,我泪目了

    Java内部类 介绍 定义 成员内部类 语法格式 使用说明 代码示例 局部内部类 语法格式 使用说明 代码示例 匿名内部类 语法格式 使用说明 代码示例 静态内部类 语法格式 使用说明 代码示例 介绍 ...

  3. Java EE 简介

    Java EE 简介 Java EE 基本架构 JavaEE 的诞生是为了解决传统 C/S 架构的弊端:客户端臃肿庞大,扩展性差等弊端. JavaEE 将传统的两层结构细分为了四层. 这四层分别是:C ...

  4. java程序包不存在_第一章 Java语言简介

    Java语言简介 Java之父 James Gosling(詹姆斯·高斯林) 正式诞生时间 1995年,已有二十多年历史 三大方向 JavaSE(桌面版,基础需重点掌握) JavaME(移动版,现在基 ...

  5. (一:NIO系列)JAVA NIO 简介

    出处:JAVA NIO 简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/O,New I/O类库的目标就是要让Java支持非阻塞I/O, ...

  6. ibm java_IBM i 上Java 虚拟机简介

    Abstract IBM i 上Java 虚拟机简介 Body Java在IT业界有多流行?google上搜索一下java, 结果一目了然(今天早上我搜索到的记录数是840000000条).Java之 ...

  7. Java内部类作用全解

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  8. netBeans调试时不进入java内部类(jdk源码)的方法 转载

    初次使用netbeans的调试功能时,会发现调试中,进入了java的内部类运行,具体情况,如下图所示: 对于我这样的一个新手,完全弄不懂啊. 后来我去论坛问了,同时自己研究,发现经过以下设置,就可以跳 ...

  9. Java内部类(Inner Class)小记

    一.引子 看到Trinea的博文Junit单测代码中java序列化失败的解决,让我想到Java内部类的一些小Gocha,初学Java时很迷惑.这里记录一下. 就以Trinea的博文中的序列化失败的例子 ...

最新文章

  1. DOS命令输出的重定向
  2. Redis:哨兵模式(Sentinel)原理
  3. 对象的克隆(clone方法)
  4. 创业——不可忽视的创业计划书!!!
  5. 1082 射击比赛 (20 分)
  6. 1-4 数组元素的区间删除 (20 分)
  7. 安全模式下修复电脑故障
  8. java多线程与线程间通信
  9. 如何禁止树莓派屏幕休眠
  10. spring boot-Soap协议客户端集成(根据WSDL文档调用WebService、maven的jaxb2插件)
  11. log4j日志配置(超详细)
  12. 怎么用计算机按log以2为底,log以2为底4的对数在计算器上怎么按?
  13. [Joy]冷笑话急转弯
  14. uniapp全端应用商城系统,应用市场APP,软件库APP,葫芦芥子博客
  15. 奥斯汀大学计算机专业怎么样,德克萨斯大学奥斯汀分校计算机工程排名
  16. Jaca程序基础学习笔记
  17. 关于中医把脉的一点想法
  18. USB过压过流保护芯片,可调限流4A,6V过压关闭
  19. 小米手机5X获得Root权限的方法
  20. 第一行代码天气预报接口更改后JSON键值对的问题

热门文章

  1. 认知理论与技术(hash函数,SHA,MD
  2. 自动化测试之鼠标悬浮操作、双击、鼠标拖拽
  3. TEE Internal core API介绍(globalplatform)
  4. [转]一篇很喜欢的知乎美文
  5. Docker Compose基本介绍
  6. 【攻防世界009】流浪者
  7. C语言的结构使用和结构对齐
  8. 002 辅助框架的设计
  9. Mysql 查询一天中,每个小时数据的数量
  10. FastDFS测试图片上传