您的位置:首页 > 编程语言 > Java开发

Java基本数据类型的比较

2018-03-27 18:51 375 查看
int 是在栈里创建的,Integer是在堆里创建的。栈里创建的变量要比在堆创建的速度快得多

== 可以比较基本数据类型 , 也可以比较引用数据类型  
equals: 只能比较引用数据类型, 默认比较的是地址值*(string类中重写了eqals方法),如果我们想建立自己的比较方式, 需要重写equals方法
通过对比字符串比较来理解,基本类型100通过包装类Integer包装后生产一个Integer对象的引用a,
而“==”使用来判断两个操作数是否有相等关系。如果是基本类型就直接判断其值是否相等。
若是对象就判断是否是同一个对象的引用,显然我们new了两个不同的对象。
但注意:对于"<",">" 只是用来判断两个基本类型的数值的大小关系。在进行(a<b)运算时,
实际上是根据其intValue方法的返回对应的数值来进行比较的。因此返回肯定是false.

一、byte, short, int, long四种基本数据类型以及其包装类的比较:
int i =50;
Integer i1 =50;
Integer i2 =50;
Integer i3 = new Integer(50);
Integer i4 = new Integer(50);
Integer i5 = 300;
Integer i6 = 300;
System.out.println(i == i1);// true;i1自动拆箱变成基本类型,两基本类型比较值
System.out.println(i == i3);// true; i3自动拆箱变成基本类型,两基本类型比较值
System.out.println(i1 == i2);// true; i1和i3都指向常量池中同一个地址
System.out.println(i1 == i3);// false; 两个不同的对象
System.out.println(i3 == i4);// false; 两个不同的对象
System.out.println(i5 == i6);// false; 自动装箱时,如果值不在-128到127,就会创建一个新的对象结论:
    1.基本数据类型与其对应的包装类运算或比较时,会自动拆箱成基本数据类型;
    2.在自动装装箱时,会先检查其值是否在-128到127之间,如果在这之间,就会直接指向常量池中其值的地址;
    3.只要是new得到的一定是对象,存在堆内存中;
    4.同时byte, short, long也具有该特性。
原因:JVM做的一些一些优化,将常用的基本数据类型在程序运行时就创建加载在常量池中。

二、double, float类型的不同:
Float f1 = 100f;
Float f2 = 100f;
Float f3 = 300f;
Float f4 = 300f;
System.out.println(f1 == f2);// false
System.out.println(f3 == f4);// false
结论:float,double类型的包装类,都会在堆中创建一个新对象,因此比较的是对象的地址

建议27:谨慎包装类型的大小比较基本数据类型比较大小木有问题,不过其对应的包装类型大小比较就需要注意了。看如下代码:public class Client {
public static void main(String[] args) {
Integer a = new Integer(100);
Integer b = new Integer(100);
/* compareTo返回值:若a>b则返回1;若a==b则返回0;若a<b则返回-1 */
int result = a.compareTo(b);
System.out.println(result);
System.out.println(a > b);
System.out.println(a == b);
}
}
运行结果:
0
false
false
为什么(a==b)返回值会是false呢?通过对比字符串比较来理解,基本类型100通过包装类Integer包装后生产一个Integer对象的引用a,
而“==”使用来判断两个操作数是否有相等关系。如果是基本类型就直接判断其值是否相等。
若是对象就判断是否是同一个对象的引用,显然我们new了两个不同的对象。
但注意:
对于"<",">" 只是用来判断两个基本类型的数值的大小关系。在进行(a<b)运算时,实际上是根据其intValue方法的返回对应的数值来进行比较的。因此返回肯定是false.知道问题原因,解决起来就容易了。两种方法:
第一种: a.intValue()==b.intValue();
第二种: a.compareTo(b);//返回-1代码(a<b),返回0代表(a==b),返回1代表(a>b)
第二种方法源码如下:
1 public int compareTo(Integer object) {
2     int thisValue = value;
3     int thatValue = object.value;
4     return thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1);
5 }
由此可知,底层实现还是一样的。总结:1.如果Integer类型的两个数相等,如果范围在-128~127(默认),那么用“==”返回true,其余的范会false。java中Integer类型对于-128-127之间的数是缓冲区取的,所以用等号比较是一致的。但对于不在这区间的数字是在堆中new出来的。所以地址空间不一样,也就不相等。其实java在编译Integer i5 = 127的时候,被翻译成-> Integer i5 = Integer.valueOf(127);所以关键就是看valueOf()函数了。只要看看valueOf()函数的源码就会明白了。JDK源码的valueOf函数式这样的:
[java] view plain copypublic static Integer valueOf(int i) {  
        assert IntegerCache.high >= 127;  
       if (i >= IntegerCache.low && i <= IntegerCache.high)  
           return IntegerCache.cache[i + (-IntegerCache.low)];  
       return new Integer(i);  
   }  
     看一下源码大家都会明白,对于-128到127之间的数,会进行缓存,Integer i5 = 127时,会将127进行缓存,下次再写Integer i6 = 127时,就会直接从缓存中取,就不会new了2.两个基本类型int进行相等比较,直接用==即可。3.一个基本类型int和一个包装类型Integer比较,用==也可,比较时候,Integer类型做了拆箱操作。4.Integer类型比较大小,要么调用Integer.intValue()转为基本类型用“==”比较,要么直接用equals比较。
 ①无论如何,Integer与new Integer不会相等。不会经历拆箱过程,i7的引用指向堆,而new Integer()指向专门存放他的内存(常量池),他们的内存地址不一样,所以为false(如L24)。       ②两个都是非new出来的Integer,如果数在-128到127之间,则是true(如L18),否则为false(如L18)。java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存。       ③两个都是new出来的,都为false(如L27)。      ④int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比(如L13、L14)

