Java 语言相关基础知识。  
命名规范
- 驼式命名法
类或接口,首字母大写;方法或变量,首字母小写。 - 常量
大写字母和下划线组成,首字母不能是下划线。 
原码,补码,反码,移码
- 正数
原码,补码,反码都是相同的。 - 负数
 
反码是其绝对值按位取反,补码是反码加 1
举例 1 :[-0]原 = 1 000000,[-0]反 = 1 1111111,[-0]补 = 0 000000
举例 2 :[-1]原 = 1 000001,[-1]反 = 1 1111110,[-1]补 = 1 1111111  
- 移码
不管正负数,只要将其补码的符号位取反即可。 - 浮点数
N = 2 ^E * F,其中E为阶码,F为尾数;阶码使用移码表示,尾数使用原码表示;浮点数运算前会先对阶。 - 补码快速计算
符号位不变其他的从低位开始,直到遇见第一个 1 之前,什么都不变。遇见第一个 1 后保留这个 1 ,以后按位取反。例:[-7]原 = 1 0000111 ,[-7]补= 1 1111001 
逻辑运算
异或
任何数连续两次与另外一个数异或,结果是本身。A ^ B ^ B = A ^ (B ^ B) = A ^ 0 = A  
移位运算符
Java中负数都是按照反码来表示的,移位运算基于值的反码。
规则
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对 int 型移动 33 位,实际上只移动了 33%32=1 位。  
<<左移运算符
高位移出舍弃,右边低位补零。如:
[2] = 0 0000010,左移 2 位为 [8] = 0 0001000;
[-2] = 1 1111110,左移 2 位为 [-8] = 1 1111000;
[-127] = 1 0000001,左移 1 位为 [2] = 0 0000010;也就是负数左移,并不保留符号位,直接舍弃。
>>右移运算符
符号位不变,左边高位补上符号位。如:
[4] = 0 0000100,右移 1 位为 [2] = 0 0000010;
[-4] = 1 1111100,右移 1 位为 [-2] = 1 1111110;>>>无符号右移运算符
忽略了符号位扩展,最高位补零。无符号右移规则和右移运算是一样的,只是填充时不管左边的数字是正是负都用 0 来填充。
[-8] = 1 1111000,右移 2 位为 [-2] = 0 0111110;
意义: Java 中数字二进制比特的最高位为符号位,即 int, long 只能使用 31/63 位来表示取值范围,无符号右移可以将最高位不做符号位来考虑,即变相扩大了数字的取值范围,可以使用 32/64 来表示 int, long,在图像处理,加解密等用的比较多。  
作用
- 乘除
在结果没有溢出的前提下:num << n:表示num乘以2 ^ n;如左移 3 位,表示乘以 8num >> n:表示num除以2 ^ n;如右移 2 位,表示除以 4 - 截取数字高/低位
比如:1 << 3表示,低三位都是 0 ,在按位操作时,截取掉低三位 
负数的除法和余数
- 除法
表达式a/b的商会向 0 取整。 - 余数
a % b的余数的定义是(a/b)*b + a % b恒等于a。 - 示例
例如:-14/3 和 14/-3 的商都是 -4;但 -14 % 3 是 -2,而14 % -3 是 2。 
数据类型
数据类型分类

基本数据类型取值范围

