1 基本信息
-
2个保留字:goto、const
-
3个直接量:true、false、null
-
标识符:字母、中文、符号下划线_或者以符号$开头,符号仅可能有下划线和$
-
注释:单行注释如// ...,块或多行注释如/ ... /,文档注释如/* ... /,用于提取信息,如作者@author,参数@param;生成文档注释的命令:javadox xxx.java
2 基本数据类型与包装类
-
包装类是对基本数据类型的包装,使其具有面向对象的特征(封装,继承,多态),提供属性和操作方法,默认值为null
基本数据类型/包装类:8种 | 表示范围 | 字节(1字节 = 8位) | |
---|---|---|---|
byte / Byte 字节 | -128 - 127 | 1 | 1 byte = 8 bit 1 KB = 1024 byte 1 MB = 1024 KB 1 GB = 1024 MB |
short / Short 短整 | -2^15 - 2^15-1 | 2 | |
int /Integer 整数的默认类型 | -2^31 - 2^31-1 | 4 | 1、与2/8/16进制的转换:Integer. toBinaryString(value) /toOctalString(value) /toHexString(value) 2、转为任意进制:Integer.toString(value, n) |
long / Long 长整 | 8 | 默认值0L BigInteger:操作大整数工具类,包含了常用的数学方法 | |
float / Float 单精度浮点类型 | 4 | 默认值0.0f/F | |
double / Double 双精度浮点类型 | 8 | 浮点数默认类型 浮点数采用科学计数法,丢失数据,即1 * 0.1 != 0.1;作比较时转为>=或<=,如float EP = 0.00000001F;if (testNumber >= -EP) && (testNumber <= EP);则认为它们等值 BigDecimal:用于金融方面确保精度的工具类 | |
boolean / Boolean 布尔 | 1 | 默认值false 参与字符串运算时被提升为字符串 | |
char / Character 字符 | 与编码相关;Unicode编码占2字节 | 默认值'\0' 可赋值为汉字 不能使用双引号 特殊字符如换行'\n',制表'\t' 可直接使用Unicode值表示,如'\uXXX';也可以表示0-65535内的整数 |
-
自动类型转换/提升:
-
转换条件:
-
表示范围低的 -> 表示范围高的,会发生自动类型转换
-
类型要兼容,数值类型(整数和浮点数)兼容
-
-
声明long,float,double类型数据时,当值在int范围内(值的取值范围限制且没有小数)时可省略后缀,否则必加后缀;如long l = 10L;等同于long l = 10;
-
表达式结果的类型,为表达式中表示范围最大的类型:如double类型与int类型运算,得到的值自动提升为double型
-
表达式自动类型提升:对byte/char/short参与的表达式运算,自动提升结果为int型,如byte + short = int;注意返回类型不兼容则报错
int a = 5; int b = 2; double e = 5; System.out.println(a / b); // 最大类型为int,结果值为int,即输出2 System.out.println(e / b); // 最大类型为double,结果为double,即输出2.5 double c = a / b; System.out.println(c); // 最大类型为int,结果为int,即a / b输出2,将2赋值为double,所以输出2.0;int型值赋值给double型,即自动类型转换 double d = a * 1.0 / b; System.out.println(d); // 最大类型为double(通过 *1.0操作实现),结果为double,即a * 1.0 / b输出2.5,将其赋值给d,输出2.5 // ========================================================================= byte a = 1; byte b = 2; byte c = 1 + 2; // 正确,此时的1和2就是byte范围内的1和2 byte d = a + b; // 错误,右边运算结果被提升为int类型,不能返回给byte类型的d a += 1; // 正确,+= 类似于 =,是赋值运算/一次运算 a = a + 1; // 错误,右边为算数运算,然后赋值,为二次运算,结果自动提升为int类型,不能赋值给byte类型的a
-
-
强制类型转换:将一种数据类型强行转为另一种数据类型;不一定必须是表示范围高的转为表示范围低的才用,如自动类型转换也可以显式写出转换类型来让它强制转换;因为会丢失数据精度,慎用
int i = 233; byte b = (byte)i; // 输出b为-23;byte范围为8位,丢失int范围32位的前24位,最高位为符号位,233的二进制右边8位的最高位为1,表示负数,负数以补码形式存储,后7位-1后转为反码在转为源码为-23
-
自增,自减运算符:
/** * 重点: * i++/i--是在自身上变化,即增减操作在局部变量表中进行,其他操作都在操作数栈中完成 * i++即自增表示变量自己增加,不执行入栈操作;同理自减;而++i需要先执行入栈后在栈中完成++;最后将栈中值取出赋给局部变量 * =赋值最后执行;=右边的值从左到右依次入栈,然后根据运算符执行优先级,临时结果也存入栈中 */ private static void doAdd() { int i = 1; // 局部变量i=1;执行入栈i的值,栈中存储1;可以理解为变量i指向栈中的值1 i = i++; // 执行i++,局部变量i=2;然后执行赋值,将栈中的1赋给i,最终i=1;可以理解为变量i指向自身,于是将自身指向的栈中的值赋予变量i(赋值:将变量指向的栈中的值赋予变量) // i++; 注意区别于这一行代码:局部变量i=1,执行入栈i,栈中存储1,然后执行i++,局部变量i=2,没有赋值,最终i=2 int j = i++; // 局部变量j默认=0,i=1,执行入栈i的值,栈中存储1;然后计算i++,局部变量i=2;然后执行赋值,将栈中的1赋给j,j=1 // 注意此时的局部变量i没有被栈中i赋值,所以最终i=2 int k = i + ++i * i++; // 局部变量k=0,i=2;依次入栈执行,从底到顶为i=2,执行++i即i=3,执行i++即i=3,最终栈内为2,9;然后局部变量i执行++即i=4 // 然后将栈中元素2+9赋值给k,最终k=11;i没有被赋值,i=4 System.out.println(i +"," + j +"," + k); }
-
特殊的,char类型字符与int类型的转换:
char c = '8'; System.out.println(c); // 输出 8 int i = c; // 自动类型转换 System.out.println(i); // 输出 c的ASCII码,即56 System.out.println(c - '0'); // 输出int类型的8,即通过操作转为了int型(用instanceof Integer判断,注意instanceof不能用于基本数据类型的判断) // 输出打印26个字母:'a'+1得到'b',最终stringBuffer为26个字母字符串 for (int i = 0; i < 26; i++) { char c = (char)('a' + i); stringBuffer.append(c); }
-
装箱:
Integer i = new Integer(1); // 传入基本数据类型到构造器实现装箱 = new Integer("1"); // 传入可转为数值类型的字符串到重载的构造器实现装箱,可能引发NumberFormatException = Integer.valueOf(1); // 传入基本数据类型到静态方法 = Integer.valueOf("1"); // 同理,重载 = 1; // JDK1.5后的进行自动装箱,编译器实际执行=Integer.valueOf(1);为了提高效率,Java设计针对-128 -127之间的数据进行缓存到一个数组中,类似常量池,每次使用时从此处获取;而超出部分虽然也写作自动装箱,但底层实现是转为new对象;所以比较的时候需要判断底层实现的方式: Integer a = (-128 - 127); Integer b = (-128 - 127); // a == b 返回true,它们都是缓存中的那个数 Integer c = new Integer(-128 - 127); // a != c,b != c,c指向新new的一个对象 Integer d = 200; Integer e = 200; // d != e,它们不在缓存范围内,因此转为指向各自new出的对象 List<Integer> list = new ArrayList<>(); list.add(1); // 集合存储基本数据类型的数据时,存储的是对应的包装类;做add()时发生自动装箱 list.get(0); // 返回Integer,也可以用int来接收 // 包装类还提供了系列工具方法,如数据比较compare(基本数据类型1, 基本数据类型2),返回1,0或者-1 i += 1; // 包装类完成一次运算,经过了先拆箱,完成int的+运算后,再装箱的过程
-
拆箱:
int i = a; // 先定义Integer a;自动拆箱,编译器实际执行了下面的方法 = a.intValue(); // 其他类型同理,如floatValue()
-
与字符串的转换:
-
基本数据类型/包装类转为字符串:
-
变量/对象.toString()
-
使用String的静态方法String.valueOf(变量)
-
直接使用连接符 + 号
-
-
字符串转为基本数据类型/包装类,注意字符串须满足是可转为数值的:
-
parseXXX(): 包装类的静态方法解析字符串,如Integer.parseInt(string)
-
使用构造器装箱
-
-
3 进制
-
二进制最高位表示符号位,JDK1.7后以0b或0B开头;八进制以0开头;十六进制以0x或0X开头,10-15用不区分大小写的a-f表示
-
二进制与十进制的转换:
-
二进制数与权的对应关系:个位对应2的0次幂,十位对应2的1次幂,百位对应2的2次幂,。。。小数点后一位对应2的-1次幂,依次类推;2的X次幂即为权
-
加权系数展开式:以每一位上的数(0或1) * 权,然后按权相加求和
-
二进制 1011.01 = 1X2^3 + 0X2^2 + 1X2^1 + 1X2^0 + 0X2^-1 + 1X2^-2 = 8+0+2+1+0+0.25 = 11.25 十进制
-
十进制 整数部分用商连续除以2并记录余数,逆序排列,如89的余数1001101,直到最后1除以2,于余1;小数部分用小数连续乘以2并记录整数,顺序排列,如0.625,余数分别为0.101
-
-
4 字符集与编解码
-
编码encode:字符转字节;解码decode:字节转字符;通过码表对应
-
ASCII字符集:7位表示,1位存储(提高读写效率):
-
数字0 - 9:char >= 48 && char <= 57,或者char == '0/1/2/3...'
-
A - Z:char >= 65 && char <= 90,或者char == 'A/B/C...'
-
a - z:char >=97 && char <= 122,或者char == ‘a/b/c...
-
-
ISO-8859-1:单字节编码,0-255,仅用于英文,即一个字母字符为一个字节
-
GB2312(简体) -> GBK(扩展到繁体):双字节编码,汉字国标码,英文兼容ISO-8859-1;即一个中文字符为两个字节,英文字符一个字节
-
Unicode:一般为定长双字节编码,即所有字符都是两个字节,统一,但不方便传输和存储,16进制方式;Java常用
-
UTF:不定长编码,一般英文1字节,汉字3字节
-
UTF-8:1-6个字节变长存储
-
UTF-32:4字节定长存储
-
UTF-16:介于两者之间,2或者4字节可变长,可定长存储
-
-
解决乱码:byte[] bytes = string.getBytes()获取字节数组;该字节数组默认字符集与项目一致;可另设置字符集,如bytes = string.getBytes("GBK");反之解码,通过String类的重载构造器指定,如string = new String(bytes, 0, bytes.length, "utf8");指定的长度不够或指定的编解码不统一,都可能出现乱码
-
详细讲解:关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换 - 海米傻傻 - 博客园
5 运算符
-
算数运算:+ 、- 、* 、 / 、%
-
符号 + 还可用作字符串连接
-
符号 - 还可用作求负运算
-
符号 / 用于整数,结果求模,即舍去余数,结果为整数;用于浮点数,除数可以为0或0.0,结果为浮点数
-
符号 % 用于整数,结果求余,即只要余数,结果为整数;用于浮点数???????????
-
-
比较运算:==、!=、>、<、>=、<=;true == false返回false
-
逻辑运算:!非、&&与、||或、^异或
-
!:取反
-
&&:同为true,则结果为true,否则为false
-
||:同为false,则结果为false,否则为true
-
短路特性:短路后,后面的表达式不再执行,直接舍弃
-
^:同则false,不同则true
-
优先级依次降低,如false || true && !false,优先!false为true,再true&&true为true,最后false||true为true
-
-
位运算:针对二进制整数(包含提升为int的byte,char,short);所移位数超过范围时,先取余,如int为4字节共32位,如果移动33位,等于移动1位
-
~:按为取反
-
&:11得1,否则得0
-
|:00得0,否则得1
-
^:同得0,不同得1(同逻辑运算,1看做true,0看做false)
-
<<:移除左边高位,右边以0填充,等同于 *2的移动次幂
-
符号>>:左边以原数的符号位填充,等同于 /2的移动次幂
-
无符号>>>:
-
6 条件语句-流程控制
-
switch...case:
-
switch的条件支持:byte,char,short,int,enum枚举(JDK1.5),String非缓冲字符串(JDK1.7);enum最终会被转换为int序号;String通过hashcode计算,也得出一个int范围内数值,以此适应switch
-
条件与任意case都不匹配时,执行default
-
default语句可在任意位置;当位于首行时,无论条件与case是否匹配,程序都会执行default直到break出现
-
条件不支持的类型:
-
long类型:switch编译时用到两个操作指令,tablesswitch和lookupswitch,这两个指令运行在int指令之下,所以超过int范围的数不被支持
-
浮点型:浮点型精度不确定
-
-
-
for:
-
初始变量可以多个,但一定同类型
-
break:结束循环;当需要直接结束外层循环时,循环外声明一个特殊标识符,如end: 来标识某层循环,通过break end: 来结束该层循环
-
continue:结束这一轮循环,即后面的代码不再执行,开始执行下一轮循环;可配合标志符
-
foreach:增强for循环, 自动遍历数组或集合的元素;for (type name: Array/Collection) ,底层为简化了的迭代器 ;无需长度和索引,且自动迭代,一次后结束循环;不适用于修改元素值
-