整型:int(4B),long,short,byte
长整型数值后缀L,十六进制数前缀0x,八进制数前缀0
Java没有unsigned类型
浮点型:float(4B),double
单精度数值后缀F
字符型:UTF-18编码
布尔型:true,false
变量名必须以字母开头,变量名长度没有限制,区分大小写,可以使用代表字母的任何Unicode字符,计算符号和空格除外,Java保留字除外
声明变量后,使用之前必须对变量进行显式初始化,否则会编译出错
final关键字修饰的变量只能被赋值一次,一旦被赋值便不能修改
const关键字是Java的保留字,但未被使用,声明常量需使用final
数值类型转换:短字长可向长字长转换,int、long型可向浮点型转换,字符型可向int型转换,不可逆;int、long到float,long到double可能有精度损失,但int到double无精度损失。
两个操作数:
1. 若其中一个是double,则另一个将被转换为double
2. 否则,若其中一个是float,则另一个将被转换为float
3. 否则,若其中一个是long,则另一个将被转换为long
4. 否则,两个操作数均被转换为int
强制类型转换:用于逆向的数值类型转换,如long型到int型,double型到int型
运算符优先级:高→低
1. 方法调用 左右
2. ! ~ ++ -- 一元加 一元减 强制类型转换 new 右左
3. * / % 左右
4. + - 左右
5. 移位 左右
6. < <= > >= instanceof 左右
7. == != 左右
8. & 左右
9. ^ 左右
10. | 左右
11. && 左右
12. || 左右
13. ?: 右左
14. 与赋值结合的运算符(如+= -=) 右左
由char值序列组成
String对象为不可变字符串;编译器将字符串存放在公共的存储池中,具有相同值的字符串变量指向相同的一个字符串存储位置,修改变量的值则是将变量指向存储池中的另一个字符串位置
StringBuilder对修改字符串的处理效率高于String
使用equals方法检测两个String是否相等,而不能使用==
标准输入流:Scanner in = new Scanner(System.in);
格式化输出:参见System.out.print**系列方法
块作用域:不允许在嵌套的块作用域中声明同名变量
switch语句:case标签必须是整数或枚举常量,case语句末尾必须有break
中断控制流程:goto关键字不推荐使用
break是跳出当前循环
continue是中断本次循环,跳到循环首部
大数值:BigInteger类和BigDecimal类,通过valueOf将普通数值转换为大数值,并通过类中提供的方法(而不是运算符)进行运算
声明:数组类型[] 数组变量名
初始化:数组类型[] 数组变量名 = new 数组类型[元素个数]; (元素个数可用变量形式)
数组类型[] 数组变量名 = { … };
数组一旦创建,大小就不能改变
for each循环:for (variable :collection) statement
其中collection可以是数组,也可以是实现了Iterable接口的类对象
匿名数组:new 数组类型[] { …}
数组拷贝:浅拷贝:将数组变量赋值给另一数组变量
深拷贝:System.arraycopy(from,fromIndex, to, toIndex, count);方法,在内存中创建一个新数组
数组排序:Arrays.sort方法,快速排序,升序排列
对象变量:Java的对象变量相当于C++的对象指针
构造体:1. 必须与类同名
2.每个类至少有一个构造体,默认为无参构造体
3.可以有0个或多个参数
4.没有返回值
5.可以是private,protected或public,默认为public
6.总是伴随new关键字一同被使用
显式参数:类方法括号中的参数
隐式参数:调用时出现在方法名前的类对象;方法定义中使用this关键字代表该隐式参数
基于类的访问权限:某个类的方法可以访问该类的任何一个实例的私有域
final实例域:将实例域定义为final,则在创建实例时必须初始化这样的域;对于可变对象的变量,定义为final只表示该变量不能再引用别的对象,但当前对象的内部数据域仍可以修改。
静态域:将域用static关键字修饰,表示该类的每一个实例中都有这个域的一份拷贝;静态域属于类,而不属于任何独立的实例,每次对其进行修改,则每个实例中的该域都会变成最新的值
常量:static + final
静态方法:将类方法用static修饰,表示该方法不能向该类的实例实施操作;静态方法没有隐式参数(this);静态方法只能访问该类中的静态域,不能访问实例域;静态方法通过类名直接调用,如Math.random();
Java使用值调用
方法参数有两个类型:
1. 基本数据类型
2. 对象引用
对于基本数据类型参数,方法并不能修改实参(因为值调用)
对于对象引用的参数,形参与实参指向的是同一个对象位置,所以方法能改变该对象内部的值,但不能使实参指向一个新的对象
重载:一个方法的签名包括方法名及其参数列表,不包括返回值和访问权限;重载就是具有相同方法名、不同参数列表的一组方法,由编译器根据参数列表挑选匹配的方法进行调用
默认域初始化:如果没有在构造体中对域进行显式赋值,那么默认地,数值域赋为0,布尔域赋为false,对象变量赋为null
默认构造体:如果在类定义中没有显式定义构造体,那么默认地,运行时系统会提供一个无参的空构造体
显式域初始化:类定义中,在域定义时直接将初始值赋给该域
调用另一个构造体:在一个构造体中第一句使用this(…);可以调用另一个重载的构造体
初始化块:类定义中直接包含代码块,用于给域赋上初始值
对象构造执行顺序:包含静态块、域初始化语句、初始化块、多个构造体
1. 所有数据域都被初始化为0、false或null
2. 按照类声明中出现的次序依次执行所有静态块
3. 按照类声明中出现的次序依次执行所有域初始化语句和初始化块
4. 如果构造体第一行调用了第二个构造体,先执行第二个构造体的主体
5. 执行本构造体的主体
对象析构:Java不支持对象析构,由垃圾回收器统一回收不再被需要的资源
子类与父类:class 子类名 extends 父类名
子类中不能直接访问父类的私有域和私有方法,但能通过super关键字调用父类的公有或保护域和方法;super不是对父类对象的引用,而是用于处理父类调用的特殊关键字,不能将super用于赋值;super同样能用于构造体第一行,表示先执行父类的构造体
覆盖:在子类中重新定义父类中已经存在的一个方法
多态:一个父类类型的变量可以引用父类的实例,也可以引用子类的实例;里氏代换原则
动态绑定:调用对象方法的执行过程:
1. 编译器查看对象变量声明的类型和方法名
2. 编译器查看调用方法时提供的参数列表
3. 若方法是private、static、final或者构造体,则编译器可以准确找到应该调用的方法,称之为“静态绑定”,在编译时已经决定好;若调用的方法还依赖于隐式参数的实际类型,称之为“动态绑定”,在运行时才调用实际类型中的对应方法
4. 运行时,若采用动态绑定调用的方法,虚拟机必须调用与对象变量引用的实际类型最合适的类中的相应方法
因此,在父类变量引用子类实例的情况下,编译时获得的是父类的方法表,但运行时动态绑定子类中的对应签名的方法
也因此,在覆盖时,子类方法的访问权限不能低于父类
final类和final方法:阻止继承;被final关键字修饰的类不可被继承;被final修饰的类方法不能被覆盖
强制类型转换:将父类的引用赋给子类变量时,必须进行强制类型转换,否则运行时会报错
1. 只能在继承层次内进行类型转换
2. 将父类转换成子类之前,应该使用instanceof关键字进行检查,以确保该该父类确实派生了该子类,避免ClassCastException
abstract关键字修饰的方法不需要实现,称为“抽象方法”;包含一个或多个抽象方法的类本身也可以被abstract修饰,是为“抽象类”
抽象类中可以包含具体数据和具体方法
即使不含抽象方法,仍然可以将类用abstract修饰为抽象类
抽象类的子类中若仍有未被实现的抽象方法,则该子类仍是抽象类;若所有抽象方法均被定义了,则该子类不再是抽象的
抽象类不能实例化
可以定义抽象类的对象变量,但只能用于引用非抽象子类的实例
Object是Java中所有类的最终祖先
Java中,所有的对象类型,以及数组类型(包括基本数据类型的数组和对象数组)都是扩展自Object类
equals方法:Object类中,equals方法用于判断两个对象是否具有相同的引用
Java语言规范要求重写equals方法具备如下特性:
1. 自反性:x.equals(x) = true
2. 对称性:若x.equals(y) = true,则y.equals(x) = true
3. 传递性:若x.equals(y) = true且y.equals(z) = true,则x.equals(z) = true
4. 一致性:若x, y引用的对象没发生变化,则反复调用x.equals(y)的结果不变
5. 对任意非空引用x,x.equals(null) = false
编写完美equals方法的建议:
1. 显式形参命名为otherObject,稍后需要将它转换成一个叫other的变量
2. 检测this与otherObject是否引用同一个对象
3. 检测otherObject是否为空
4. 检测对象类型是否相容:若equals的语义在每个子类中有所改变,使用getClass()方法检测;若语义保持不变,则使用instanceof关键字检测
5. 将otherObject强制转换为相应的对象类型变量
6. 逐一比对需要比较的域,使用==比较基本数据类型,使用equals比较对象引用
7. 如果在子类中重写equals,则必须在其中包含super.equals(otherObject);
hasCode方法:equals相等的对象必须返回相等的散列码
Class类:保存某个类实例所属的类足迹
getName()方法:返回类名
静态方法forName(String):返回字符串对应的类的Class实例
任意的Java类型T,T.class表示它所匹配的Class类实例
newInstance()方法:用于创建该Class对象对应的类的一个实例,使用默认的无参构造体,返回的实例为Object类型;另外,Constructor类中的newInstance(Object[] args)方法可以采用有参数的构造体实例化一个目标实例,args就是该构造体的参数列表
使用反射分析对象:java.lang.reflect包中的类Field、Method和Constructor分别描述类的域、方法和构造体;分析对象的方式:
1. 得到对应的Class对象
2. Class对象中的getFields方法返回类支持的public域,getDeclaredFields方法返回类声明中的全部域
3. Class对象中的getMethods方法返回类支持的public方法,getDeclaredMethods方法返回类声明中的全部方法
4. Class对象中的getConstructors方法返回类支持的公有构造体,getDeclaredConstructors方法返回类声明中的全部构造体
5. 上述方法中却不能获得父类中的成员
6. Field、Method和Constructor可以通过getModifiers方法获得Modifier类对象,该对象描述了这些域或方法中的public、static、final等关键字的使用情况,并提供了对应的操作
7. 反射机制的默认行为受Java的访问控制限制,但可以通过设置Field、Method和Constructor的setAccessible(boolean)方法为true,以覆盖访问控制,从而通过get和set方法访问和修改域等的值
使用反射扩展数组:java.lang.reflect包中的Array类的静态方法Object newInstance(Class componentType, int length)允许动态创建数组,生成后需要强制类型转化成数组
方法指针:Method类中的Object invoke(Object obj, Object … args)允许调用封装在当前Method实例中的具体方法,其中obj表示该方法的隐式参数,args表示显式形参;对于静态方法,obj置为null;返回的结果需要强制类型转换,如果是基本数据类型,返回的是它对应的包装器格式;可以通过Class类的Method getMethod(String methodName, Class … paramTypes)获取需要某个的Method对象