1,(在有符号的情况下)若一个二进制数都是1,则对应的十进制数是-1
2,在定义数值类型时,若无特别说明,整数默认:int 小数默认:double
在内存中
占字节数 取值范围
(1)byte:1个字节(8个二进制位) -2(7) --- 2(7)-1
(2)short:2个字节(16个二进制位)-2(15)--- 2(15)-1
(3)int :4个字节(32个二进制位)-2(31)--- 2(31)-1
(4)long: 8个字节(64个二进制位)-2(63) --- 2(63)-1
class VarDemo
{
public static void main(String[] args)
{
//数据类型 变量名 = 初始化值
byte b = 6;
short c = 8;
int x = 123;
long l = 123456789006l; //注意最后是英文字母“l”,不是数字1
}
}
虽然在程序中定义了byte类型的变量b,并赋给了初值为整数6,但是此时这个整数6是默认为int(占据4个字节)类型的,在内存中的表示形式为:00000000 00000000 00000000 00000110,但是byte在内存中只占据了一个字节00000000,那他是如何装下这个整数6呢?
但是编译器在检查的时候,发现6这个整数在byte范围之内,所以会自动把前面的三个字节段去掉
【00000000 00000000 00000000 00000110】---》【00000110】
其他的依照这个类推!
class VarDemo { public static void main(String[] args) { byte b = 6; short s = 4; int i = 7; long l = 1234567890l; //过大的数(范围超过了int型) float f = 2.3f; //如果不加f的话,编译的时候会报错,说损失精度,因为小数默认是double类型的 double d = 3.4; char c = '1'; //char c = 1 boolean bo = true; //bo = false } }
//自动类型转换 class VarDemo2 { public static void main(String[] args) { /* byte b = 4; int x = 3; x = x + b; //b就自动类型提升为和x一样的整形。 System.out.println("x="+x); */ byte b = 3; b = b + 1; /*
【在编译的时候,b=b+1是不会做加法运算的,所以下文中说到的相加是不准确的。】
这一句在编译的时候会报错,因为在做相加之前 byte类型的变量b被自动提升为了和1一样的整形类型 ,所以相加完后的结果为整形,但是要赋给的变量b此时 是byte类型的,所以可能丢失精度,此时编译器会报错: 原理如下图(1) 但是此时又有这样一个疑问: 在定义byte b = 3;的时候,3也是整形的, 那为什么整形的3可以赋值给byte类型的变量b呢(这个解释就是上面所说的内容) 疑问是虽然做完了加法运算后的结果为整数(4),但是整形的4也在byte范围之内啊, 此时为什么就不能赋给byte类型的变量b了呢? 原因是: 因为在做加法之前,byte类型的变量b的值是不确定的,比如如下代码 byte b = 3; b = 127; b = b+1; 这个时候做完加法后的结果是整形的数值128,而此时128已然超出了byte类型的范围,所以如果再 把128赋给byte类型的变量b,就会发生数据损失。 而byte b = 3之所以可以完成把整形(int)的数3赋给byte类型的变量b是因为编译器在检查的时候 判断了这个3是在byte范围之内的,并且这个3是一个常量,值不会改变,(就是数值3)所以可以按照上面的 方法把这个整形的3赋给byte类型的变量b。 总结一句话就是: 若是不变的量(常量)在判断后,符合这个类型的取值范围,则可以成功赋值。 若是变量,则不能再赋值。比如 上面的b = b + 1;(第二个b是变量,不确定其值,万一b等于127呢?思考...) */ System.out.println("b="+b); } }
/*可以通过强制类型转换,实现上述赋值*/ //byte b = 3; //b = (byte)(b+1); System.out.println("b="+b);
//但是种转换可能发生数据丢失:如下图:
class OperateDemo { public static void main(String[] args) { /*【算术运算符】 + - * / %(取余数) */ int x1 = 3810; System.out.println(x/1000); System.out.println(2%5); //结果为2 System.out.println(-2%5); //结果为-2 System.out.println(2%-5); //结果为2 System.out.println(-2%-5); //结果为-2 //总结:结果为正还是为负,取决于左边的操作数。 // 若左边操作数为正,则结果一定为正, // 若左边的操作数为负,则结果一定为负。 //应用: // 如果想让某一个结果控制在这个数的范围内, // 则可以用模运算进行操作。比如想让某一个数 // 的结果控制在10以内,就模10,则运算后的结果 // 一定在10以内 /* 【++:自增】。对原有的数据进行+1 int a = 3; a++ ++a--->a = a+1; //当自增,自减进行独立运算的时候,++a和a++是没有区别的。 a++; System.out.println("a="+a) //结果是a=4 ++a; System.out.println("a="+a) //结果是a=4 */ //当这个自增运算和其他运算放在一起时,就有区别了: int a= 3,b; b = ++a; System.out.println("a="+a+"b="+b); //结果是a=4,b=4 /* b = ++a; 运算过程如下: a先执行a = a+1;再把此时a的值赋给b */ b=a++; System.out.println("a="+a+"b="+b); //运算结果是a=4,b=3; /* b = a++; 运算过程如下: 先在内存中开辟一块空间,把a的值3临时存储下来,然后做a= a+1运算, 此时a的值为4。再把原有的a的值赋给b,则此时b的值为3。 其运算原理如下: temp = a; //先将a进行临时存储。 a = a+1; //自增 b = temp; //将临时的值赋给b。 */ //字符串的连接符: System.out.println(5+5); //输出结果为整数10 System.out.println("5"+5); //输出结果为字符串55 System.out.println("5+5="+5+5); //输出结果为5+5=55 System.out.println("5+5="+(5+5)); //输出结果为5+5=10 //【赋值运算符】:= , +=, -= , *= , /= , %= int x,y,z; x=y=z; int a = 3; //把右边赋给左边 a+=4; //将左右两边的和赋给左边a = a+4; //练习题:下面两个式子有区别吗? short s = 4; //s = s+5; //编译不能通过 //s+=5; //编译可以通过,因为+=是赋值运算符,会做自动转换。 //【比较运算符】 System.out.println(3==4); //输出结果为:false //运算完的结果要么true,要么false //【逻辑运算符】用来连接boolean型表达式的。 /* &:与 |:或 ^:异或 !:非 && :短路与 || :短路或 */ int x = 7; //x>2 & x<5 //x<2 | x>5 /* &:两边都为true,结果为true.否则为false. |:两边都为false,结果为false,否则为true. ^:两边相同为false,两边相异为true. */ //&& :短路与 || :短路或 y>3 & y<6 y>3 && y<6 /* & 和 && 的区别: &:无论左边结果是什么,两边都参与运算。 &&:当左边为false,右边不参与运算。 | 和 ||的区别: |: 两边都参与运算。 ||:当左边为true时,右边不参与运算。 */ } }