第六章 面向对象(下)

包装类

  • 通过包装类将八种基本类型的值包装成对象使用
  • 自动装箱:把基本类型变量赋给对应包装类变量
  • 自动拆箱:把包装类变量赋给对应基本类型变量
  • 自动装箱拆箱必须类型匹配,赋给Object是利用了向上转型特性
  • 包装类的parseXxx(String s)方法和Xxx(String s)构造器将字符串转换成基本类型
  • String类重载valueOf()方法将基本类型转换成字符串
  • 包装类实例可以与数值类型的值比较
  • 两个包装类引用指向同一个对象时才相等
  • 包装类的compare(xxx val1, xxx val2)方法比较基本类型值大小,布尔值true>false

处理对象

  • syso打印会自动toString(),可用于对象的自我描述,所有类都可以重写toString()
  • 引用变量指向同一对象时==才会true
  • ==只能用于比较有继承关系的两个对象
  • new String("hello");共产生两个字符串对象
  • jvm使用常量池保存"hello"
  • 调用String构造器创建新对象,新"hello"被保存在堆内存
  • jvm常量池保证相同字符串常量只有一个
  • String的equal()已经重写了,字符序列相同返回true
  • 默认Object的equal()只是比较地址,需要时可重写提供自定义相等标准
  • if(obj!=null && obj.getClass()==Person.class)当obj是Person对象时

类成员

  • static不能修饰构造器
  • null对象可以访问类成员,因为会在底层转换为类去访问
  • 单例类,只能创建一个对象,private修饰构造器,public static方法作为类的访问点,static成员变量保存层创建的对象

final

  • final可修饰类、变量、方法
  • 修饰成员变量,必须显示指定初始值,不能重新赋值
  • 类变量:静态初始化块或声明时指定初始值
  • 实例变量:非静态初始化块、构造器或声明时指定
  • 修饰局部变量,只能赋值一次,final修饰的形参不能在代码块里赋值
  • 修饰引用变量时不能改变的是地址,对象可以改变
  • 直接量,变量其实不存在,编译时宏替换
  • final修饰变量
  • 定义时确定初始值
  • 初始值编译时能确定
  • final修饰的方法不能被重写
  • private final同时修饰重写其实是创建新方法
  • final修饰类不能被继承
  • 不可变类:创建实例后,其实例变量不可改变
  • 创建不可变类:
  • private final修饰成员变量
  • 带参数构造器用来初始化成员变量
  • 不能提供setter方法
  • 有必要时重写hashCode()和equals(),保证equals()相等时haahCode()也相等
  • 类的引用变量实例改变时属于可变类,在构造器和getter方法中使用创建新对象的方法实现真正不可变类
  • Integer的valueOf缓存,范围导致不在范围的不被缓存,能缓存的同值对象则返回同一地址

抽象类

  • 抽象方法abstract修饰,不能有方法体,圆括号后一个分号
  • 有抽象方法的类必须定义成抽象类,抽象类里可以没有抽象方法
  • 抽象类不能被实例化,只能被继承
  • 抽象类的构造器不能用于创建实例,只能被子类调用
  • 抽象类更好发挥多态优势,父类变量调用子类实现后的抽象方法时无须转换为子类类型
  • abstract和final不共存
  • abstract和static不能同时修饰方法,可以同时修饰内部类
  • abstract和private不能同时修饰方法
  • 模板模式,车速表
  • 抽象父类抽象不能实现的方法
  • 父类定义通用算法,其它依赖于子类去实现

接口

  • public/default interface修饰,public修饰时与源文件同名
  • 接口只能继承接口,多继承
  • 成员可以是静态常量、抽象方法、内部类、接口、枚举、默认方法和类方法
  • 接口所有成员都是public访问权限,可省略
  • 系统自动为静态常量增加public static final
  • 抽象方法自动修饰为public abstract
  • 默认方法必须用default修饰,不能用static,自动public修饰
  • 类方法必须用static修饰,不能用default,子的钱public修饰
  • 内部类、内部接口、内部枚举自动oublic static
  • 实现类可实现多个接口,implements,必须实现接口的所有抽象方法,否则需要定义成抽象类
  • 实现抽象方法时注意加上public
  • 接口引用变量可以直接赋给Object引用变量
  • 简单工厂模式


  • 命令模式


