一 内部类是什么

Java类中不仅可以定义变量和方法,还可以定义类,这样定义在类内部的类就被称为内部类。根据定义的方式不同,内部类分为静态内部类,成员内部类,局部内部类,匿名内部类四种。

Java为什么要引入内部类这个概念呢?原因在于,内部类定义在类的内部,可以方便访问外部类的变量和方法,并且和其它类进行隔离。

二 静态内部类

定义在类内部的静态类,就是静态内部类。

2.1 语法

定义一个静态内部类:

public class Out {

private static int a;

private int b;

public static class Inner {

public void print() {

System.out.println(a);

}

}

}复制代码

Inner就是静态内部类。静态内部类可以访问外部类所有的静态变量和方法,即使是private的也一样。静态内部类和一般类一致,可以定义静态变量、方法,构造方法等。

其它类使用静态内部类需要使用“外部类.静态内部类”方式,如下所示:

Out.Inner inner = new Out.Inner();

inner.print();复制代码

2.2 实现原理

查看编译后的代码可以知道,Out.java编译后会生成两个class文件,分别是Out.class和Out$Inner.class。因为这两个类处于同一个包下,所以静态内部类自然可以访问外部类的非私有成员。但是我们知道静态内部类是可以访问外部类所有访问权限的成员的,Java是如何实现的呢?看编译后生成的代码就知道了:

public class Out$Inner {

public Out$Inner() {

}

public void print() {

System.out.println(Out.access$000());

}

}复制代码

静态内部类通过外部类的access$000()方法访问外部类的私有变量,这个方法是编译器自动生成的。在运行时,我们可以通过反射调用该方法。

2.3 应用场景

Java集合类HashMap内部就有一个静态内部类Entry。Entry是HashMap存放元素的抽象,HashMap内部维护Entry数组用了存放元素,但是Entry对使用者是透明的。像这种和外部类关系密切的,且不依赖外部类实例的,都可以使用静态内部类。

三 成员内部类

定义在类内部的非静态类,就是成员内部类。

3.1 语法

定义一个成员内部类:

public class Out {

private static int a;

private int b;

public class Inner {

public void print() {

System.out.println(a);

System.out.println(b);

}

}

}复制代码

成员内部类可以访问外部类所有的变量和方法,包括静态和实例,私有和非私有。和静态内部类不同的是,每一个成员内部类的实例都依赖一个外部类的实例。其它类使用内部类必须要先创建一个外部类的实例。如下所示:

Out out = new Out();

Out.Inner inner = out.new Inner();

inner.print();复制代码

成员内部类不能定义静态方法和变量(final修饰的除外)。这是因为成员内部类是非静态的,类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的。

3.2 实现原理

和静态内部类类似,Out.java编译后会生成两个class文件,分别是Out.class和Out$Inner.class。成员内部类的代码如下:

public class Out$Inner {

public Out$Inner(Out var1) {

this.this$0 = var1;

}

public void print() {

System.out.println(Out.access$000());

}

}复制代码

成员内部类访问外部类的私有变量和方法也是通过编译时生成的代码访问的。区别是,成员内部类的构造方法会添加一个外部类的参数。

四 局部类

定义在方法中的类,就是局部类。

4.1 语法

定义一个局部类:

public class Out {

private static int a;

private int b;

public void test(final int c) {

final int d = 1;

class Inner {

public void print() {

System.out.println(a);

System.out.println(b);

System.out.println(c);

System.out.println(d);

}

}

}

public static void testStatic(final int c) {

final int d = 1;

class Inner {

public void print() {

System.out.println(a);

//定义在静态方法中的局部类不可以访问外部类的实例变量

//System.out.println(b);

System.out.println(c);

System.out.println(d);

}

}

}

}复制代码

局部类只能在定义该局部类的方法中使用。定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。同时局部类还可以访问方法的参数和方法中的局部变量,这些参数和变量必须要声明为final的。

4.2 实现原理

Out.java编译后局部类会生成相应的class文件。

class Out$1Inner {

Out$1Inner(Out var1, int var2) {

this.this$0 = var1;

this.val$c = var2;

}

public void print() {

System.out.println(Out.access$000());

System.out.println(Out.access$100(this.this$0));

System.out.println(this.val$c);

System.out.println(1);

}

}复制代码

和成员内部类类似,生成的局部类的构造方法包含了外部类的参数,并且还包含了定义局部类方法的参数,这也就解释了为什么局部类可以访问外部类和方法的成员。同时也明白了为什么局部类访问的变量需要final修饰,因为局部类访问的变量其实是该局部类自己的成员,如果不用final修饰,那么在局部类修改该变量的值并不会影响方法中该变量的值。为了避免这种困惑,Java就禁止修改。

4.3 应用场景

如果一个类只在某个方法中使用,则可以考虑使用局部类。

五 匿名内部类

