JAVA从入门到精通-内部类、自动拆装箱、枚举
黄泽民 2018-04-03 来源 : 阅读 403 评论 0

摘要:要使JAVA从入门到精通,学习一下内容,内部类是在另外一个类中的类,叫做内部类(嵌套类),包含内部类的类称为外部类(宿主类);包装类是Java是面向对象的编程语言,但它也包含了8种基本数据类型;枚举类是enum很像特殊的class,实际上enum声明定义的类型就是一个类,这些类都是类库中Enum类的子类(java.lang.Enum),它们继承了Enum中许多有用的方法。让我们在JAVA从入门到精通中更远。

内部类

l 定义在另外一个类中的类,叫做内部类(嵌套类),包含内部类的类称为外部类(宿主类)

l Java编译器在编译时,一个类对应一个字节码文件(.class文件),所以内部类也会单独生成一个字节码文件

l 访问特点

Ø 内部类可以直接访问外部类中的成员,包括私有成员

Ø 外部类要访问内部类中的成员,必须要先创建内部类的对象

Ø 一般用于类的设计,会进行私有化,当然也有公有化的情况

l 在Java中,内部类可以分为以下 4 种

Ø 成员内部类

Ø 静态内部类

Ø 匿名内部类

Ø 局部内部类

l 内部类和外部类的语法大致相同,内部类除了需要定义在其他类里面之外,还存在如下两点区别:

1. 内部类比外部类多了三个修饰符:private、protected、static

2. 非静态内部类不能拥有静态成员

成员内部类

l 成员内部类属于外部类的实例成员

l 一个成员内部类实例属于它的外部类的实例

l 内部类对象有一个隐式引用,指向创建它的外部类对象

l 成员内部类的特殊语法

Ø OuterClass.this:表示对外部类当前实例的引用

Ø OuterObject.new InnerClass()

调用成员内部类的构造方法

Ø OuterClass.InnerClass:在外部类之外引用到的内部类类型

l 成员内部类有以下限制

Ø 成员内部类不能与外部类重名

Ø 不能在成员内部类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员内部类实例必然与一个外部类实例关联,static成员完全可以移到其外部类中去。

Ø 如果内部类中定义了静态成员,那么该内部类也必须是静态内部类(静态常量除外)

l 思考:为什么内部类可以直接访问外部类的成员?

Ø 因为内部类持有了外部类对象的引用: OuterClass.this

静态内部类

l 内部类对象有一个隐式引用,指向创建它的外部类对象

l 只有内部类可以用static修饰,外部类不能用static修饰

l 静态内部类可以访问外部类的静态成员

l 在接口中可以定义内部类,不过必须是public static修饰的

l 静态成员内部类有以下限制:

Ø 静态内部类不能与外部类重名

Ø 静态内部类不能直接访问外部类的实例成员(非static修饰的成员)

局部内部类

l 在方法中定义的内部类,叫做局部内部类

l 局部内部类不能加访问修饰符,因为它不是类的成员

l 作用域被限定在声明该类的代码块内部

l 局部内部类的优势

Ø 对外界世界完全隐藏

Ø 不仅能访问外部类的成员,还能访问所在代码块中的局部变量,但是这些局部变量必须都是final修饰的

 JAVA从入门到精通-内部类、自动拆装箱、枚举

匿名内部类

l 没有名称的内部类,叫做匿名内部类

l 使用内部类的前提:

Ø 内部类必须继承一个类或者实现一个接口

l 创建匿名内部类对象,需要采用另一种形式的new语句

Ø 语法

