浏览以下内容前,请点击并阅读 声明

java允许在一个类中定义另外一个类,这就叫类嵌套。类嵌套分为两种,静态的称为静态嵌套类,非静态的又称为内部类。

使用嵌套类的原因:

  1. 能够将仅在一个地方使用的类合理地组合。如果一个类可能只对于另外一个类有用,此时将前者组合到后者,可以使得程序包更加简洁。
  2. 增强封装性。假如由两个类A和B,B类需要使用A类中的成员,而恰好该成员又是仅类内部可见(private)的,如果将B定义为A的嵌套类,则B可以使用A的任何成员,而且B也可以声明为外部不可见(private),将B隐藏起来。
  3. 能够使代码可读性和维护性更强。嵌套的类代码相较于顶级类,更靠近它被使用的地方,方便查看。

嵌套类也属于类的成员,因此也可使用类成员的可视范围控制修饰词(public,protect,private),内部类能够使用其所在类的其他类成员,而静态嵌套类则不能使用其所在类的其他类成员。

静态嵌套类

与静态方法与静态字段类似,静态嵌套类是与其所在类相关的。静态嵌套类不能直接使用实例变量或者实例字段,而只能通过一个对象引用,可将静态嵌套类视为跟其他顶级类一样,只不过是内嵌在其他类里面,方便打包。

静态嵌套类的使用方法与类中的其他类成员类似,一下演示如何创建静态嵌套类对象:

//StaticNestedClass为OuterClass的一个嵌套类
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

内部类(非静态嵌套类)

内部类是与其所在类的实例相关的  ,能够直接使用实例对象的方法和字段,内部类与实例相关,所以内部类不能定义静态的成员。

如果需要创建内部类对象,首先需要创建该内部类所在的类的对象,如下所示:

//1创建内部类所在类的对象
OuterClass outerObject=new OuterClass();
//2创建内部类对象
//注意与静态嵌套类的构造器使用方法的差异
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

嵌套类的遮蔽

当我们声明一个类型时,如果其名称与当前代码块(如一个方法内部)所在的代码块(如类内部)内的另一个类型的声明含有相同的名称,这种现象就叫遮蔽。需要用到被遮蔽的类型时,我们不能直接引用其名称,如下例所示:

 public class ShadowTest {

    public int x = 0;
//嵌套类
class FirstLevel {
//以下声明会遮蔽其所在类的名称为x的字段
public int x = 1;
//以下方法的声明会遮蔽其所在类的名称为x的字段
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);//注意this关键词的使用方法
}
} public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}

上述代码输出为:

x = 23
this.x = 1
ShadowTest.this.x = 0

序列化,教程中强烈建议不要序列化内部类,在此留下疑问。

除了非静态嵌套类意外,还有两种内部类,一种是局部类,还有一种是匿名类。

局部类

局部类可以在任何代码块(花括号内)中定义,一般应用于方法之中。

局部类可以使用其所在顶级类的类成员,此外,局部类也可以使用局部变量,然而,其所使用的局部类必须有final关键词修饰,即不可变变量。在java SE8中,局部类可以使用本质上不变的局部变量,即该局部变量即便没有final关键词修饰,但实际上从初始化以后,其值从未改变过。

从java8开始,局部类也可以使用其所在方法的参数。

与内部类相似,局部类不能定义静态成员,在静态方法中定义的局部类不能使用实例成员。

在代码块中不能定义接口,因为接口本质是静态的。局部类中也不能定义借口成员,不过局部类中可以定义常量变量(用final修饰,类型为基本数据类型或者字符串,编译时进行初始化)。

匿名类

匿名类能是代码更加简洁,它不需要名称,可以声明,实例化一步完成。

匿名类的声明是一个表达式,如同调用一个构造器,不同的是其后还跟上了一个定义类的代码块。

匿名类的定义的表达式包含如下几个部分:

  • new关键词
  • 一个该匿名类需要实现的借口或者是继承的父类的名称
  • 一对圆括号,包含参数,实现一个接口时,参数部分留空
  • 匿名类主体,跟类的主体类似, 可以定义方法

匿名类对于可使用的类型与局部类相同:

  • 可使用其所在类的类成员
  • 可使用其所在代码块的带final修饰词的局部变量,或者初始化后不再赋值的局部变量(java8)
  • 对于遮蔽的类型,不能直接用名称引用

同样匿名类不能声明静态的成员或者接口,但是可以声明常量变量,在匿名类的类主体中,可以声明实例字段,实例方法,实例初始化代码块和局部类。

