一、数据类型
Java语言是强类型语言(要求变量要先定义才能使用),对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。
分类:
1.基本数据类型
整型:byte、short、int、long
浮点型:float、double
字符型:char
布尔型:boolean
2.引用类型
类、接口、数组
注意:String不是基本数据类型,是一个类,是引用数据类型
char c='\u0000';
\是转义字符,\u表示转义成16进制数
注意事项:
1.浮点型可能只是一个近似值,并非精确的值。
2.数据范围与字节数不一定相关,如float数据范围比long类型更广。
4.浮点数默认类型为double,如果要使用float类型,需要加后缀F;整型为int,long类型要加后缀L。
5.对于整型
二进制要以0b开头,如0b100110
八进制数要以0开头,如0123
十六进制数要以0x开头,如0x132
6、对于char类型,英文字母和汉字均占2个字节;
对于String来说,英文字母占一个字节,汉字占两个字节,但长度汉字与字母都是占一位,所以可以用字节数与与字符串长度来判断Str中是否有汉字;
【数字可以用下划线分割】
如:int x=10_0000_0000;
对于基本数据类型变量,有默认值(如int为0),基本类型的赋值是按值传递;
对于引用类型变量,默认值为null,null仅仅表示这个引用没有指向任何对象,引用类型的赋值是按引用传递;
运算及类型转换:
1.隐式类型转换
从低级向高级转换,系统自动执行。
注意:在有不同数据类型参与运算时,结果会转化为数据类型大的那种。
2.显示类型转换(强制转换)
范围小的数据转换为范围大的数据类型,代码需要格式处理,不能自动完成。
如:
long x=(long)100.5F;(float强制转化为long,输出x=100)
char y='a';
int y=(int)y;(char强制转换为int,输出y=97)
注意:
1.强制类型转换可能会精度丢失,数据溢出。
2.char类型中每个字符对应一个数字(Unicode表),因此可以转化为int等整型数据;
其中特别要记住A对应65,a对应97;
ASCII表:AmericanStandardCodeforInformationInterchange,美国信息交换标准代码。
Unicode:万国码《也是数字和符号的对照关系,开头127部分和ASCII完全一样,但是从128开始包含有更多字符。
Java语言采用Unicode编码标准,它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。
浮点数特点:有限,离散,有误差,近似值;
所以最好不要用浮点数进行比较;
现示应用中一般用BigDecimal类代替浮点数
char c=97;
int i=97;
char c2=i;//报错
char c3=(char)i;//正确
int常量值可以直接赋值给char类型;
但int类型的变量不能直接赋值给char类型,需要强转;
float f=3.4;是否正确?
不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;。
short s1 = 1; s1 = s1 + 1;是否正确?short s1 = 1; s1 += 1;是否正确?
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。
二、运算符
匹则运算当中的加号“+”有常见的三种用法:
1.对于同类型数值来说,那就是加法:
2.对于byte、short、char类型来说,在计算之前,它们会被提升成为int,然后再计算,即最终结果是int类型。
如:
byte x=12;
byte y=13;
int z=x+y;【结果为int类型,而不是byte类型】【byte + byte--->int + int 然后再计算】
3.对于字符串str来说,加号代表字符串连接操作。任何数据类型和字符串进行连接的时候,编译器会将该变量先变为String类型,再运算,结果变成字符串。
位运算符
①、按位与运算&(同一为一)
如果两个操作数对应位都是1,则结果位才是1,否则为0;
②、按位或运算|(同0为0)
如果两个操作数对应位都是0,那么结果位才是0,否则为1;
③、按位取反运算~(按位非)
将操作数上0变成1,1变成0;
④、按位异或^(同0异1)
当两个操作数对应位相同时结果位为0,否则为1;
⑤、位移操作
<<左移,>>有右移,>>>无符号右移;
<<、>>、>>>
1:<< 运算符用于无符号左移,又称逻辑左移,数据转换成补码形式,左移后,最低位补0.
2: >> 运算符用于有符号右移,又叫算数右移,数据转换成补码形式,右移后 ,最高位补符号位。
3:>>>运算符用于无符号右移,又叫逻辑右移,在移动过程中,最高位补0.
需要注意的是java中不支持<<<运算符。(理论上,左移就是不考虑符号位的,即逻辑左移与算数左移是一样的)
a<<b a以二进制补码形式,向左移b位,相当于二进制的a最后添加b个0,十进制相当于a*2b ;
a>>b a以二进制补码形式,向右移b位,相当于二进制的a最后减去b个0,十进制相当于a/2b ;
【<<与>>可以直接十进制计算出来,但>>>不可以】(逻左算右)(左乘右除)
例:
-20<<2==-20*2*2==-80
源码:10000000 00000000 00000000 00010100
反码:11111111 11111111 11111111 11101011
补码:11111111 11111111 11111111 11101100
左移:11111111 11111111 11111111 10110000
反码:11111111 11111111 11111111 10101111
原码:10000000 00000000 00000000 01010000
结果:-80
-----------------------------------------------
-20 >>> 2
源码:10000000 00000000 00000000 00010100
反码:11111111 11111111 11111111 11101011
补码:11111111 11111111 11111111 11101100
右移:00111111 11111111 11111111 11111011
反码:00111111 11111111 11111111 11111010
原码:01000000 00000000 00000000 00000101
结果:1073741819(√)
-----------------------------------------------
-20>>2 (有符号)
32位
原: 1000 0000 0000 0000 0000 0000 0001 0100
反: 1111 1111 1111 1111 1111 1111 1110 1011
补: 1111 1111 1111 1111 1111 1111 1110 1100
右移: 1111 1111 1111 1111 1111 1111 1111 1011
反: 1111 1111 1111 1111 1111 1111 1111 1010
原: 1000 0000 0000 0000 0000 0000 0000 0101=-5(√)
对于byte,short,char来说移位运算都要先将其转换为int类型即32位二进制;
【位移运算效率比正常的乘除法快】
如:
2 << 3和2*(2^3)效果是一样的,但前者比后者效率高;移位指令有更高的效率,因为移位指令占2个机器周期,而乘除法指令占4个机器周期。
&和&&,|和||区别:
&和&&都可作为逻辑运算符“与”使用,但是**&&是短路与**,运算时先判断符号前面的表达式的值,如果能够确定整个表达式的值,则不进行符号后面的表达式的运算,如果是“&”则前后都必须进行判断。因此&&可以节省一定性能。
同理,“短路或”,运算时如果前面的判断可以得到最终结果,那么后面的代码就不执行。而“|”会全部都判断;
if(10==10|10/0==0)【会报错】会执行10/0
if(10==10||10/0==0)【不会报错】
自增、自减运算符
前++,后++区别
- 若单独写做一行,两者效果是一样的,都相当于:
i=i+1;
i++;
++i;
若参与运算,前++是先自增再参与运算,后++是先参与运算再自增;
int n,m;
int i=1,k=1;
n=++i;//n等于2
m=k++;//m等于1
int i=1;
i=i++;
System.out.println(i);//这里输出为1
过程:i = i++;的操作可能相当于以下三步操作:①把变量i的值取出来,放在一个临时变量里(我们先记作temp);②把变量i的值进行自加操作;③把临时变量temp的值作为自增运算前i的值使用,在本题中就是给变量i赋值。因此,经过以上三步操作以后,虽然变量i在第②步操作中进行了自增运算,但第三步操作以后又把原来的值赋给了它,故最后输出结果为1。
即:
①temp=i;(i=1)
②i=i+1;(i=2)
③i=temp;(i=1)
运算符优先级
通常优先级从高到低是:
括号>自增自减运算符>算术运算符>比较运算符>逻辑运算符>赋值运算符
三、流程控制
break ,continue ,return 的区别及作用
break 跳出当前第一层循环(结束当前的循环体)
continue 停止本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
return 方法返回,不再执行下面的代码,表示程序控制从一个方法返回到调用该方法的地方(结束当前的方法 直接返回)
【提问】break只能跳出一层循环,如果多重循环如何跳出?
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标签,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环,另外continue也可以使用此类标签。例如:
public static void main(String[] args) {
out://out标记是自定义的,其他单词也是可以的
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
break out;
}
}
}
}
switch
在switch(expr)中,expr是整型或字符类型或它们对应的包装类以及常量,常量计算式;
在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。
Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型。
Java 7 开始,expr 还可以是字符串(String)。
但是long、float、double是不可以的,因为他们不像byte、short、char那样可以隐式转换为int。
switch(str){
case "str1":
xxx;
break;
case "str2":
yyy;
break;
default:
ccc;
}
for循环
语法:
for(①初始化表达式;②循环条件;③循环后操作表达式)
{
循环体;
}
执行流程:
初始表达式①—>循环条件表达式②—>循环体—>循环操作后表达式③
可以用for循环实现无限循环,用break跳出循环
for(;;){
xxx;
break;
}
增强for循环(foreach语句)
语法:
for(元素变量 x:遍历对象){
引用了x的Java语句;
}
如:
int[] array1={1,2,3};
for(int i:array){
Sysyem.out.printIn(i);
}
与
for(int i=0;i<array.length;i++){
Sysyem.out.printIn(array[i]);
}
等效