java萌新的进化旅程02

版权声明:转载请注明出处 https://blog.csdn.net/YaeSakuraZR/article/details/83870734

初识java(02)

这篇文章从最基本的一些东西开始讲起,因为博主也刚学,所以… 讲的不好请见谅,哪里不对还请指出
涉及到的内容有:数据类型,数据类型转换,数据类型取值范围,装箱拆箱,按位与或非运算

一、数据类型

首先了解数据类型有哪些
在这里插入图片描述
数据类型之间的关系
在这里插入图片描述
我们知道不同类型的数据是不能直接拿来拼凑使用的,所以这里就涉及到了类型转换
类型转换分为自动类型转换强制类型转换
这里举例说明

int a=1;
byte b=2;
byte c=a+b;

像这样从int(大类型)到byte(小类型)的转换无需其他步骤,这样的数据转换称为自动类型转换
再举一个例子来说明

int a=1;
byte b=2;
int c=a+b;           //错误
int c=(int)(a+b);     //这里的步骤就是强制数据转换

像这样从byte到int(小到大)的转换则必须用到强制数据转换
注意:强制数据转换时一定要注意转换前后的数据类型,取值范围,以及合理性
既然说到数据类型的取值范围,那就有必要列出一些常用的数据类型取值范围了
首先,一个字节(byte)对应8个位数
在这里插入图片描述
首位(红色)对应的为符号位,首位为0时对应为+,为1时对应为-
这样,一个字节所存储的数值最大值为127,最小值为-128
这里还要补充一个无符号数据类型
拿无符号byte来举例,其最大值为255,最小值为0,也就是说相当于去掉了负数部分
各个数据类型的字节数

数据类型 字节数
byte 1
short 2
int 4
long 8
float 4
double 8
char 2 (Unicode)

按照byte的取值范围我们可以类推出其他数据类型的取值范围

数据类型 取值范围
byte -128 — 127
short -32768—32767
int -2^31 — (2^31)-1
long -2^63 — (2^63)-1
char \u0000 (0) — \uffff(65535)
boolean false — true

当然还有各个基本类型对应的包装类
byte =》Byte
short=》Short
int =》 Integer
long=》Long
float=》Float
double=》Double
char=》Character
boolean=》Boolean
这里要讲解下装箱与拆箱

二、装箱拆箱

首先我们要理解装箱与拆箱的概念
装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float以此类推
拆箱:和装箱相反,将引用类型的对象简化成值类型的数据
我们以int来举例,假设我们要得到一个数值为1的Integer数据

Integer i = new Integer(10);//这是在java SE5之前的装箱操作
//从java SE5 开始提供了自动装箱功能
Integer i = 1; //装箱
int n = i;     //拆箱

看似简单的一个过程,但却不能小瞧它所包含的内容
在这里我们调用java源码来详细看看

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

/**
* The value of the {@code Integer}.
*
* @serial
/
private final int value;
/
*
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
/
public Integer(int value) {
this.value = value;
}

/
*
* Constructs a newly allocated {@code Integer} object that
* represents the {@code int} value indicated by the
* {@code String} parameter. The string is converted to an
* {@code int} value in exactly the manner used by the
* {@code parseInt} method for radix 10.
*
* @param s the {@code String} to be converted to an
* {@code Integer}.
* @exception NumberFormatException if the {@code String} does not
* contain a parsable integer.
* @see java.lang.Integer#parseInt(java.lang.String, int)
*/

这里我们会发现在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。
在这里只是介绍下装箱和拆箱,看似简单的东西往往会暴露出很多的问题,例如这些 点我查看

三、按位运算

1.与
仍然是举个例子,比如 5&3

public class Test {
	public static void main(String[] args) {
		System.out.println(5 & 3);//结果为1
	}
}

要想搞清楚与运算是如何实现的我们必须把10进制数换为2进制数
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
与的运算规则是 0与0为0,1与0为0,1与1为1
所以5&3的结果为1
1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001

下面我们来依次展示或、非、异或的按位运算

2.或

public class Test {
	public static void main(String[] args) {
		System.out.println(5 | 3);//结果为7
	}
}

或的运算规则是 0或0为0,1或0为1,1或1为1
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111

3.非

public class Test {
	public static void main(String[] args) {
		System.out.println(~5);//结果为-6
	}
}

非的运算规则是 0变1,1变0
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010

4.异或

public class Test {
	public static void main(String[] args) {
		System.out.println(5 ^ 3);//结果为6
	}
}

异或的运算规则 0异或1为1,0异或0为0,1异或1为0
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110

这里还要介绍两种特殊的位运算:左移和右移
1.左移

public class Test {
	public static void main(String[] args) {
		System.out.println(5<<2);//运行结果是20
	}
}

0000 0000 0000 0000 0000 0000 0000 0101 左移2位,右边空位补0
0000 0000 0000 0000 0000 0000 0001 0100 运行结果为20

2.右移

public class Test {
	public static void main(String[] args) {
		System.out.println(5>>2);//运行结果是1
	}
}

0000 0000 0000 0000 0000 0000 0000 0101 右移2位,左边空缺补0
0000 0000 0000 0000 0000 0000 0000 0001 运行结果为1

3.无符号左移(误)
这个东西其实是没有的,因为左移是在后面补0,而右移是在前面边补1或0
有无符号是取决于数的前面的第一位是0还是1
所以右移是会产生到底补1还是0的问题。
而左移始终是在右边补,不会产生符号问题。
所以没有必要无符号左移<<<。
无符号左移<<<和左移<<是一样的概念

4.无符号右移
我们先来比较一下右移无符号右移的区别

public class Test {
	public static void main(String[] args) {
		System.out.println(-5>>3);//结果是-1
		System.out.println(-5>>>3);//结果是536870911
	}
}

-5右移3位后结果为-1,二进制为: 1111 1111 1111 1111 1111 1111 1111 1111 (用1进行补位)
-5无符号右移3位后的结果 536870911 二进制为: 0001 1111 1111 1111 1111 1111 1111 1111 (用0进行补位)

这里要写一道面试题
如何用最快的方法把一个数据缩小到1/2倍
答案是右移两位
因为在计算机中,位的运算要快于常规的赋值运算

到此为止,有关本篇涉及的内容以及介绍完了
最后还要说一句

记得经常保存!!!

猜你喜欢

转载自blog.csdn.net/YaeSakuraZR/article/details/83870734