闭关修炼100天 JavaEE乱杀 闭关第二天

本文详细解析了Java中的基础类型如byte和int之间的运算,涉及类型转换、运算符优先级、短路逻辑、Scanner输入以及位运算等知识点,通过实例演示帮助理解。
摘要由CSDN通过智能技术生成

闭关修炼100天 JavaEE乱杀 闭关第二天

推荐大家搭配Java技能树学习,很多比较容易理解的东西我并没有呈现出来,但我们还是得掌握它,在基础之上进一步深造。

第一个代码及其详解

public class Test01{
	public static void main(String[] args){
		byte a = -128;
		byte b = 127;
		System.out.println(a +" " + b);
		
	}
}
//输出结果-128 127;但是如果把b = 128就会报错,int转换为byte可能会有损失

btye为1个字节,占8个bit位,首位为符号位

最大值:2的8次方减一:127

2^72^62^52^42^32^22^12^0
01111111

最小值:首位既作符合位,又作数值位:-128

其实按正常理解这是-0,1作为符号位,后面数值为0,但是由于已经有0的存在了,会出现歧义,所以科学家把-0设置为了-128.

2^72^62^52^42^32^22^12^0
10000000

第二个代码及其详解

public class Test01{
	public static void main(String[] args){
		byte a = 1;
		System.out.println(a++);
		System.out.println(a);
		byte b = 1;
		System.out.println(++b);
		System.out.println(b);
		
	}
}
/**
输出结果为:
	1
	2
    2
    2
*/

这里就要谈到a++和++a的区别了,a++是先使用再自增,++a是先自增再使用,以此内推a–和–a也一样。

第三个代码及其详解

public class Test01{
	public static void main(String[] args){
		byte a = 1;
		byte b = 1;
		byte c = a+b;
		System.out.println(c);
	}
}
//输出结果报错,不兼容的类型,从int转换到byte可能会有损失

这是因为byte、char、short类型做运算时会自动转型为int类型来做运算,为什么byte和short做运算要转换为int呢,让我上网搜一搜,大概看了一下,就是底层原理设计,我大概推测是因为计算方法用的是int,重新弄一个计算方法的成本严重大于转型成本。

解决方法byte c = (byte)(a+b)也就是加一个强转,看到这里我突然想到一个事,既然byte的运算都是转换为int计算的,那么byte定义一个a ,a++是怎么样运行的呢,运行结果是不是也是int类型呢,来个代码尝试:

public class Test01{
	public static void main(String[] args){
		byte a = 1;
		byte b = 1;
		b = ++a;
		System.out.println(b);
	}
}
//输出结果为2,又发现一个问题,b = a++;输出结果为1

那就证明a++和++a输出结果不是int,这里我不知道具体咋回事,应该是通过强转,转换成了byte类型。

然后就是b = ++a和b = a++结构不同的原理:

b = a++;先将a的值1压入栈中,再将a的值加1,最终将栈中的值赋值给b,所以b=1.

b = ++a;先将a的值加1再压入栈中,然后赋值给b,所以b=2.

第四个代码及其详解

public class Test01{
	public static void main(String[] args){
		byte a = 1;
		a += 1;
		a = a+1;
	}
}
/**
	运行结果:报错:不兼容类型,从int转换到byte可能会有损失
			a = a+1;
*/

为什么a += 1不报错,a = a+1就报错了呢?(上网搜了一下)

a += 1;运算符使用的是复合赋值运算符,运算时会将右边数也就是1转换为左边a的类型。

a = a+1;运算符为简单赋值运算符,右边的数据类型不改变(1还是int类型),左边a是byte类型,所以就会出现从int转换到byte可能有损失的错误。

第五个代码及其详解

import java.util.Scanner;
public class Test01{
	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入一个数");
		int i = scan.nextInt();
		System.out.println(i);
		
	}
}

上面是Scanner的用法,就是我们能输入,上面的代码中我们能输入int值。

import java.util.Scanner;这是导包,Scanner是一个类,在java文件中的util文件中。

Scanner scan = new Scanner(System.in);要理解这个代码就要去了解c语言里面的动态分配malloc,

Scanner * scan = (Scanner*)malloc(sizeof(Scanner));

