java数据类型与运算符


本文讲述java数据类型和java运算符,java数据类型包括8种基本数据类型和引用数据类型,不同类型数据间有转换机制;本文还描述了java众多运算符及一些对应使用注意事项和运算符优先级。

java数据类

Java是强数据类型语言,对于每一种数据都定义明确了的类型,并在内存中分配不同大小的空间。

Java数据类型分为8种基本数据类型和引用型数据类型

8种基本数据类型是:

1. byte,short,int,long,整型,内存中分别占1个字节、2个字节、4个字节、8个字节。

2. float,double,浮点型,分别占4个字节、8个字节。

java中的浮点数采用的是IEEE Standard 754 Floating Point Numbers标准。
float占用4个字节,也就是32bits,在内存中分配如下:
第1个bit表示符号,0表示正数,1表示负数.
第2-9个bit表示指数,一共8为(可以表示0-255),这里的底数是2,为了同时表示正数和负数,这里要减去127的偏移量.这样的话范围就是(-127到128),另外全0和全1作为特殊处理,所以直接表示-126到127。
剩下的23位表示小数部分, 小数点后第1位基数是0.25,第2位基数是0.125,依次类推是(1/2)^n,各位上的值与基数相乘再相加就是最后结果中的小数部分。
最后结果是:(-1)^(sign) * 1.f * 2^(exponent).这里:sign是符号位,f是23bit的小数部分,exponent是指数部分。
这是float数据在内存中的规格化表示,IEEE 754标准中还规定了非规格化表示法,另外还有一些特殊规定,这里不再多说。
float类型数据的取值范围是[2-149,(2-2-23)·2127],也就是Float.MIN_VALUE和Float.MAX_VALUE。
double数据在内存中的表现形式与float有相通之处。double占8个字节,即64bits,第1位是符号位,第2~12位是指数位,第13~64位是尾数位。
double取值范围是[2-1074, (2-2-52)*21023],也就是Double.MIN_VALUE和Double.MAX_VALUE。

3. char,字符型,占1个字节 

一个char字符表示Unicode字符集中的一个元素,Unicode字符由16位组成,范围从’\u0000’,’\uffff’(u代表j是unicode字符),所以char的范围是0~65535(2^16-1)。Unicode的前128个字符编码与ASCII兼容。

4. Boolean,布尔型占一个字节,取值范围是false和true。

引用数据类型:类、接口、数组

类型转换

自动类型转换:不同类型数据间不能进行运算,除非提升为同类型的;数值型的6种基本数据类型间可以进行运算,因为系统底层会对参与运算的数作自动类型提升.

类型自动提升规则:
  所有的byte/short/char将被提升到Int
  如果一个操作数是long型,计算结果就是long
  如果一个操作数是float型,计算结果就是float
  如果一个操作数是double型,计算结果就是double

强制类型转换:不同类型数据间还可以手动进行强制类型转换,如double型数值要想去掉小数时,可以将double型强制转成int型,强转语法格式:int a=(int)4.5.

下面的代码中总结若干类型转换可行及不可行的情况

public class Type {
	public static void main(String[] args) {
		byte b=3; /*编译通过,虽然3默认是Int类型,但是常量直接赋值给byte时,系统内部会自动作一个判断,只要在byte范围内就可以*/
		short s=3000; /*编译通过,同上*/
		long l=4; /*编译通过,同上,但一般也成long l=4l*/
		long la=101000001010; /*编译不通过,101000001010超出int取值范围,系统不会自动将它当作double类型处理*/
		long lb=101000001010l; /*编译通过,101000001010后面加l,手动将其指定为long类型*/
		float f=2.3; /*编译不通过,因为2.3默认是double型变量,不能赋给float型变量,在范围内也不行*/
		float f1=2.3f; /*编译通过,因为2.3f指定了2.3是float型变量*/
		double d=34.56; /*编译通过*/
		b=b+2; /*编译不通过,因为2是Int型,b也自动提升成int型进行运算,得到的结果还是int型的;因为b是变量,这时系统内部就无法判断运算结果是否在byte范围内,因此不能再赋给byte变量*/
		b=(byte)(b+2); /*编译通过,但注意不能写成b=(byte)b+2,不起作用*/
         char c=’你’; /*编译通过,一个char类型变量占2个字节,一个汉字也是占2个字节*/
		System.out.println('a'+1); /*ASCII码表中有'a'与数字的对应,和1运算时,类型就会提升为int,将ASCII表中'a'对应的数字体现出来,打印98*/
	   System.out.println('a'); /*单独打印'a'时是显示字符效果*/
	}
}

java运算符

算术运算符

1. 加减乘除:+-*/

关于符点数运算,在黑马论坛上看过一个有意思的帖子,在这里记录并分享下,代码如下

public class Test3 {
	public static void main(String[] args) {
		System.out.println(5-2.1);
		System.out.println(2-1.1);
		System.out.println(5f-2.1f);
		System.out.println(2f-1.1f);
		System.out.println(5f-2.1);
		System.out.println(2f-1.1);
	}
}
/*运行结果:
2.9
0.8999999999999999
2.9
0.9
2.9
0.8999999999999999
*/