5.1 语法

定义一个匿名内部类:

public class Out {

private static int a;

private int b;

private Object obj = new Object() {

private String name = "匿名内部类";

@Override

public String toString() {

return name;

}

};

public void test() {

Object obj = new Object() {

@Override

public String toString() {

System.out.println(b);

return String.valueOf(a);

}

};

System.out.println(obj.toString());

}

}复制代码

匿名内部类可以出现在任何允许表达式出现的地方,定义格式:

new 类/接口{

//匿名内部类实现部分

}复制代码

5.2 实现原理

Out.java编译后匿名内部类会生成相应的class文件。

class Out$1 {

private String name;

Out$1(Out var1) {

this.this$0 = var1;

this.name = "匿名内部类";

}

public String toString() {

return this.name;

}

}复制代码

匿名内部类可以访问外部类所有的变量和方法。

5.3 应用场景

匿名内部类使用广泛,比如我们常用的绑定监听的时候。

view.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(v.getContext(),"click",Toast.LENGTH_SHORT).show(); }

});复制代码

android访问静态内部类,Java 内部类详解相关推荐

  1. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  2. 接口与继承系列教材 (十)- Java 内部类详解

    接口与继承系列教材 (十)- Java 内部类详解 内部类分为四种: 非静态内部类 静态内部类 匿名类 本地类 步骤1:非静态内部类 步骤2:静态内部类 步骤3:匿名类 步骤4:本地类 步骤5:在匿名 ...

  3. Java提高篇 —— Java内部类详解

    一.简介 内部类是一个非常有用的特性但又比较难理解使用的特性. 内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类. public class OuterClass {privat ...

  4. Android中R.java文件详解

    R.java文件有两种,两种文件作用一样都是获取资源的引用,区别在于一个存放着我们写的项目中资源的引用,另一个存放着系统定义好的一些资源 1.1 项目的R.java文件 先说第一种是项目编译出来的R. ...

  5. 【Android架构师java原理详解】二;反射原理及动态代理模式

    前言: 本篇为Android架构师java原理专题二:反射原理及动态代理模式 大公司面试都要求我们有扎实的Java语言基础.而很多Android开发朋友这一块并不是很熟练,甚至半路初级底子很薄,这给我 ...

  6. Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)

    内部类是什么? 字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class). ...

  7. Java内部类详解(使用场景和好处、相关内部类的笔试面试题)

    此篇文章作者为:Matrix海子 出处:http://www.cnblogs.com/dolphin0520/ 最近也是在学习java,看的是<java核心技术卷一>jdk8,看到内部类的 ...

  8. (转)java内部类详解

    本文转自http://www.cnblogs.com/dolphin0520/p/3811445.html,谢谢作者 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能 ...

  9. Java内部类详解(转)

    说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就来一探究竟.下面是本 ...

最新文章

  1. xdoj 易碎的鸟蛋(鹰蛋实验)
  2. 测试服务命名和动态注册路由的方式@Xan
  3. 如何将Excel中,某个单元格中的下拉选删除掉
  4. 1600: 卡斯丁狗要吃糖葫芦-回文串
  5. java mysql乱码_41、java与mysql乱码的问题
  6. flash 绘图API:绘制弧线
  7. 边缘计算的五个大坑,里面一定有你跳过的
  8. 移动端H5 腾讯地图sdk 当前位置 地址你解析 距离计算
  9. c/c++中define用法详解及代码示例
  10. python海龟作图不用循环_10分钟,利用聪明的小海龟可以制作出绚丽的视觉效果,你信不信呢...
  11. 计算机学院部长换届答辩,未来可期,各自精彩——记计算机科学学院2020年两委换届竞职答辩活动...
  12. 酷派5890详细获取ROOT、以及刷机教程
  13. AnimationController
  14. 魔兽争霸3技术分析资源汇总
  15. BZOJ 2827 千山鸟飞绝 Treap
  16. 软工学者Ming Wen及其顶会论文解读
  17. HTML+CSS网页设计期末课程大作业 【茶叶文化网站设计题材】web前端开发技术 web课程设计 网页规划与设计
  18. linux下读取ntfs数据,在Linux中读取NTFS分区上的数据
  19. 国家电力项目思路总结
  20. 英文学习20180321

热门文章

  1. 实践GoF的23的设计模式:SOLID原则(下)
  2. 看FusionInsight Spark如何支持JDBCServer的多实例特性
  3. 浅谈云网融合与SD-WAN
  4. 使用Mac终端设置alias常用别名,以git提交为例
  5. day16 java中的package和import
  6. VMware中安装deepin虚拟机
  7. JSP页面元素-新手向
  8. 局域网网管软件_局域网安全管理面临的4大挑战
  9. php中phpmyadmin打不开,解决phpMyAdmin打不开的方法
  10. python logger_牛逼!python中的logging模块居然这么好用!