自动装箱:把一个基本类型变量直接赋值给对应的包装类变量
自动拆箱:把包装类对象直接赋给一个对应的基本类型变量
处理对象
打印对象和toString方法
对象都具有toString,,重写toString()方法,就可以让系统在打印对象时,打印出该对象"自我描述"信息
==和equals方法
Java程序中测试两个变量是否相等有两种方式:一种是利用==运算符,另一种利用equals()方法。
==方法
当使用==来判断两个变量是否相等
如果两个变量是基本类型变量,且都是数值类型,则只要两个变量的值相等,就返回true
对于两个引用类型变量,只有当他们指向同一个对象是,==判断才返回true。==不可用于比较类型上没有父子关系的两个对象。
常量池专门用于管理在编译时被确定并保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。
JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本。使用new String()创建的字符串对象是运行时创建出来的,他被保存在运行时内存区(即堆内存)内,不会放入常量池中。
equals()方法
可以判断大部分字段的值是否相等
是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法来判断是否与其他引用变量相等。使用这个方法判断两个对象相等的标准与使用==运算符没有区别,同样要求两个引用变量指向同一个对象才会返回true。
类成员
static关键字修饰的成员是类成员,static关键字不能修饰构造器。static修饰的类成员属于整个类,不属于单个实例。
理解类成员
Java里只能包含成员变量,方法,构造器,初始化块,内部类五种
static修饰成员变量,方法,初始化块,内部类,以static修饰的成员就是类成员。类成员属于整个类,而不属于单个对象。类变量属于整个类,当系统第一次准备使用该类时,系统回味i该类提供变量分配内存空间,类变量开始生效,直到该类被卸载。
通过对象来访问类变量时,系统会在底层转换为通过该类来访问类变量。
对象并不持有类变量,类变量是由该类持有的,同一个类的所有对象访问类变量时,实际上访问的都是该类所持有的变量。
重要规则:对于static关键字而言,类成员不能访问实例成员。因为类成员是属于类的,类成员的作用域比市里成员的作用域更大,会出现类成员初始化完成,但实例成员没有初始化的情况,会导致更大的错误。
单例类
一个类始终只能创建一个实例,则称这个类为单例类。
总之在一些特殊场景下,要求不允许自由创建该类的对象,而只允许为该类创建一个对象。
final修饰符
final关键字可用于修饰类、变量和方法,final关键字便是修饰的类、方法和变量不可改变。
final修饰变量时,表示该变量一旦获得了初始值就不可被改变,final即可修饰成员便利,也可修饰局部变量、形参。
final修饰成员变量
成员变量是随类初始化或对象初始化而初始化的。
对于final修饰的成员变量而言,final修饰的成员变量必须有程序员显示地指定初始值。
final修饰的类变量、实例变量能指定初始值的地方如下。
类变量:必须在静态初始化块中指定初始值或声明该变量时指定初始值,而且只能在两个地方的其中之一指定。
实例变量:必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定。
final局部变量
系统不会对局部变量进行初始化,局部变量必须由程序员显示初始化。final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。
如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值;如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能再对该变量赋值。
final修饰基本类型变量和引用变量的区别
基本变量不能重新赋值,基本类型变量不能改变。
但对于引用类型而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。
可执行"宏替换"的final变量
不管是类变量,实例变量,还是局部变量,只要满足三个条件,这个final变量就不再是一个变量,而是相当于一个直接量。
1使用final修饰符修饰
2在定义该final变量时指定了初始值
3该初始值可以在编译时就被确定下来
注意:final修饰符的一个重要用途就是定义“宏变量”。当定义final变量时就为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那么这个final变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方直接替换成该变量的值。
final方法
final类
不可变类
缓存实例的不可变类
代码实现demo
抽象类
抽象方法是只有方法签名,没有方法实现的方法。
抽象方法和抽象类
抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义为抽象类,抽象类里可以没有抽象方法。
抽象方法和抽象类的规则如下。
1抽象方法和抽象类必须使用abstract修饰符来定义,抽象方法不能有方法体。
2抽象类不能被实例化,不论如何抽象类都不能实例化。
3抽象类可以包含成员变量、方法、构造器、初始化块、内部类5种成分,抽象类的构造器不能用于创建实例,主要用于被其子类调用。
4含有抽象方法的类只能被定义为抽象类
抽象类的作用
抽象类不能创建实例,只能被当成父类来被继承
抽象类体现了一种模板模式的设计,可作为多个子类的通用模板
Java8改进的接口
接口是特殊的抽象类,接口里不能包含普通方法,接口里所有方法都是抽象方法。
接口的概念
接口定义了一种规范,接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,只规定这批类里必须提供某些方法,提供这些方法的类就可满足实际需要。
接口是从多个相似类中抽象出来的规范,接口不提供任何实现。接口体现的是规范和实现分离的设计哲学。
Java8中接口的定义
接口的成员变量只能是静态常量,接口里的方法只能是抽象方法、类方法和默认方法。
不管是否使用public static final修饰符,接口里的成员变量总是使用这三个修饰符来修饰。接口里没有构造器和初始化块,接口里定义的成员变量只能在定义时指定默认值。
接口的继承
接口完全支持多继承,即一个接口可以有多个直接父接口。子接口扩展某个父接口,将会获得父接口里定义的所有抽象方法、常量。
使用接口
主要用途
1定义变量,也可用于进行强制类型转换
2调用接口中定义的常量
3被其他类实现
一个类可以实现一个或多个接口,实现用implements关键字,实现接口可以获得所实现接口定义的常量(成员变量)、方法(包括抽象方法和默认方法)。
一个类可以继承一个父类,同时实现多个接口,implements部分必须放在extends部分之后。
实现接口,必须完全实现这些接口里所定义的全部抽象方法,子类重写父类时,访问权限只能更大或者相等,所以实现类实现接口里的方法只能是public访问权限。
接口和抽象类
接口和抽象类很像,他们都具有如下特征:
1接口和抽象类都不能被实例化,他们都位于继承树的顶端,用于被其他类实现和继承。
2接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
区别:
接口作为与外部交互的窗口,体现了一种规范。程序使用接口时,接口是多模块间的耦合标准;多个应用程序调用接口时,接口时多个程序之间的通信标准。
抽象类是系统中多个子类的共同父类,他所体现的是一种模板设计
用法差别:
1接口只能包含抽象方法和默认方法,不能为普通方法提供实现方法;抽象类则完全可以包含普通方法
2接口里不能定义静态方法;抽闲类可以定义静态方法
3接口里只能定义静态常量,不能定义普通成员变量;抽象类可以定义普通成员变量也可以定义静态常量
4接口里不包含构造器;抽象类里可以包含构造器,抽象类的构造器不用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作
5接口里不包含初始化块;抽象类则完全可以包含初始化块
6一个类最多只能有一个直接父类,包括抽象类;但是一个类可以实现多个接口,通过实现多个接口可以弥补Java单继承的不足
面向接口编程
1简单工厂模式
2命令模式
内部类
一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,包含内部类的类也被称作外部类。
作用:
1内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
2内部类成员可以直接访问外部类的私有数据,但外部类不能访问内部类的实现细节。
3匿名内部类适合用于创建那些仅需要一次使用的类
除了定义在其他类里边还有区别:
1内部类比外部类可以多使用三个修饰符:private、protected、static--外部类不可以使用这三个修饰符
2非静态内部类不能拥有静态成员
非静态内部类
外部类对象访问非静态内部类成员是,可能非静态普通内部类对象根本不存在。而非静态内部类对象访问外部类成员时,外部类对象一定存在。
非静态内部类里不能有静态方法、静态成员变量、静态初始化块。
静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。static修饰的内部类被称为类内部类,也称为静态内部类。
简单的说,就是静态的只能访问静态的。
使用内部类
1在外部类内部使用内部类
2在外部类以外使用非静态内部类
Java8新增的Lambda表达式
Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口的实例。
Lambda表达式入门
Lambda表达式的主要作用就是代替匿名内部类的繁琐语法。由三部分组成
1形参列表。
2箭头(->)。
3代码块。
Lambda表达式与函数式接口
Lambda表达式的目标类型必须是"函数式接口"。函数式接口代表只包含一个抽象方法的接口。函数式接口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
方法引用与构造器引用
1引用类方法
2引用特定对象的实例方法
3应用某类对象的实例方法
4引用构造器