内部类

  • 作用
  • 提供更好的封装,不允许其他类访问
  • 直接访问所在外部类的私有数据
  • 匿名内部类创建只需要使用一次的类
  • 内部类多可用private、protected、static修饰符
  • 非静态内部类不能拥有静态成员
  • 内部类也会生成.class文件OuterClass$InnerClass.class
  • 非静态内部类内可直接访问外部类的private成员
  • 非静态内部类的对象里会保存它所寄生的外部类对象的引用
  • 覆盖的成员变量可以用OuterClass.this.、this.作区分
  • 外部类不能直接使用非静态内部类成员,必须显式创建对象来调用
  • 外部类的静态成员不能直接使用非静态内部类
  • 非静态内部类中不能定义静态成员
  • 静态内部类可以包含静态成员,也可以包含非静态成员
  • 静态内部类内部不能访问外部类的实例成员,只能访问外部类的类成员,因为静态内部类持有外部类的引用,没有外部类对象的引用
  • 外部类不能直接访问静态内部类的成员,可以用内部类的类名作调用者来访问
  • 接口内可以定义内部类,默认用public static修饰
    所以接口的内部类只能是public访问权限并且是静态的
  • 在外部类以外的地方创建内部类引用变量:PackageName.OuterClass.InnerClass varName
    需要完整的类名
  • 在外部类以外的地方创建非静态内部类之前需要先创建外部类对象,在用外部类的实例作调用者调用内部类构造器new Out().new In();
  • 创建非静态内部类的子类的时候要保证子类构造器能够调用内部类的构造器,也就是必须存在一个外部类对象,参数传进子类构造器,out.super();调用内部类构造器
  • 内部类子类对象一样需要保留其父类所在外部类对象的引用
  • 创建静态内部类对象时无须创建外部类对象,因为它是类相关的,只需要把类名写全调用内部类构造器就可以了
  • 使用静态内部类只需要把外部类看做包空间,比较简单,程序需要时,优先考虑静态内部类
  • 不存在子类继承外部类去重写内部类,因为内部类类名还由外部类类名组合构成,不可能做到两个类的内部类是一样的名字,所以不能重写
  • 局部内部类不能使用访问修饰符,因为一定不能被其他类访问
  • 创建匿名内部类时会立即创建一个该类的实例,类定义立即消失
  • 匿名内部类必须继承一个父类,或实现一个接口
    new 实现接口()|父类构造器(实参列表){内部类实体部分}
  • 匿名内部类不能是抽象类,因为会随即创建对象
  • 匿名内部类不能定义构造器,因为没有类名
  • 通过父类继承创建的匿名内部类会拥有和父类相同形参列表的构造器
  • 如果局部变量被匿名内部类访问,变量就需要用final修饰,不能重复赋值
  • Lambda简化创建只有一个抽象方法的接口(函数式接口)的实例
  • (形参列表)->{代码块}
  • 如果只有一条语句,可以省略花括号,如果有返回值且只有一条语句,可以省略return关键字,会自动返回唯一语句的值
  • 允许省略形参类型,如果形参只有一个,可以省略圆括号
  • 函数式接口可以包含多个默认方法、类方法,但只能有一个抽象方法
  • Lambda表达式结果被当成对象,所以可以赋值,只能为函数式接口创建对象,也可以通过函数式接口强制类型转换,再赋值
  • Lambda实现的匿名方法的形参列表必须和函数式接口的唯一抽象方法形参列表相同
  • 如果Lambda表达式中只有一条语句,可以使用方法引用和构造器引用


  • Lambda表达式可以直接访问final局部变量和外部成员变量
  • 匿名内部类可以为任意接口、抽象类、普通类创建实例,Lambda只能是函数式接口
  • Lambda限制代码块不能调用接口中定义的默认方法,匿名内部类可以