这个还得说到浮点数在内存中的二进制表示,并不是所有带小数都可以在内存中用32位或64位二进制精确表示出来,如3.125可以用一个32位或64位二进制精确表示,但0.1在内存中用64位二进制也无法精确表示;

另一方面,Double类的静态toString()方法在打印double数值时是将能区分该值和其double类型的邻近值的最短小数位数的数值打印显示出来;也就是说,假设d是double类型的数,x是调用toString方法得到的d的十进制数,那么 d 一定是最接近 x 的 double 值。(参见jdk 1.6 API文档中Double类toString()方法说明)。

基于以上2点,java中浮点数不能进行精确的四舍五入运算,这在商业领域,特别是金融行业是不允许的,如你有9.999999999999块钱,但计算机却不认为你能买10块钱的东西。java中float和double只能用来做科学计算或者是工程计算,在商业计算中需要用java.math.BigDecimal。这个就说到这,有个直观印象就好,更系统且深入的知识还有待学习。

2. 取模:%

就是取余数;涉及负数取余时,结果的符号与左边的数一致,如1%-5=1-1%5=-1.

3. 自增和自减:++,--

b=a++和b=++a:b=a++是先将a的值赋给b,然后a自增1,b=++a是a先自增1,然后将a值赋给b;2种写法中b取值不同,但下次使用a时,a值是一样的,都是自增过1的。

4. 字符串连接符:+

字符串数据和任何数据使用+,都是相连接,最终都会变成字符串。

5. 转义字符:通过\来转变后面字母或者符号的含义

常用的有:\n:换行,\b:退格,\r:按下回车键,\t:制表符,相当于tab键。
在Linux系统中换行用\n来表示,在window系统中回车符用\r\n来表示。

6. 赋值运算符=,+=,-=,*=,/=,%=

用下面一小段代码说明一下:

public class test{
    public static void main(String[] args){
            x+=4;//效果等同于x=x+4;
            short s=4;
            s=s+4;/*编译失败,2次运算,s进行类型提升为int与4相加,运算结果还是int类型,然后赋值给s时失败*/
            s+=4;/*编译通过,1次运算,将s和4的和赋给s,+=在赋值时,会自动执行强制转换操作*/
            int a,b,c;
            a=b=c=5;//Java允许这样赋值
    }
}

7.  比较运算符:==,!=,<,>,<=,>=,instance of(检查是否是某个类的对象)

8.  逻辑运算符:用于连接boolean类型的表达式

&:两边都为真时,结果为真
|:两边只要有一个为真,结果为真
^:异或,两边相同结果为false,两边不同结果为true.
&&:与&的不同是进行短路运算,只要左边为假,右边不会再运算
||:与|的不同是进行短路运算,只要左边为真,右边不会再运算

9. 位运算符:直接对二进制进行运算,位运算的速度是最快的

<<:左移,其实就是乘以2的移动的位数次幂
>>:右移,其实就是乘除以2的移动的位数次幂;右移后最高位补什么由原有数据的最高位而定
>>>:无符号右移,右移后高位上空出来的位都以0补
&:与,运算规则跟&作为逻辑运算符时相同,对应位都为1时结果为1
|:或,对应位只要有一个为1,结果为1
 ^: 异或,对应位数上,相同时为0,不同是时为1; 一个数异或同一个数2次,结果还是那个数,可用异或来加密数据,再异或同一个数来解密。
~:反码,取反

这里记录一个有意思的小例子:

/*2个数互换的3种方法,常用的是swap1*/
public class Swap {
	/*使用第三方变量*/
	public static void swap1(int a,int b){
		int temp;
		temp=a;
		a=b;
		b=temp;
	}
	/*不用第三方变量,但如果a和b的值非常大,容易超出int范围*/
	public static void swap2(int a,int b){
		a=a+b;
		b=a-b;
		a=a-b;
	}
         /*使用用异或*/
	public static void swap3(int a,int b){
		a=a^b;
		b=a^b;
		a=a^b;
	}
}

10. 三元运算符,即条件表达式

变量=(条件表达式)?表达式1:表达式2,条件表达式为真时,变量取值为表达式1,为假时,变量取值为表达式2.

public class IFDemo{
      public static void main(String[] args){
                int x=1,y;
              y=(x>1)?’a’:200;// ‘a’与200作运算,’a’会自动提升为int
      }
}

这么多运算符,实际应用中往往是多个运算一块使用,因此运算符优先级和结合性就显得比较重要了,不明确这些,就不知道先算哪个再算哪个,下面通过一张表的形式来说明java所有这些运算符的优先级和结合性:

优先级
运算符
结合性
1
() [] .
从左到右
2
! +(正)  -(负) ~ ++ --
从右向左
3
* / %
从左向右
4
+(加) -(减)
从左向右
5
<< >> >>>
从左向右
6
< <= > >= instanceof
从左向右
7
==    !=
从左向右
8
&(按位与)
从左向右
9
^
从左向右
10
|
从左向右
11
&&
从左向右
12
||
从左向右
13
?:
从右向左
14
= += -= *= /= %= &= |= ^=  ~=  <<= >>=    >>>=
从右向左
 

------- android培训java培训、期待与您交流! --------



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值