boolean 类型
Java 虚拟机队boolean类型的处理比较特殊。
当Java编译器把java源代码编译为字节码时,会用int后byte来表示boolean。
在java虚拟机中,用证书零来表示false,用任意一个非零证书来表示true。
在java源程序中,不允许把证书或null赋值给boolean类型的变量。
byte short int long 类型
byte,short int long 都是整数类型,并且都有符号整数。
在java语言中,为了区分不同进制的数据,八进制数以"0"开头,十六进制数以"0x"开头。
选择合适的整数类型
例如月份的取值是1和12之间的整数,因此把代表月份的month变量定义为byte类型:
byte month;
当month变量为byte类型时,Java虚拟机只需为month变量分配1个字节的内存。如果把month变量定义为long类型,尽管是可行的,但是会占用更多的内存空间,影响程序的性能。不过在内存资源充足的情况下,对于整数变量,通常都把它定义为int类型,这样可以简化数学运算时强制类型转换操作。
在java语言中,如果数学表达式中都是整数,那么表达式的返回值只可能是int或long类型,如果把返回值赋给byte类型的变量,就必须进行强制类型的转换,例如
byte month = 1;
month = month + 2 ;//编译错误,month+2 的结果为int类型
month = (byte)(month+2) ;//合法
2 给整数类型变量赋值[size=medium][/size]
如果一个整数值在某种整数类型的取值范围内,就可以把它直接赋给这种类型的变量,否则必须进行强制类型的转换。
例如整数13 在byte类型的取值范围(-128~127)内,因此可以把它直接赋给byte类型变量。
byte b = 13;
再例如129不在byte类型的取值范围,则必须进行强制转换。
byte b = (byte)129 ;//变量b的取值为-127
java 语言允许把八进制(以0开头),十六进制(以0x开头)赋值给整数类型变量:
int a1 = 012;
int a2 = 0x12;
int a3 = 12;
int a4 = 0xF1;
byte b = (byte)0xF1; //;十六进制 ,b的十进制的取值为-15
引用
在这里先温习下计算机基础理论
byte是一个字节保存的,有8个位,即8个0、1。
8位的第一个位是符号位,
也就是说 0000 0001代表的是数字1
1000 0000代表的就是-1
所以正数最大位0111 1111,也就是数字127
负数最大为1111 1111,也就是数字-128
上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码
1、反码:
一个数如果是正,则它的反码与原码相同;
一个数如果是负,则符号位为1,其余各位是对原码取反;
2、补码:利用溢出,我们可以将减法变成加法
对于十进制数,从9得到5可用减法:
9-4=5 因为4+6=10,我们可以将6作为4的补数
改写为加法:
9+6=15(去掉高位1,也就是减10)得到5.
对于十六进制数,从c到5可用减法:
c-7=5 因为7+9=16 将9作为7的补数
改写为加法:
c+9=15(去掉高位1,也就是减16)得到5.
在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。
⑴一个数为正,则它的原码、反码、补码相同
⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1
- 1的原码为 10000001
- 1的反码为 11111110
+ 1
- 1的补码为 11111111
0的原码为 00000000
0的反码为 11111111(正零和负零的反码相同)
+1
0的补码为 100000000(舍掉打头的1,正零和负零的补码相同)
Integer.toHexString 的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,
例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即 0xffffffff但是这个数是不对的,这种补位就会造成误差。
和0xff相与后,高24比特就会被清0了,结果就对了。
----
Java 中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。
而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。
Char 字符与字符编码
char是字符类型,java语言对字符采用Unicode字符编码。由于计算机的内存之能存储二进制数据,因此必须为各个字符进行编码。字符编码,是指一串二进制数据来表示特定的字符。
常见的字符编码包括:
1 ASCII 字符编码
ASCII编码实际上只用了一个字节的7位,一共能表示128个字符。例如“a”的编码是01100001 相当于十进制的97.
2 UNICODE
收录了全世界所有语言文字的字符,是一种夸平台的字符编码。
3 GBK gb2312 utf-8
引用变量在java虚拟机中所处于数据区的哪个区呢?
这取决于变量的作用域,如果是局部变量,则位于java栈区;如果是某个类的静态成员变量,则位于方法区,如果是某个类的成员变量,则位于堆区。
2 float 和 double 类型
float :占用4个字节 共32位
double : 占用8个字节,共64位
java类的成员变量有俩种:
引用
一种是被static关键字修饰的变量,叫类变量或者静态变量
另一种没有static修饰,为实例变量
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
成员变量的初始化
整数型(byte,short,int long)的基本类型变量的默认值是 0
单精度浮点型float的基本类型变量的默认值是0.0f
双精度浮点型double的基本数据类型是0.0d
字符型char的基本类型变量的默认值是"\0000"
局部变量的声明周期[size=medium][/size]
当Java虚拟机(更确切的说,是Java虚拟机中的某个线程)调用一个方法时,会为这个方法的局部变量分配内存。
当Java虚拟机(更确切的说,是Java虚拟机中的某个线程)结束调用一个方法时,会结束找个方法中的局部变量的声明周期.
以下是Sample类中定义的4个变量: var1 var2 var3 var4
public class Sample {
int var1 = 1; //var1是实例变量
static int var2 = 2;// var2是静态变量
public int add() {
int var3 = var1 + var2 ; //var3 是局部变量
return var3 ;
}
public int delete() {
int var4 = var1 - var2 ;//var4 是局部变量
return var4;
}
public static void main(String args[]) {
new Sample().add();
}
}
当执行“java Sample”命令时,Java虚拟机执行以下流程:
(1) 加载Sample类,开始讲台变量var2的声明周期,var2位于方法区
(2) 创建Sample实例 ,开始实例便令var1的声明周期,var1位于堆区
(3) 调用Sample实例的add()方法,开始局部变量的声明周期,var3位于Java栈区。
(4) 执行完毕Sample实例的add()方法,结束局部变量的var3的声明周期,退回到main()方法。
(5) 执行完毕后main方法,结束sample实例何它的实例变量var1的生命周期。
卸载Sample类,结束静态变量var2的生命周期,java虚拟机运行结束。
由于main方法没有调用Sample实例的delete方法,所以var4变量在java虚拟机的运行过程从没有创建过.
引用
将局域变量的范围最小化
notes:
在需要使用某个局部变量的时候,才定义它
使方法小而集中,如果一个方法包含多个操作,尽可能把这个方法分解为多个小方法,每个方法负责一项操作,这写小方法在java源文件中可集中放在一起。