面向对象(最终版)
使用内部类
- 1.在外部类内部使用内部类—不要再外部类的静态成员中使用非静态内部类,因为静态成员不能访问非静态成员
- 2.在外部类以外使用非静态内部类
- prviate修饰的内部类只能在外部类内部使用
- 在外部类以外的地方使用内部类,内部类完整的类名应该OuterClass.InnerClass
- 在使用外部类以外的地方使用非静态内部类创建对象的语法如下:OuterClass.InnerClass
- 在外部类以外的地方使用非静态内部类创建对象的语法如下:OuterInstance.new InnerConstructor()
- 在外部类以外的地方使用静态内部类创建对象的语法如下:new OuterClass.InnerConstructer();
局部内部类
- 如果把一个内部类放在方法里定义,这就是局部内部类,仅仅在这个方法里有效
- 局部内部类不能在外部类以外的地方使用,那么及局部内部类也不能使用访问控制符和static修饰
匿名内部类
- 匿名内部类适合创建那种只需要一次使用的类,定义匿名内部类的语法格式如下:
- new父类构造器(实例列表)|实现接口)
- {
- //匿名内部类的类体部分
- }
- 匿名内部类不能是抽象类,匿名内部类不能定义构造器
Lambda表达式入门
- Lambda表达式主要作用就是代替匿名内部类的繁琐语法。它由三部分组成:
- 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略
- 箭头(->),必须通过英文等号和大于符号组哼
- 代码块。如果代码块只有包含一条语句,Lambad表达式允许省略大妈快的花括号,如果省略了代码块的花括号,这条语句不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块种仅有一条省略了return的语句,Lambda表达式会自动返回这条语句的值
Lambda表达式与函数接口
-
如果采用匿名内部类语法来创建函数时接口的实例,只要实现一个抽象的方法即可,在这种情况下即可次啊用Lambda表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口
-
Lambda表达式由如下两个限制:
—Lambda表达式的目标类型必须是明确的函数式接口。
—Lambda表达式只能为函数式接口创建对象。Lambda表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数式接口)创建对象
-
为了保证Lambda表达式的目标类型是一个明确的函数式接口,可以由如下三种常见的方式:
—将Lambda表达式赋值给函数式接口类型的变量。
—将Lambda表达式作为函数接口类型的参数传给某个方法。
—使用函数式接口对Lambda表达式进行强制类型转换
方法引用与构造器引用
Lambda表达式与匿名内部类
-
Lanbda表达式与匿名内部类存在如下相同点:
—Lambda表达式与匿名内部类一样,都可以直接访问“effectively final"的局部变量,以及外部类的成员变量(包括实例变量和类变量)—Lambda表达式创建的对象与匿名内部类生成的对象一样,都可以直接调用从接口继承得到默认方法
-
Lambda表达式与匿名内部类主要存在如下区别:
—匿名内部类可以为任意接口创建实例——不管接口包含多少个抽象方法,只要匿名内部类实现所以的抽象方法即可。但Lambda表达式只能为函数式接口创建实例。
—匿名内部类实现的抽象方法的方法体允许调用接口中定义的默认方法:但Lambda表达式的代码块不允许调用接口中定义的默认方法。
手动实现枚举类
-
可以采用如下设计方式:
—通过private将构造器隐藏起来
—把这个类的所由可能实例都是用public static final属性来保存
—如果有必要,可以提供一些静态方法,允许其他程序根据特定参数来获取与之匹配的实例
JDK 5新增的枚举支持
- J2E 1.5新增一个enum关键字,用以定义枚举类。正如前面看到,枚举类是一种特殊的类,它一样可以有自己的方法和属性,自己实现一个或者多个几口,也可以定义自己的构造器。一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须要和枚举类的类名相同
枚举类
- 枚举类可以实现一个或者多个接口,使用enum定义的枚举类默认继承了java.lang.Comparable两个几口
- 枚举类的构造器只能使用prviate访问控制符,如果还省略了其构造器的访问控制符,则默认使用private修饰符
- 枚举的所有实例必须在枚举类中显示列出,否则这个枚举类将永远都不能产生实例。列出这些实例时系统会自动添加public static final修饰,无需程序员显示添加。
- 所有枚举类都提供了一个values方法,该方法可以很方便的遍历所有的枚举值
枚举的属性、方法和构造器
- 枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以使用属性和方法。
- 灭据类通常应该设计成不可变类,也就是说它的属性值不因该允许改变,这样会更加安全,而且代码更加简洁。为此,我们应该将枚举类的属性都是用private final修饰
- 一旦为枚举类显示定义了带参数的构造器,则列出枚举值时也必须对应地传入参数
实现接口地枚举类
- 枚举类也可以实现一个或多个接口,与普通类实现一个或多个接口完全一样,枚举类实现一个或多个接口时,也需要实现该接口所包含的方法
- 如果需要每个枚举值在调用同一个方法时呈现出不同的行为方式,则可以让每个枚举值分别来实现该方法,每个枚举值提供不同的实现方式,从而让不同枚举值调用同一个方法时具有不用的行为方式
包含抽象方法的枚举类
- 可以在枚举类里顶一个抽象方法,然后把这个抽象方法交给各枚举值去实现即可
- 枚举类里定义抽象方法时无需显示使用,因为枚举类需要显式创建枚举值,而不是作为父类,所以定义每个枚举类时必须为抽象方法提供实现,否则将出现编译错误
垃圾回收机制
- 垃圾回收机制这负责回收堆内存中对象,不会回收任何物理资源(例如数据库连接,网络IO等资源
- 程序无法精确控制垃圾回收的运行,垃圾回收会在合适时候进行垃圾回收。当对象永久性地失去引用后,系统就会在合适时候回收它所占的内存
- 垃圾回收机制回收任何对象之前,总会先调用它的fianalize方法,该方法可能使该对象重新付汇(让一个引用变量重新引用该对象),从而导致垃圾回收机制取消回收
对象在内存中的状态
- 激活状态:当一个对象被创建后,有一个以上的引用变量引用它。则这个对象在程序中处于激活状态,程序可通过引用变量来调用该对象的属性和方法
- 去活状态:如果程序中某个对象不再有任何引用变量引用它,他就进入了去活状态。在这个状态下,系统的垃圾回收机制准备回收该对象所占用的内存,在回收该对象之前,系统会调用所有取货状态对象的finalize方法进行资源清理,如果系统在调用finalize方法重新让一个引用变量引用该兑现给,则这个对象会再次变为激活状态;否则该对象将进入死亡状态。
- 死亡状态:当对象与所有引用变量的关联都被打断,且系统会调用所有对象的fianlize方法依然没有使该对象变成激活状态,那这个对象将永久性地失去引用,最后变成死亡状态。只有当一个对象处于死亡状态时,系统才会真正回收该对象所占有的资源
强制垃圾回收
- 强制垃圾回收有如下两个方法:
- 调用System类的go()静态方法:System.gc()
- 调用Runtime对象的gc()实例方法:Runtime.getRuntime().ge()
finalize方法
- finalize方法有如下四个特点:
- 永远不要主动调用某个对象的finalize方法,该方法应交给垃圾回收机制调用
- fianalize方法的何时被调用,是否被调用具有不确定性。不要把finalize方法当成一定会被执行的方法
- 当JVM执行去活对象的finalize方法时,可能使该对象,或系统中其他对象重新变成激活状态
- 当JVM执行fianalize方法时出现了异常,垃圾回收机制不会报告异常,程序继续执行
对象的软、弱和虚引用
- 强引用(StrongReference)
- 软引用—软引用通过SoftReference类来实现,当一个对象只具有软应用时,它有可能被垃圾回收机制回收
- 弱引用—弱引用通过WeakReference类来实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收极致运行时,不管系统内存是否足够,总会回收该对象所占用的内存
- 虚引用—虚引用通过PhantomReference类实现,虚引用完全类似于没有引用。虚引用对对象本身影响不大,对像甚至感觉不到虚引用的存在
使用JAR文件好处
- 安全
- 加快下载速度
- 压缩
- 包封装
- 可移植性
jar命令详解
- -c创建文档,-t列出存档内容的列表,-x展开存档中的命名文件
- -u更新已存在的存档,-v生成详细输出到标准输出上
- -f指定存档文件名,-m包含来自标文件的标明信息
- -e指定生成JAR包和主类
- -0 只存储方式:未用ZIP压缩格式
- -M 不产生所有项的清单文件,-i为指定的jar文件产生索引信息
- -C 改变到指定的目录
- –release:用于指定版本,生成多版本的JAR包
创建可执行的JAR包
- 使用平台相关的编译器将整个应用编译成平台相关的可执行文件
- 为整个应用编辑一个批处理文件
关于JAR技巧
- 相当于一个压缩文件
- 可使用WinRAR来压缩JAR包
- 也可使用WinRAR来查看JAR包