最好是同类型之间的比较 否则会有问题

Java 基本数据类型

变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。

因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。Java 的两大数据类型:内置数据类型
引用数据类型
byte:
byte 数据类型是8位、有符号的,以二进制补码表示的整数;
最小值是 -128(-2^7),最大值是 127(2^7-1),默认值是 0
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
例子:byte a = 100,byte b = -50。

short:
short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15),最大值是 32767(2^15 - 1),默认值是 0;
Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
例子:short s = 1000,short r = -20000。

int:
int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31),最大值是 2,147,483,647(2^31 - 1),默认值是 0 ;
一般地整型变量默认为 int 类型;
例子:int a = 100000, int b = -200000。

long:
long 数据类型是 64 位、有符号的以二进制补码表示的整数;
最小值是 -9,223,372,036,854,775,808(-2^63),最大值是 9,223,372,036,854,775,807(2^63 -1),默认值是 0L;
这种类型主要使用在需要比较大整数的系统上;定义long类型的变量的时候,需要对该数添加一个标志使用: L或者l
例子: long a = 100000L,Long b = -200000L。(如果值在int范围内 后缀也可以不加)
"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

float:
float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;定义float类型的变量的时候,需要对该数添加一个标志使用: F或者f
默认值是 0.0f;
浮点数不能用来表示精确的值,如货币;
例子:float f1 = 234.5f。

double:
double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
浮点数的默认类型为double类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d;
例子:double d1 = 123.4。

boolean:
boolean数据类型表示一位的信息;
只有两个取值:true 和 false;
这种类型只作为一种标志来记录 true/false 情况,默认值是 false;
例子:boolean one = true。

char:
char类型是一个单一的 16 位 Unicode 字符;
最小值是 \u0000(即为0);
最大值是 \uffff(即为65,535);
char 数据类型可以储存任何字符;
例子:char letter = 'A';。
整数默认是int类型,浮点数默认是double类型

自动类型转换
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级。
低  ------------------------------------>  高
byte,short,char—> int —> long—> float —> double 
byte,short,char之间不转换,他们参与运算自动转成int

数据类型转换必须满足如下规则:
1. 不能对boolean类型进行类型转换。
2. 不能把对象类型转换成不相关类的对象。
3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
4. 转换过程中可能导致溢出或损失精度,例如:
int i =128;   
byte b = (byte)i;
因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
5. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
(int)23.7 == 23;        
(int)-45.89f == -45

自动类型转换

必须满足转换前的数据类型的位数要低于转换后的数据类型,例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。
public class ZiDongLeiZhuan{
public static void main(String[] args){
char c1='a';//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于"+i1);
char c2 = 'A';//定义一个char类型
int i2 = c2+1;//char 类型和 int 类型计算
System.out.println("char类型和int计算后的值等于"+i2);
}
}
char自动类型转换为int后的值等于97
char类型和int计算后的值等于66
解析:c1的值为字符'a',查ascii码表可知对应的int类型值为97,'A'对应值为65,所以i2=65+1=66。

强制类型转换

1. 条件是转换的数据类型必须是兼容的,强制转换不会报错 但是会损失精度。
2. 格式:(type)value type是要强制类型转换后的数据类型 实例:

实例

int i1 = 123; byte b = (byte)i1;//强制类型转换为byte System.out.println("int强制类型转换为byte后的值等于"+b); }}运行结果:int强制类型转换为byte后的值等于123

隐含强制类型转换

1. 整数的默认类型是 int。
2. 浮点型不存在这种情况,因为在定义 float 类型时必须在数字后面跟上 F 或者 f。

// java中的常量优化机制: 编译器会对其做一个处理,计算出3+4的值,然后判断这个值有没有在byte范围内,如果在就不报错,如果不在就报错了.
byte b4 = 3 + 4;
System.out.println(b4);

               Byte aByte=null;
System.out.println( aByte== new Integer(1 ).byteValue() ); //null 和基本类型比较会包空指针
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: