内部类可以是静态(static)的,可以使用 public、protected 和 private 访问控制符,而外部类只能使用 public,或者默认。

成员式内部类

在外部类内部直接定义(不在方法内部或代码块内部)的类就是成员式内部类,它可以直接使用外部类的所有变量和方法,即使是 private 的。外部类要想访问内部类的成员变量和方法,则需要通过内部类的对象来获取。

请看下面的代码:

public class Outer{private int size;public class Inner {public void dostuff() {size++;}}public void testTheInner() {Inner in = new Inner();in.dostuff();}
}

成员式内部类如同外部类的一个普通成员。

成员式内部类可以使用各种修饰符,包括 public、protected、private、static、final 和 abstract,也可以不写。

若有 static 修饰符,就为类级,否则为对象级。类级可以通过外部类直接访问,对象级需要先生成外部的对象后才能访问。

非静态内部类中不能声明任何 static 成员。

内部类可以相互调用,例如:

class A {// B、C 间可以互相调用class B {}class C {}
}

成员式内部类的访问

内部类的对象以成员变量的方式记录其所依赖的外层类对象的引用,因而可以找到该外层类对象并访问其成员。该成员变量是系统自动为非 static 的内部类添加的,名称约定为“outClassName.this”。

1) 使用内部类中定义的非静态变量和方法时,要先创建外部类的对象,再由“outObjectName.new”操作符创建内部类的对象,再调用内部类的方法,如下所示:

public class Demo{public static void main(String[] args) {Outer outer = new Outer();Outer.Inner inner = outer.new Inner();inner.dostuff();}
}
class Outer{private int size;class Inner{public void dostuff() {size++;}}
}

2) static 内部类相当于其外部类的 static 成员,它的对象与外部类对象间不存在依赖关系,因此可直接创建。示例如下:

public class Demo{public static void main(String[] args) {Outer.Inner inner = new Outer.Inner();inner.dostuff();}
}
class Outer{private static int size;static class Inner {public void dostuff() {size++;System.out.println("size=" + size);}}
}

运行结果:
size=1

3) 由于内部类可以直接访问其外部类的成分,因此当内部类与其外部类中存在同名属性或方法时,也将导致命名冲突。所以在多层调用时要指明,如下所示:

public class Outer{private int size;public class Inner{private int size;public void dostuff(int size){size++;  // 局部变量 size;this.size;  // 内部类的 sizeOuter.this.size++;  // 外部类的 size}}
}

局部内部类

局部内部类(Local class)是定义在代码块中的类。它们只在定义它们的代码块中是可见的。

局部类有几个重要特性:

  1. 仅在定义了它们的代码块中是可见的;
  2. 可以使用定义它们的代码块中的任何局部 final 变量;
  3. 局部类不可以是 static 的,里边也不能定义 static 成员;
  4. 局部类不可以用 public、private、protected 修饰,只能使用缺省的;
  5. 局部类可以是 abstract 的。

请看下面的代码:

public class Outer {public static final int TOTAL_NUMBER = 5;public int id = 123;public void func() {final int age = 15;String str = "http://www.weixueyuan.net";class Inner {public void innerTest() {System.out.println(TOTAL_NUMBER);System.out.println(id);// System.out.println(str);不合法,只能访问本地方法的final变量System.out.println(age);}}new Inner().innerTest();}public static void main(String[] args) {Outer outer = new Outer();outer.func();}
}

运行结果:
5
123
15

匿名内部类

匿名内部类是局部内部类的一种特殊形式,也就是没有变量名指向这个类的实例,而且具体的类实现会写在这个内部类里面。

注意:匿名类必须继承一个父类或实现一个接口。

不使用匿名内部类来实现抽象方法:

abstract class Person {public abstract void eat();
}
class Child extends Person {public void eat() {System.out.println("eat something");}
}
public class Demo {public static void main(String[] args) {Person p = new Child();p.eat();}
}

运行结果:
eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用。但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类。使用匿名内部类实现:

abstract class Person {public abstract void eat();
}
public class Demo {public static void main(String[] args){// 继承 Person 类new Person() {public void eat() {System.out.println("eat something");}}.eat();}
}
复制纯文本新窗口

可以看到,匿名类继承了 Person 类并在大括号中实现了抽象类的方法。

浅谈 Java中的静态内部类、匿名内部类、成员式内部类和局部内部类相关推荐

