内部类

Posted 雨晨漫步

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类相关的知识,希望对你有一定的参考价值。

在一个.java源文件中,只能定义一个类名与文件名完全一致的公开类,使用public class关键字来修饰。但在面向对象语言中,任何一个类都可以在内部定义另外一个类,前者为外部类,后者为内部类。内部类本身就是类的一个属性,与其他属性定义方式一致。比如,属性字段private static String str,由访问控制符、是否静态、类型、变量名组成,而内部类private static class Inner,也是按这样的顺序来定义的,类型可以为class、enum、甚至是interface,当然在内部类中定义接口是不推荐。内部类可以是静态和非静态的,它可以出现在属性定义、方法体和表达式中,甚至可以匿名出现,具体分为如下四种。
 ·静态内部类,如:static class StaticInnerClass;
 ·成员内部类,如:private class InstanceInnerClass;
 ·局部内部类,定义在方法或者表达式内部;
 ·匿名内部类,如:(new Thread()).start()。
如下是最精简的4种内部类定义方式:

点击查看代码
 public class OuterClass 
   
  // 成员内部类 
  private class InstanceInnerClass 

  // 静态内部类
  static class StaticInnerClass 
  
  public static void main(String[] args) 

   // 两个匿名内部类,分别对应图2-1所示的OuterClass$1和OuterClass$2
   (new Thread()).start();
   (new Thread()).start();
  
  // 两个方法内部类,分别对应图2-1所示的OuterClass$1MethodClass1和
  // OuterClass$1MethodClass2
  class MethodClass1
  class MethodClass2  
  

无论是什么类型的内部类,都会编译成一个独立的.class文件。 外部类与内部类之间使用$符号分割,匿名内部类使用数字进行编号,而方法内部类,在类名前还有一个编号来标识是哪个方法。匿名内部类和静态内部类是比较常用的方式。在本书的示例代码中经常使用匿名类来启动线程,节约了若干行代码。而静态内部类是最常用的内部表现形式,外部可以使用OuterClass.StaticInnerClass直接访问,类加载与外部类在同一个阶段进行,在JDK源码中定义包内可见静态内部类的方式很常见,这样做的好处是: (1)作用域不会扩散到包外 (2)可以通过“外部类.内部类”的方式直接访问 (3)内部类可以访问外部类中的所有静态属性和方法
点击查看代码
static class Node<K,V> implements Map.Entry<K,V> 
  final int hash;
  final K key;
  volatile V val;
  volatile Node<K,V> next;

如上所示的源码是在ConcurrentHashMap中定义的Node静态内部类,用于表示一个节点数据,属于包内可见,包内其他集合要用到这个Node时,直接使用ConcurrentHashMap.Node。仅包内可见,可以阻止外部程序随意使用此类来生成对象,Node的父类Entry是Map的静态内部类,之所以可以被Node成功继承,是因为两个外部类同属一个包。在JDK源码中,使用内部类封装某种和操作的方式比较常见,比如应用类加载器Launcher的AppClassLoader,ReentrantLock中继承自AbstractQueuedSynchronizer的内部类Sync,ArrayList中的私有成员内部类SubList。内部类中还可以定义内部类,形成多层嵌套,如在ThreadLocal静态内部类ThreadLocalMap中还定义一个内部类Entry。 因为访问权限可见,所以在同一个包内的Thread可以直接使用如下方式声明自己的属性: ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal.ThreadlLocalMap inheritableThreadLocals = null;

内部类之静态内部类

一.类内部类(静态内部类)定义:若使用static来修饰一个内部类,则这个内部类就属于外部类本身,就不属于外部类的某个对象(区别于非静态内部类)

二.静态内部类可以包含静态成员,也可以包含非静态成员;静态内部类的实例方法也不能访问外部类的实例成员

技术分享图片


三.外部类虽然不能直接访问静态内部类的成员.但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的          实例方法

技术分享图片

技术分享图片

 

以上是关于内部类的主要内容,如果未能解决你的问题,请参考以下文章

内部类

内部类

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

一个java内部类有几个分类?

内部类之静态内部类

java内部类的匿名内部类