Java数据类型
long 64bit
double 64bit
int 32bit
float 32bit
short 16bit
byte 8bit
public static void main(String[] args){
char a= (char) Integer.MAX_VALUE;
System.out.println((int)a);
System.out.println("Hello World!");
try{
System.out.println("中".getBytes("UTF-8").length);
System.out.println("中中".getBytes("UTF-8").length);
System.out.println("中".getBytes("GBK").length);
System.out.println("中中".getBytes("GBK").length);
}catch(Exception e){}
}//main
输出:
run:
65535 --> 2的16次方,char两字节,16位,与short相当长度。short有符号位,数字为15位,表示范围为-32768~32767
Hello World!、
3 --> UTF8编码下,一个汉字3个字节
6
2 --> GBK编码下,一个汉字2个字节
4
程序中用到getBytes()的用法:
将String类型的字符串转换成byte类型,并且存入一个byte数组中。.length位获得数组的长度属性。
因为在java中的所有数据底层都是字节,字符串可以存入到byte数组。
getBytes()是使用默认的字符集进行转换,getBytes("utf-8")是使用UTF-8编码表进行转换。
程序中使用的Integer.MAX_VALUE的作用是:得到整型的最大值,即int的最大值(最大值+1变为最小值)。再用强制类型转换(char)进行截取。Integer最大作用在于字符串与整型的转换,也具有自动装箱拆箱功能(Object)。
为了避免int溢出,可以在常量后加一L,或者变量前加(long)。
public static void main(String[] args){
int max = Integer.MAX_VALUE;
System.out.println(max);
System.out.println(max+1);
System.out.println(max+2L); //L和l都可以,大小写没区别
System.out.println((long)max+2);
}//main
输出:
2147483647
-2147483648
2147483649
2147483649
int类型与long类型相加,自动转换为long类型。
char可以看作无符号的整型数。与short的非负整数部分重合(0~32767)。
public static void main(String[] args){
iint int_max = Integer.MAX_VALUE;
int char_max = (char)Integer.MAX_VALUE;
int short_max = Short.MAX_VALUE;
long long_max = Long.MAX_VALUE;
char a = 97;
char b = 'a';
int c = 'a';
System.out.println("char variable a is :"+a);
System.out.println("char variable b is :"+b);
System.out.println("int variable c is :"+c);
System.out.println("The max of int is :"+int_max);
System.out.println("The max of char is :"+char_max);
System.out.println("The max of short is :"+short_max);
System.out.println("The max of long is :"+long_max);
}//main
输出:
char variable a is :a
char variable b is :a
int variable c is :97
The max of int is :2147483647
The max of char is :65535
The max of short is :32767
The max of long is :9223372036854775807
原码,反码和补码
正数的原码、反码、补码都相等
例:0000 1010(在十进制中表示+10,左数第一位为符号位)
它的原码、反码、补码都是0000 1010
负数的原码是其本身,负数的反码是将符号不变,把符号后边的数取反,对于负数的补码 是把原码取反后加1
例:1000 1010(在十进制中表示-10)
它的原码是 1000 1010
它的反码是 1111 0101
它的补码是 1111 0110
数据类型转换:
自动类型转换:由范围小到范围大,且两者数据类型兼容的时候,为自动转换,如f转换d,s转换i,i转换l。
强制类型转换:反过来...
String属于引用数据类型,任何数据类型碰到String类型的变量或者常量都向String类型转换。
public static void main(String[] args){
int x = 10; float y = 3.5f;float z = x/y;
System.out.println(z); //整型和浮点型,自动转换浮点型
System.out.println((int)z); //浮点型强制转换整型,截断小数部分
System.out.println((int)(z+0.5)); //若要四舍五入,在小数部分加0.5再强制转换
String str = "Hello No.";
int numberA = 0;
int numberB = 7;
int numberC = 1;
int numberD = -1;
System.out.println(str+numberA+(numberC+numberD)+numberB);
}//main
输出:
2.857143
2
3
Hello No.007 //1和-1由于括号的加持先行运算,剩余的两个0并没有和7相加,而是和7一起转化为String类型添加到了str的后面。
提问:int a=10 int b =3; float f = a/b 会不会编译错误。
答:并不会
int x = 10; int y =3;
float z1 = x/y; //x/y结果为int类型,
float z2 = (float)x/y; //(float)x/y结果为float类型。
System.out.println(z1);
System.out.println(z2);
z1 = 3.0 z2 =3.3333333
不过反过来就要考虑下了,毕竟从float到int会损失精度。
float x = 10.0; float y =3.0;
//int z1 = x/y; // x/y结果为浮点数,直接赋值给int会损失精度,编译错误。
int z2 = (int)(x/y); //这里注意的是,若写成(int)x/y,按照优先级,x转换为int,y不变,出现编译错误。
//System.out.println(z1);
System.out.println(z2);
为什么会有两种与和或的操作?(&,&&,|,||)
&&, ||拥有短路功能。&和|则需要对所有条件进行判断。
public static void main(String[] args){
int a = 1;int b = 2;
int c = 0;
if(b!=2 && a/c == 0){ //若换&会检测所有布尔表达式,a/c则生成除数为0的异常,编译出错。
}else{
System.out.println("compile with no error");//&&短路与则在第一个判定false之后自动判断整个 //表达式为false,不会生成除数为0的异常。
}
}//main
输出:compile with no error
短路或||和或|也是一样
public static void main(String[] args){
int a = 1;int b = 2;
int c = 0;
if(b ==2 || a/c == 0){ //这里如果用|会生成算术异常,除数为0,编译错误
System.out.println("compile with no error");
}else{
}
}//main
输出:compile with no error
位运算符:^异或 ~取反 &与 |或 <<带符号的左移位 >>带符号的右移位 >>>不带符号的右移位
正数的原码,反码,补码相同。
负数的反码为符号位不变,原码取反。补码为反码+1。
int x = -3 ; int z = ~x; z = ?
负数x的原码 1,0000000 XX 00000011 //XX省略中间16位数
负数x的反码 1,1111111 XX 11111100
负数x的补码 1,1111111 XX 11111101
~x 为: 0,0000000 XX 0000010 --->> 2
所以z == 2;
<<左移填0 >>右移填充符号位 正0负1
int x = 3; int y = -3;
x<<2
0,0000000 XX 00000011 -> 0,0000000 XX 00001100 -> 12
y<<2 (给负数补码,反向操作先-1再取反(符号位1不变),得到负数原码)
1,1111111 XX 11111101 -> 1,1111111 XX 11110100 ->
1,1111111 XX 11110011 -> 1,0000000 XX 00001100 -> -12
x >> 2
0,0000000 XX 00000011 -> 0,0000000 XX 00000000 -> 0
y >> 2
1,1111111 XX 11111101 -> 1,1111111 XX 11111111 ->
1,1111111 XX 11111111 -> 1,0000000 XX 00000000 -> -1
x >>>2 -> 0 (x为正数,跟x>>2一样)
y >>> 2 无符号右移不补符号位,应该补0,连带符号位一起右移。
0,0111111 XX 11111111 -> 2的30次方(6+8+8)-1 = 1073741823
优先级:
()
[]
! + - 一元运算符 由右向左
~ 位取反 由右向左
++ -- 由右向左
* / %
+ - 算术运算符
>> <<
> >= < <=
== !=
&
^
|
&&
||
?: 三目运算符 由右向左
= 赋值运算符 由右向左
不过,最好多用括号改变优先级。
int a = 10 , b = 6;
a -= b++;
b = 7;
a = 10 - 6 = 4;
int a = 10, b = 6;
a-=++b;
b= 7;
a = 10 - 7 =3;
三目运算符可以替代if-else
int max = 0;int a = 6;
int b = 8;
max = a>b?a:b;
System.out.println(max);
输出:8
switch可以替换多分支的if结构。java1.5之前支持byte,short,char,int。1.5之后支持枚举。1.7之后支持String。
public static void main(String[] agrs){
System.out.println("Please input!");
Scanner in = new Scanner(System.in);//需要加入import java.io.File和import java.util.Scanner
String str=in.next();
switch(str){
case "abc":
System.out.println("abc");
break;
case "bcd":
System.out.println("bcd");
break;
default :
System.out.println("default");
break;
}//switch
}//main
输入abc,则case "abc"成功,跳出循环。如果不加break,会从第一个满足条件的case开始执行到default结束。
如果想在switch表达式加入boolean类型,可以考虑将boolean转换为String
boolean flag1=true;
boolean flag2=false;
switch(flag1+""){
case "true":
System.out.println("boolean type:true");
break;
case "false":
System.out.println("boolean type:flase");
break;
default :
System.out.println("default");
break;
}//switch flag1
输出:boolean type:true
若switch中换成flag2,则输出boolean type:false。
有意思的地方,byte short char int的包装类,Byte Short Character Integer也都可以带入表达式。不过这是由于1.5之后的自动拆箱(将引用数据类型转换为基本数据类型)和自动装箱功能(将基本数据类型转换为引用数据类型)。
Byte拆箱调用byteValue()方法,其他类似。所以switch只支持byte short char int 枚举 java.lang.String.
如果不加break,会从第一个满足条件的case开始执行到default结束。不过default加不加break感觉意义不大。
int b = 6;
char op = '+';
switch(op){
case '+':
System.out.println("Plus:"+(a+b));
case '-':
System.out.println("Minus:"+(a-b));
case '*':
System.out.println("Multiply:"+(a*b));
case '/':
System.out.println("Divided:"+(a/b));
default :
System.out.println("What are you doing?");
}//switch op
输出:
Plus:9
Minus:-3
Multiply:18
Divided:0
What are you doing?
从第一个符合条件的case开始一直输出到default结束。
break跳出当前循环。continue跳出当前循环并回到循环开始处继续执行。
while和do while不同之处为do while必定会执行一次。
while/do while和for的区别:while系列并不一定要明确知道循环次数。for需要明确循环次数。
String属于引用数据类型,任何数据类型碰到String类型的变量或者常量都向String类型转换。