new interface/superclass(参数列表){ //匿名内部类的类体 }

这种形式形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口,并同时创建该匿名类的一个新对象。

l 关于匿名内部类还有如下两条规则

Ø 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类

Ø 匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义初始化代码块,可以通过初始化代码块来完成构造器需要完成的任务

PS:匿名内部类不能定义构造器,但是其本身拥有构造器,如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的参数列表。

l JDK 8新特性 —— effectively final

在Java 8之前,Java要求被局部内部类、匿名内部类访问的局部变量必须使用final修饰,从Java 8开始这个限制被取消了,Java 8变得更加智能:如果局部变量被匿名内部类或局部内部类访问,那么该局部变量相当于自动使用了final修饰。

Java 8 将这个功能称之为“effectively final”,它的意思是对于被匿名内部类访问的局部变量,可以用final修饰,也可以不用final修饰,但必须按照有final修饰的方式来使用,也就是一次赋值后,以后不能重新赋值。

包装类

l 包装类的概念

Java是面向对象的编程语言,但它也包含了8种基本数据类型,这8种基本数据类型不支持面向对象的编程机制,基本数据类型的数据也不具备“对象的特性”(没有成员字段和方法可以被调用),为了照顾程序员的传统习惯,Java就提供了包装类(Wapper Class)的概念,为8种基本数据类型分别定义了相应的引用类型,并称之为基本数据类型的包装类。

JAVA从入门到精通-内部类、自动拆装箱、枚举

l JDK 5新特性 —— 自动装箱、拆箱

在JDK1.5之前,把基本数据类型变成包装类实例需要通过对应的包装类的构造方法来实现,如果希望获得一个包装类对象中包装的基本类型变量,需要通过相应的方法来获取。

JAVA从入门到精通-内部类、自动拆装箱、枚举 

通过上面的介绍,大家会发现Java提供的基本类型变量和包装类对象之间的转换操作有些繁琐,但从JDK1.5开始,这种繁琐就消除了,JDK1.5提供了自动装箱(Autoboxing)和自动拆箱(AutoUnboxing)功能。

Ø 所谓自动装箱,就是可以把一个基本类型变量直接赋值给对应的包装类变量,或者赋值给Object类的引用(这里涉及了自动上转型)

Ø 自动拆箱则与之相反,允许把包装类对象直接赋给一个对应的基本类型变量

l 常用方法

Ø 将字符串转换成基本数据变量(2种)

Xxx(String s) // 构造方法

parseXxx(String s) // 静态方法

l 包装类实例和基本类型变量之间的比较

虽然包装类是引用数据类型,但是包装类的实例可以与数值类型的值直接进行比较,这种比较是直接取出包装类实例所包装的数值来进行比较。看下面代码。

 JAVA从入门到精通-内部类、自动拆装箱、枚举

两个包装类实例进行比较的情况就比较复杂一些,如果值是判断大小,那么就是直接按照包装的数值进行比较,如上图中的代码所示。但如果判断是否相等的话,就要考虑到包装类实例本身是引用数据类型,之前我们学过,用“==”来判断两个引用时,其实判断的是两个引用指向的是否是同一个对象内存,如果是的话返回true,否则返回false。看下面代码。

 JAVA从入门到精通-内部类、自动拆装箱、枚举

但是JDK1.5以后加入了自动拆、装箱的新特性,那么代码就可以这么写,情况会有一些不同。看下面代码

 JAVA从入门到精通-内部类、自动拆装箱、枚举

上面的程序结果是否令人费解?就让我们来深入探讨一下。

枚举类型

l enum很像特殊的class,实际上enum声明定义的类型就是一个类,这些类都是类库中Enum类的子类(java.lang.Enum<E>),它们继承了Enum中许多有用的方法。

l 枚举值都是public static final的,也就是常量,因此枚举类中的枚举值应该全部大写。

l 枚举类型是class,在枚举类型中有构造器、方法和字段。

但枚举的构造器有很大的不同:

Ø 构造器只是在构造枚举值的时候被调用

Ø 构造器私有private,不允许有public构造器

希望这篇文章可以帮助到你,总之同学们,it资讯尽在职坐标。

本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:13167058313
小职老师的微信号:13167058313

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    ICP许可  沪B2-20190160

站长统计