一、八种基本类型
1.取值范围
2.字面值前缀
0b:二进制
0x:十六进制
0:八进制
u char 类型十六进制
3.运算规则结果类型与运算中的最大类型一致
byte、short、char三种比int小的整数,计算时会自动转成int(自增自减不会转换;有long型时,转long型)
Integer.MAX_VALUE+1得负数的最小值
浮点数运算不准确
计算机所有数据的表现形式都是二进制,浮点数精度不准确的原因是十进制转换成二进制导致的。下面回顾一下十进制与二进制的相互转换过程。10010 = 0 * 2^0 + 1 * 2^1 + 0 * 2^2 + 0 * 2^3 + 1 * 2^4 = 18
// 十进制转二进制
18 / 2 = 9 …….0
9 /2 = 4 ……….1
4 / 2 = 2……… 0
2 / 2 = 1 ………0
1 / 2 = 0……… 1
结果
10010
上面是整数之间的转换过程,下面看一下小数之间是如何转换的。10.01 = 1 * 2^-2 + 0 * 2^-1 + 0 * 2^0 + 1 * 2^1 = 2.25
//十进制转二进制
//整数部分
2 / 2 = 1…….0
1 / 2 = 0…… 1
// 小数部分
0.25 * 2 = 0.5…..0
0.5 * 2 = 1 ……..1
结果
10.01
为什么有的浮点数会有精度不准确的问题,以2.1为例,看一下十进制转成二进制是什么样子的。2 / 2 = 1……0
1 / 2 = 0……1
// 小数部分
0.1 * 2 = 0.2……0
0.2 * 2 = 0.4……0
0.4 * 2 = 0.8……0
0.8 * 2 = 1.6……1
0.6 * 2 = 1.2……1
0.2 * 2 = 0.4……0
……..
2.1转成二进制会陷入无限循环中,而计算机在存储小数时是有长度限制的,会截取部分小数进行存储,从而导致计算机存储的数值只能是个大概的值,而不是精确的值。计算机根本无法使用二进制来精确的表示2.1这个小数,计算肯定也有问题。
精度丢失的解决办法使用BigDecimal计算,传入的参数一定要转换成字符串,不然还是有坑。
4.运算符
&&:逻辑与(短路与),左边是假,右边忽略不执行
&:不管左边什么结果都要执行右边
||:逻辑或(短路或),左边是真,右边忽略不执行
二、基本类型的包装类
1.IntegerInteger类中存在256个缓存对象,从-127~128;如果访问这个范围内的值,会访问缓存对象,超出范围,会新建对象
三、流程控制
1.switch支持的类型有byte、short、int、char及这四种类型对应的包装类,以及String和枚举类型。枚举类有一个ordinal方法,该方法实际上是一个intl类型的数值,String类型有一个hashCode算法,结果也是int类型。所以总的来说,可以认为switch中只支持int。
switch的值不能是null,case子句中也不能是null
case子句的值不能重复,会产生编译错误
如果一个case条件成立,之后会无条件的执行后面所有的case和default直到结束,或者遇到break跳出循环;如果所有条件都不成立,则执行default
四、数组
1.Arrays数组工具类
其中封装了一些对数组的排序、查找、复制等操作
五、变量
1.局部变量定义在方法或局部代码块中,必须初始化,第一次赋值时分配内存空间
2.成员变量定义在类中,自动初始化默认值
3.为什么局部变量需要初始化,而成员变量不需要?
成员变量的赋值和取值的先后顺序具有不确定性,这是在运行时发生的,编译器确定不了,所以交给JVM来进行初始化;而局部变量的访问顺序是可以确定的,为了防止不可预期的情况发生,做的一种约束。
六、Object类
1.概念是所有类的父类
2.方法toString():获得一个对象的字符串表示,默认是“类名@地址”,可在子类中重写该方法
equals():判断内存地址是否相等
七、String类
1.概念是封装char[]数组的对象
第一次使用一个字符串常量时,会在字符串常量池中新分配内存,之后使用相同的字符串时,直接访问常量池中存在的对象,不会重复创建
2.equal和====比较的是内存地址
String重写了Object的equal方法,比较的是值
3.StringBuilder线程不安全,效率高
4.StringBuffer线程安全
八、抽象类可以有构造方法
可以有具体方法
包含抽象方法的类一定是抽象类,抽象方法必须由abstract修饰,必须由子类实现
不能用new来创建实例
可以继承抽象类,也可以继承普通类
九、final内存地址不可变,可以修饰常量、类、方法
final常量:值不可变。不过对于引用类型来说,保存的是地址,所以内容可变
final方法:不能被子类覆盖。private方法不能被子类覆盖,因此private默认是final类型的
final类:不能被继承,没有子类
十、static共享的数据
静态成员属于类,而不属于实例
静态方法不能直接调用非静态方法,只能由实例调用
静态块,只会在类被加载时,执行一次
静态变量保存在方法区中,被所有实例共享
十一、面向对象
1.基本概念
1)类:类中定义对象的成员变量、成员方法。类第一次使用时会加载到方法区。
2)对象:从类中创建的具体实例。新建实例时,在堆内存中会分配内存空间给这个实例。
3)引用变量:在栈中保存一个实例的内存地址(堆中实例的地址),引用变量保存在栈。null不保存任何实例的内存地址。
4)构造方法:新建实例对象时,立即执行的一个特殊方法,可重载
5)this当一个对象创建后,JVM会给对象分配一个引用自身的指针,这个指针就是this,表示当前对象的引用
this只能在非静态的方法中使用
用于区分同名变量
只能在构造方法中通过this来调用其他构造方法,普通方法中不能使用;不能通过this递归调用构造方法;调用其他构造方法时,必须放在第一行
因为super方法调用父类的构造函数也必须放在第一行,所以super和this不能同时出现在构造方法中
this访问类的成员变量和成员函数时不受访问权限的控制,包括private的变量和方法
在继承关系下,父类中的this关键字表示如下:
this(paras…)访问其他构造方法:访问的始终是父类的构造方法;
this.XXX访问类中的成员变量:访问的始终是父类中的成员变量;
this.yyy(paras…)访问类中的成员方法:如果子类重写了该方法,则访问的是子类的方法;否则访问的是父类的方法;
6)super和this的异同:super是子类中访问父类成员的一个桥梁,而this是一个对象的引用
当子类覆盖了父类的成员变量,或重写了父类的成员方法时,通过super还能够访问到
都不能在静态方法中使用
7)继承:只能继承一个父类;构造方法和私有成员不能被继承
8)方法重写:子类重写父类的方法,方法名、参数的个数和类型、返回值类型必须都相同
9)多态一个对象具有多种形态的表现,多态的前提是必须有继承
向上转型:子类的实例转换成父类型。只能调用父类定义的通用成员,子类特有成员被隐藏
向下转型:已经转换成父类型的子类实例
2.对象加载的过程
1)加载类加载父类,为父类静态变量分配内存
加载子类,为子类静态变量分配内存
执行父类静态变量的赋值运算和静态初始化块
执行子类静态变量的赋值运算和静态初始化块
2)新建实例新建父类实例,为父类实例变量分配内存
新建子类实例,为子类实例变量分配内存
执行父类的实例变量赋值运算和构造方法
执行子类的实例变量赋值运算和构造方法