浮点类型特殊数值:+0, -0, NaN(Not a Number), +infinities, -infinities,其中:  
1  | // Float.java  | 
包装类
Java 为每种基本数据类型分别设计了对应的类,称之为包装类 Wrapper Classes。
8 种基本数据类型及对应的包装类
| 基本类型 | 包装类 | 
|---|---|
| byte | Byte | 
| short | Short | 
| int | Integer | 
| long | Long | 
| char | Character | 
| float | Float | 
| double | Double | 
| boolean | Boolean | 
自动装箱和拆箱
- 自动装箱 
Auto Boxing Conversation
基本类型自动转换为对应的封装类型(对象)即为自动装箱。 - 自动拆箱 
Unboxing Conversation
封装类型自动转换为基本类型为拆箱。 
转换过程
- 装箱:
*.valueOf(*) - 拆箱:
*.intValue() 
源码如下,展示了常见的自动装箱和拆箱的用法:
1  | // 自动装箱  | 
经过反编译后,可以明确看到装箱和拆箱的动作:
1  | Integer localInteger = Integer.valueOf(1); // 装箱  | 
自动装箱后的比较
因为是对象比较,所以建议直接使用
equal而不是==。
== 比较的是对象的首地址。但是 Java 做了部分优化,在如下范围内使用的是相同的对象(封装类型的缓存),范围外则在装箱的过程中重新生成一个对象。  
char[\u0000, \u007f]:即ASCII码表中的 128 个字符。byte/short/int/long[-128, 128):在-128 <= x < 128范围内,共用相同的对象(缓存),即byte能够表达的范围。float/double
没有缓存,直接重新生成一个新对象。
1  | // char  | 
String 的自动拆装箱
基本概念:Java 中的 "abc" 对应的实际是常量,存储在常量池中。  
1  | // 对应的都是常量池中 "abc" 的地址  | 
注意事项
- 内存空间
自动装箱涉及到重新生成对象,所以频繁大量的使用会创建很多无用的对象,增加GC压力,拉低程序的性能。 - 拆箱空指针异常
如果封装类型并没有初始化,在拆箱时会报空指针异常,因为编译过程无法检测到,只能在运行时出现,需要特别注意。 
BigInteger/BigDecimal 类型
BigInteger/BigDecimal 用于大数操作和高精度计算:BigInteger 操作大整数,BigDecimal 可以指定小数保留位数。它们类似 String,但是它的初始化方式却没有 String 那么方便可以直接赋值,而是跟其他自定义的类一样,要调用它的构造器进行初始化。这个类的取值范围原则上是没有上限的,取决于你的计算机的内存。  
1  | public static void main(String[] args){  | 
解析:a 和 b 的值刚好可以使用 long 表示,但是相加的结果超出了 long 的范围,而使用 float/double 计算出来精度不够,会在个位数上产生误差。使用 BigInteger 正好解决这个问题。  
数据类型和存储
存储区:栈和堆
- 栈内存
用于存放基本类型的变量和引用变量。当超过变量的作用域后,Java会自动释放掉为该变量分配的栈内存空间。 - 堆内存
用于存放由new创建的对象和数组。堆中分配的内存由Java虚拟机自动垃圾回收器来管理。数组和对象在没有引用变量指向它的时候才变成垃圾,不能再被使用,但是仍然占着内存。在随后的一个不确定的时间被垃圾回收器释放掉,这个也是Java比较占内存的主要原因。 
数据类型
- 基本数据类型
基本数据类型只涉及一个存储区:是存在栈内存中的,保存的是数据值本身。 - 引用数据类型
涉及到两块存储区:对象本身是存储在堆内存中;引用变量是存储在栈内存中,并存放指向该对象堆内存的首地址。 
参数传递
形参传递分为:值传递和引用传递。
值传递
Java 的基本数据类型都属于值传递,即将栈内存中的数据传递给形参,所以值传递过程中,形参的修改不会影响到实参。String 比较特殊,根据 String 的源码可以认为 String 本身是一个常量,所有的修改都是拷贝生成一个新字符串,所以也属于值传递。  
引用传递
Java 中所有的对象都是引用传递(除了 String),引用传递实际室传递了引用变量,而该变量指向了对象的堆内存,所以改变引用变量指向对象的值时,实参会跟着改变(实参指向了同一个堆内存)。但是如果重新给引用变量赋值,即重新 new 一个对象或者指向另外一个对象,这时改变引用变量指向对象的值时,实参并不会受到影响(实参指向的堆内存并没有被改变)。  
示例说明:
1  | private MyDataParcelable updateBookOut(MyDataParcelable myDataParcelable){  | 
数组
Java 中二维数组有一下几个约定:  
- 第一维为行数,第二维为列数
即对于int[][] a中,a.length为行数,a[0].length为列数。 - 数组中默认会将数值型初始化为 0, 布尔型初始化为 
false 
switch
switch 能否作用在 byte 上?能否作用在 long 上,能否作用在 String 上?switch 的表达式数据类型是:整型、字符型和枚举型;可以作用在 byte 上,不可作用域 long 上,Java 7 以后可作用于 String 上。  
Log 打印
System 打印
1  | System.out.println(""); // 常规换行打印  | 
out 和 err 打印时不在同一个线程执行,所以混合使用它们打印时,时间上并不是顺序打印(看起来是异步在执行)。  
堆栈打印
打印当前堆栈调用信息:new Exception("This is a log.").printStackTrace(System.out);printStackTrace 默认使用的是 System.err 来打印的,如果其他 Log 都是 System.out 输出的,会导致信息看起来像是异步执行。所以要求堆栈也使用 out 打印,即 printStackTrace(System.out) 。  
其他
try-catch-finally
Java 7 中的新特性,带资源的 try 可以自动 close 实现了 Closeable 的对象。
