Java有各类各样类,内部类、嵌套类、成员类、局部类(本地类)、静态类、匿名类、文件类以及这些组合起来的称呼类,成员内部类,成员匿名类,成员嵌套类,本地匿名类等,真是多的不行,但有些实际上是一个意思,在这里好好理一理。java
1.注意,这些称呼都是翻译过来的,可是同一个英文单词或一个词组翻译过来可能有不一样叫法,好比local nested class,local有局部、本地意思,实际上是一个意思,local nested class翻译过来就是局部嵌套类(本地嵌套类),又由于非静态嵌套类都称为内部类,因此local nested class又叫为内部局部类(本地内部类),最终又简称为:局部类(本地类)。我我的以为局部类更加形象点因此下面都优先采用局部类一说。
2.我经过搜索找到两种不太相同的内部类定义,一种认为:定义在类里面的称为嵌套类(nested class),而非静态嵌套类才是内部类(inner class),也就是说嵌套类包含内部类;另一种则是认为:定义在类里面的称为内部类,这样静态嵌套类也是内部类,也就是说嵌套类=内部类。可是,第一种才是Java语言规范规定的,我一开始不肯定,找到Java7的语言规范验证,结果确实如此,即第一种才是正确的,那么问题来了:依照第一种划分,静态内部类实际上是一种错误说法。。。只有静态嵌套类,内部类是没有静态一说的!
可是对于大多数中国程序员,貌似将定义在类里面的类称为内部类不是更符合文意么?也许这就是为何会有这么多人一直认为静态内部类的存在。嘛,反正无论怎么称呼,只要知道表明什么意思就好,细节什么的不要在乎(光哥:因此不注意细节的你写的代码才这么一大堆bug么?还不赶忙去改(怒吼))。
我这里采用Java语言规范上说的。程序员
文件类放在最前面,是由于文件类是与主类(一个文件中public类)关系最不密切的一类。什么是文件类?看代码就知道:express
public class Main{} class Test{}//Test就是文件类 //是的,一个.java文件里面定义在主类外面的就是文件类 //主类、文件类称为顶级类(top level class),Java语言规范中定义:非嵌套类即为顶级类。
【注意】:主类这必定义是我本身按语义称呼的,有的地方称为基本类,但我以为很不符合语义,Java语言规范我也没找到相关定义。ide
由上面文件类可有相似定义:一个.java文件里面定义在类里面的就是嵌套类,定义在类内部,包括块、静态块、构造器、方法内。这个时候该类也相对来被称为包装类(enclosing class)或外部类。
嵌套类是能够有层次的,也就是说嵌套类里面还能够定义类,成为嵌套类中的嵌套类。
在Java语言规范里面,嵌套类定义是:spa
A nested class is any class whose declaration occurs within the body of another class or interface.
说的简单一点,就是定义在类(这里还包括接口,下同)里面的类。因此说,如下全部的类均可以称为嵌套类。嵌套类分为两种:静态嵌套类和非静态嵌套类,非静态嵌套类就是内部类(inner class)。.net
简称静态类,和主类关系也不大,只是在其余类中引用使用的时候须要加上外部类限定,但在技术上来看,彻底是两个独立无关系的类。翻译
public class Main{ public static class NestClass{} } //在外面使用时候形式以下,在Main中使用则不须要加上外部类限定 Main.NestClass nestClass = new Main.NestClass();
从形式上来看,静态类能够说是类的一个静态成员(因此也能够说是成员类一种),但从技术上来看,其实两者没什么关系,能够看作第三类顶级类。但也所以,静态类不怎么经常使用,由于它同通常类没什么优点可言。code
Java语言规范里的定义:对象
An inner class is a nested class that is not explicitly or implicitly declared static. //即非静态嵌套类即为内部类
内部类包括:成员类、局部类、匿名类。blog
public static final int a = 6;
这里说的是非静态成员内部类(若是静态嵌套类也算是成员类一种的话),non-static member (inner) class。而通常说的也是这种,但从技术上来看,成员类应该还包括静态嵌套类。
A member class is a class whose declaration is directly enclosed in another class or interface declaration.
成员类算是最多见最经常使用的一种内部类,咱们通常说的内部类说的就是成员类:在类里面,但不在块、构造器、方法里面。
//成员类,从技术上来讲,能够分为两种:成员内部类和成员嵌套类。 //1.成员内部类即这里说的成员类,全称是非静态成员内部类 //2.成员嵌套类即上面的静态嵌套类 public class Main{ public class MemberClass{}//成员内部类,常简称为成员类 }
成员类,可使用public,private,protected访问控制符,也能够用static,final关键字修饰,而且有enclose class属性。
这里题外说明一下:
local nested class,局部嵌套类,简称局部类,局部类所属范围:在块、构造器以及方法内,这里的块包括普通块和静态块。局部类只在本块范围内有效。
定义:
A local class is a nested class (§8) that is not a member of any class and that has a name.
翻译过来就是:局部类是嵌套类,但不是成员类,并且有名称(不是匿名类)。
public class Test { { class AA{}//块内局部类 } public Test(){ class AA{}//构造器内局部类 } public static void main(String[] args){ } public void test(){ class AA{}//方法内局部类 } } //注意到了吧,能够同名,编译后,造成诸如:外部类名称+$+同名顺序+局部类名称 //Test$1AA.class/Test$2AA.class/Test$3AA.class
局部类最多只能有final修饰,但不一样的是,块内局部类有enclose class属性,而构造器局部类有enclose constructor属性,方法局部类有enclose method属性,嘛,其实很好理解的吧,一看就知道。
定义:
An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler
匿名类,就是没有名称的类,其名称由Java编译器给出,通常是形如:外部类名称+$+匿名类顺序,没有名称也就是其余地方就不能引用,不能实例化,只用一次,固然也就不能有构造器。
匿名类根据位于地方不一样分为:成员匿名类和局部匿名类。
public class Test { InterfaceA a = new InterfaceA() {};//成员匿名类 public static void main(String[] args){ InterfaceA a = new InterfaceA() {};//局部匿名类 //以上两种是经过实现接口实现匿名类,称为接口式匿名类,也能够经过继承类 Test test = new Test(){};//继承式匿名类 //还能够是位于参数上 new Thread(new Runnable() { @Override public void run() { } }).start();//属于局部匿名类一种 } private interface InterfaceA{} }
匿名类不能使用任何关键字和访问控制符,匿名类和局部类访问规则同样,只不过内部类显式的定义了一个类,而后经过new的方式建立这个局部类实例,而匿名类直接new一个类实例,没有定义这个类。匿名类最多见的方式就是回调模式的使用,经过默认实现一个接口建立一个匿名类而后,而后new这个匿名类的实例。
本文讨论的是:嵌套类、内部类、成员类、局部类、匿名类相关,这些类的划分主要是根据类声明(或位于)的地方划分的: 1.嵌套类,位于类内部,又分为:静态嵌套类和非静态嵌套类。 2.静态嵌套类即为静态类。静态类只有这一种,技术来讲,也能够当作静态成员类。 3.非静态嵌套类即为内部类,又分为:成员类、局部类(本地类)、匿名类。 4.成员类:位于类内部但不包括位于块、构造器、方法内,且有名称的类。 5.局部类:位于块、构造器、方法内的有名称类。 6.匿名类:类内无名称类,又可细分为:成员匿名类和局部匿名类。