左边是定义一个存放Scanner类型地址的指针变量scan;右边是动态分配一个大小为Scanner大小的空间并将首地址类型转换为Scanner类型。scan中存放的是右边的首地址,指向右边,在java中就代表了右边这块空间。

System.in是系统输入流,由外界输入系统。

int i = scan.nextInt();获取scan中int值并赋值给i。

第六个代码及其详解

public class Test01{
	public static void main(String[] args){
		System.out.println(false && 10/0>3);
		System.out.println(false & 10/0>3);
	}
}
/**
	输出结果:
			false
			报错,0不能当除数
*/

看了上述的报错你应该就明白短路与&&和与&的区别,短路与&&只要前面为false就不判断后者,而与&前面为false也要判断后者。以此内推,短路或||和或|也是一样的。我突然有一个想法,既然这个短路与不判断后者,是不是后面能不是布尔值,让我用代码试试:

public class Test01{
	public static void main(String[] args){
		System.out.println(false && 10);
	}
}
//输出结果:错误:操作数类型错误

那就证明后面还是得是布尔值,得是表达式。

第七个代码及其详解

public class Test01{
	public static void main(String[] args){
		System.out.println((false)?10.9:9);
	}
}
//输出结果:9.0

三目运算符值1和值2都是常量的时候,按照取值范围大的返还数据,上述代码中值1是10.9,double类型;值2是9,int类型,按照double返还类型,所以返还的是9.0.

第八个代码及其详解

public class Test01{
	public static void main(String[] args){
        char x = 'x';
        int i = 10;
		System.out.println((false)?i:x);
	}
}
//输出结果为120

三目运算符值1和值2都是变量的情况,也是按照取值范围大的返还数据,x字符在底层对应的是120,int类型取值范围大于char,所以x按照int类型输出,就为120。

第九个代码及其详解

public class Test01{
	public static void main(String[] args){
        char x = 'x';
		System.out.println((false)?x:97);
		System.out.println((false)?100000:x);
	}
}
//输出结果为a 120

三目运算符值1和值2是变量和常量的情况下,常量如果在这个变量属于的变量类型的取值范围中时,就按变量类型输出,97在char类型取值范围中,按照char类型输出,97对应的是a,所以输出a;常量如果不在这个变量属于的变量类型的取值范围中时,就按照常量输出,x对应的常量是120。

第十个代码及其详解

public class Test01{
	public static void main(String[] args){
        byte i = 127;
		System.out.println(i<<1);
	}
}
//输出结果为254

这是为什么呢,我们知道127的二进制代码为0111,1111;

254的二进制代码为0000,0000,0000,0000,0000,0000,1111,1110

在第三个代码详解中谈到byte做运算时会自动向上转型到int类型,位运算也一样,左移一位。

public class Test01{
	public static void main(String[] args){
        int i = 2147483647;
		System.out.println(i<<1);
	}
}//输出结果为-2

2147483647的二进制代码为0111,1111,1111,1111,1111,1111,1111,1111

-2的二进制代码为1111,1111,1111,1111,1111,1111,1111,1110

public class Test01{
	public static void main(String[] args){
        int i = -2147483648;
		System.out.println(i>>1);
	}
}
//输出结果为-1073741824

-2147483648二进制代码1000 0000 0000 0000 0000 0000 0000 0000

-1073741824二进制代码1100 0000 0000 0000 0000 0000 0000 0000

右移在高位补符号位

public class Test01{
	public static void main(String[] args){
        int i = -2147483648;
		System.out.println(i>>>1);
	}
}
//输出结果为1073741824

-2147483648二进制代码1000 0000 0000 0000 0000 0000 0000 0000

1073741824二进制代码0100 0000 0000 0000 0000 0000 0000 0000

三个小于大于符号为无符号右移,高位补0

第十一个代码及其详解

public class Test01{
	public static void main(String[] args){
        int a = 1;
        int b = 2;
        a = a^b;
        b = a^b;
        a = a^b;
		System.out.println(a + " " + b);
	}
}输出结果为2 1

上述代码为实现a、b两个数的交换,很好理解.

a = a^b;

b = ab;这里a里面是ab,那么实际上就是abb,b异或自己本身就为0,结果就为a

a = ab;这里a为ab,b为a,就是aba,a异或自己本身为0,结果就为b

于是就实现了a与b的交换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值