  1. Java静态内部类、匿名内部类、成员式内部类和局部内部类

    内部类可以是静态(static)的,可以使用 public.protected 和 private 访问控制符,而外部类只能使用 public,或者默认. 成员式内部类 在外部类内部直接定义(不在方法 ...

  2. 浅谈Java中的栈和堆

    人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...

  3. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  4. 浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  5. java中修饰常量的事_浅谈java中的声明常量为什么要用static修饰

    今天定义一个类常量,想着也只有这个类可以用到,就没用static关键字修饰.结果sonar代码检查提示: Rename this field "PERSON_TYPE_USER" ...

  6. 浅谈JAVA中如何利用socket进行网络编程(二)

    转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...

  7. scale和java比较_浅谈java中BigDecimal的equals与compareTo的区别

    这两天在处理支付金额校验的时候出现了点问题,有个金额比较我用了BigDecimal的equals方法来比较两个金额是否相等,结果导致金额比较出现错误(比如3.0与3.00的比较等). [注:以下所讲都 ...

  8. file相对路径java_浅谈java 中文件的读取File、以及相对路径的问题

    一.对于java项目中文件的读取 1.使用system 或是 系统的properties对象 ①直接是使用 string relativelypath=system.getproperty(" ...

  9. java中的强制类型转换注意事项_浅谈Java中强制类型转换的问题

    为了更好的理解我们先看下面的例子: package com.yonyou.test; import java.util.ArrayList; import java.util.Iterator; im ...

最新文章

  1. mini-uboot 启动过程简单分析
  2. 网管管理的12种方法
  3. A组包含的前导码数( sizeOfRA-PreamblesGroupA)
  4. CSDN网站用户数据库给破了
  5. 【机器学习】sklearn数据特征预处理:归一化和标准化
  6. php如何读取excel合并单元格_PHP读取excel中合并的单元格的值
  7. 基于tkinter的简易加减乘除计算器
  8. C++编程技术常见问题有哪些?
  9. matlab2016a打开为响应,MATLAB2016a启动慢
  10. 【图像超分辨率】Deep Learning for Image Super-resolution: A Survey
  11. android 自定义圆点,Android自定义带圆点的半圆形进度条
  12. 4.蒙特卡洛(Monte-Carlo, MC)+时序差分(Temporal Difference, TD)
  13. java版溺尸哪里有_我的世界基岩版1.3新增生物大全 新增珊瑚/幻翼/溺尸等
  14. 中国移动湖南公司2022校园春季招聘正在进行中
  15. 派森编程python_派森学python
  16. poi/jxls导入/导出Excel工具类(支持2003和2007)
  17. sqli-labs/Less-52
  18. 虹科分享 | 解析数据加密,保护你的数据安全
  19. PHP开发支付宝微信个人免签支付接口实例
  20. excel找到对应数据的列指标_三种方式制作数据地图

热门文章

  1. 安装Windows7之后出现“Bootmgr is missing”的解决办法
  2. html form半透明,HTML——form
  3. AQS acquire(int arg) 深度解析
  4. 苹果CMSv10好看的自适应bt电影天堂美化高端模板源码
  5. 【Coursera 计算导论与C语言基础】苹果和虫子+最高分数+最大奇数与最小偶数差+分离整数的各个数位
  6. 我看好的人都变世界首富了
  7. 基础工具运用:爆破管理员账户登录后台【配套课时:burp到支付和暴破 实战演练】
  8. Django + ajax
  9. 自学网站 分享一波儿!
  10. 阿里新一代微服务,内部资深架构师手抄的笔记+脑图不容错过,全是精华