枚举类

  • 一个java源文件最多定义一个public enum,且源文件名与枚举类类名相同
  • enun默认继承java.lang.Enum,未继承Object类,不能显式继承其他类
  • 非抽象enun默认用final修饰,不能派生子类
  • 枚举类构造器默认private修饰,且只能private 修饰
  • 所有实例在第一行列出 否则永远不能产生实例,自动public static final修饰
  • 访问枚举类某实例:EnumClass.variable
  • switch语句的表达式可以是枚举值
  • values()方法返回枚举类的所有实例
  • 枚举类通常应该设计成不可变类,成员变量用private final修饰,在构造器中指定初始值,列出枚举类实例时传入参数:枚举值("实参"),……
  • 实现接口的枚举类可以让每个枚举值分别去实现抽象方法,枚举值("实参"){...抽象方法(){}...}
  • 抽象枚举类不用final修饰,用abstract修饰
  • 实现接口的枚举值实际上是枚举类的匿名子类的实例
  • 定义了抽象方法的枚举类不能用abstract修饰,因为枚举类需要显式创建枚举值,而不是父类,定义每个枚举值时必须实现抽象方法

对象与垃圾回收

  • 垃圾回收机制只负责回收堆内存中的对象
  • 程序无法控制垃圾回收的运行,只能控制对象不被引用,不能控制何时被回收
  • 垃圾回收机制回收对象之前会调用finalize()方法,该方法可能使让对象复活,让一个新的引用变量引用该对象,导致垃圾回收机制取消
  • 对象的三种状态
  • 可达状态 有一个或一个以上引用变量引用它
  • 可恢复状态 没有引用变量引用,开始调用finalize()方法
  • 不可达状态 没有引用,finalize()也已经调用
  • 被其他类的类变量引用的对象,只有类被销毁,对象才会进入可恢复状态
  • 被其他对象的实例变量引用的对象,只有当对象被销毁,才进入可恢复状态
  • 强制系统垃圾回收(只是通知)
  • System.gc() System类的静态方法gc()
  • Runtime.getRuntime().gc() Runtime对象的实例方法gc()
  • java命令的-verbose:gc可以看到每次垃圾回收后的提示信息
  • finalize()方法返回后,对象消失,垃圾回收机制开始执行
  • 永远不要主动调用某对象的finalize()方法,应该交给垃圾回收机制去调用
  • finalize()何时被调用、是否被调用具有不确定性
  • JVM执行finalize()出现异常时,垃圾回收机制不会报告异常,程序继续执行
  • 因为finalize()不一定会被调用,所以想清理某个类里打开的资源时,不要放在finalize()里
  • 引用类型
  • 强引用,最常见的普通引用方式
  • 软引用,通过SoftReference类来实现,对于只有软引用的对象来说,当系统内存空间不足时,系统可能会回收它,软引用通常用于对内存敏感的程序中
  • 弱引用,通过WeakReference类来实现,对于只有弱引用的对象,当垃圾回收机制运行时,不管系统内存空间是否足够,总会回收其所占内存
  • 虚引用,通过PhantomReference类来实现,完全类似于没有引用,主要用于跟踪对象被垃圾回收的状态,不能单独使用,必须和引用队列(ReferenceQueue)联合使用
  • 三种引用类都有get()方法,用于获取被他们所引用的对象(虚引用获取不到)
  • 联合使用软引用、弱引用和引用队列时,在对象回收之后,将把对应引用添加到关联的引用队列。虚引用则是在回收之前添加,使得可以在回收之前采取行动
  • 程序可以通过检查与虚引用关联的引用队列中是否包含该虚引用,从而了解对象的状态
  • 从软、弱引用中取出被引用的对象时,可能该对象已经被释放了

修饰符的适用范围

  • strictfp用来精确浮点
  • native修饰方法引入C语言实现,会失去跨平台性
  • 4个访问控制符互斥
  • abstract final不共存
  • abstract static不能同时修饰方法,可以同时修饰内部类
  • abstract private不能同时修饰方法,可以同时修饰内部类
  • private final同时修饰方法合理但无意义
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 以下是《疯狂Java讲义》中的一些知识,如有错误,烦请指正。 Java8增强的包装类 自动装箱就是把一个基本类型的...
    hainingwyx阅读 389评论 0 0
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,567评论 18 399
  • 面向对象(下) 6.1 java8增强的包装类 int Integerchar Character其他的都是直接首...
    娄童阅读 586评论 0 2
  • 1 面向对象No6 面向对象 OO Object Oriented 编程时以对象为单元,封装数据和逻辑,以此提...
    征程_Journey阅读 1,122评论 0 2
  • 大家好,我是栗子徐,很高兴在这里认识你。 坚持写公号是一件酝酿了很久的事情,在我差不多理清了毕业这件事之后,才开始...
    栗子田阅读 188评论 0 0