java-嵌套类的更多相关文章

  1. JAVA 嵌套类和内部类

    一.什么是嵌套类及内部类?  可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:  静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类, ...

  2. java嵌套类

    java有四种嵌套类: 静态内部类,成员内部类,局部内部类,匿名内部类 1)静态内部类: (1)类的申明加上staitc关键字.一般用public修饰 (2)只能访问外部类的静态变量和静态方法.不能访 ...

  3. 分析java 嵌套类与内部类

    一.什么是嵌套类及内部类?     可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类 ...

  4. 深入理解java嵌套类和内部类

    一.什么是嵌套类及内部类 能够在一个类的内部定义还有一个类.这样的类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类.静态嵌套类使用非常少,最重要的是非静态嵌套类,也 ...

  5. (十二)java嵌套类和内部类

    嵌套类和内部类:在一个类里边定义的类叫做嵌套类,其中没有static修饰的嵌套类是我们通常说的内部类,而被static修饰的嵌套类不常用.有的地方没有嵌套类和内部类的区分,直接是嵌套类就称作内部类,没 ...

  6. Java 嵌套类基础详解

    目录 1. 什么是嵌套类? 2. 为什么要使用嵌套类? 3. 嵌套类的类型 4. 静态嵌套类 5. 非静态嵌套类 5.1 成员内部类 5.2 局部内部类 5.3 匿名内部类 6. 嵌套接口 1. 什么 ...

  7. JAVA嵌套类:静态嵌套类和非静态嵌套类

    1.内部类定义 内部类在维基百科的定义为:  面向对象编程中,内部类(又叫做嵌套类)是在另一个类或者接口中进行声明的类.内部类不同于子类(subclass).(译者注:wiki的注解有误,内部类和嵌套 ...

  8. Java嵌套类,内部类和外部类

    1.嵌套类,内部类 嵌套类是指被定义在一个类内部的类: JAVA的嵌套类有很多种类:1.静态成员类:2.非静态成员类:3.匿名类:4.局部类:其中,除了静态成员类之外,其他的都是内部类,因为静态成员类 ...

  9. java 嵌套类 简记

    嵌套类包括:1)静态嵌套类  (static 修饰符) 2)非静态嵌套类(又叫内部类) 其中内部类又可分为三种: 其一.在一个类(外部类)中直接定义的内部类: 其二.在一个方法(外部类的方法)中定义的 ...

  10. Java 嵌套类和内部类演示样例<二>

    嵌套类(nested class)是一个在还有一个类或接口内部声明的类. 嵌套类分为两种:静态内部类(static inner class)和非静态嵌套类(non-static nested clas ...

随机推荐

  1. SQLServer自定义函数简单演示

    CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] par ...

  2. poj1308(简单并查集)

    题目链接:http://poj.org/problem?id=1308 题意:x, y 表示x 与 y连接,给出一波这样的数据,问这组数据能否构成树,即不能形成回路,不能有多个根节点:要注意可以是空树 ...

  3. NYOJ之算菜价

    Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable ...

  4. 微信支付 - V3支付问题

    参考资料:http://www.2cto.com/weixin/201506/407690.html   1.微信公众号支付出错: 当前页面的URL未注册: get_brand_wcpay_reque ...

  5. jQueryEasyUi验证

        多重验证: { field : 'startPort', title : "起始端口", editor: "text", width : 50, edi ...

  6. OS Boot Loader -- 启动器

    这篇文章先抛出来,现在还没有彻底研究明白,但可以做个个人的小结和整理: 记得刚开始搞Linux的时候,普遍采用的是grub,后来有了grub2,尤其是在ubuntu那种非常差劲的不稳定的更新频繁的系统 ...

  7. HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)

    当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...

  8. hdu 2897 巴什博弈变形 ***

    大意:一堆石子共有n个,A,B两人轮流从中取,每次取的石子数必须在[p,q]区间内,若剩下的石子数少于p个,当前取者必须全部取完.最后取石子的人输.给出n,p,q,问先取者是否有必胜策略? Bash博 ...

  9. hdu 5366 组合数 *

    考虑放1个,2个....的情况,相加就是最后的结果 #include<cstdio> #include<iostream> #include<algorithm> ...

  10. 第十八篇:在SOUI中实现PreTranslateMessage

    在MFC中,通常可以通过重载CWnd::PreTranslateMessage这样一个虚函数来实现对一些窗口消息的预处理.多用于tooltip的显示控制. 在SOUI中也实现了类似的机制. 要在SOU ...