Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别

文章目录

    • 基本数据类型的自动转换
    • 基本数据类型的强制转换
    • 包装类(封装类)
    • Integer类中的方法
      • 一:Number中的xxxValue()方法
      • 二:Integer.parseInt("String")方法
    • Integer中equals和==的区别
    • Interger加载时的源码分析

基本数据类型的自动转换


基本数据类型在计算的时候都会向数值范围大的方向转换

  • byte->short->int->long->float->double
  • 特别:一:所有的byte类型,short类型,char值,int类型在相互运算的时候都会变成int类型,int最大值为2,147,483,647
  • 二:int,float,double自身来进行计算的时候没有类型的提升,如果超出范围就会出现精度的损失
  • 三:基本数据类型在计算的时候,数值常量默认为int

【注意:数值范围较大和数据类型的字节数更多并不一定对应,比如float只有四个字节,long有八个字节,但是float表示的范围更大,这是因为它们的底层原理不同】

举例如下:
例一,所有的byte类型,short类型,char值,int类型在相互运算的时候都会变成int类型,数值常量默认为int

//数值常量默认为int
//所有的byte类型,short类型,char值,int类型在相互运算的时候都会变成int类型

public class Demo{
	public static void main(String[] args){
		byte b = 1; 
		byte b1 = b + 1; 
		//在等式的右边,b为byte类型,1 默认为int型,i + 1就会转化成int型,而int型是4个字节,
		//等式左边的b1是byte类型,一个字节,所以会报错(不兼容的类型: 从int转换到byte可能会有损失)
	}
} 

result:
在这里插入图片描述
将代码稍作修改:

public class Demo{
	public static void main(String[] args){
		byte b = 1; 
		int b1 = b + 1; //将b1的类型改为int型,就没问题了
	}
} 

例二,所有的byte类型,short类型,char值,int类型在相互运算的时候都会变成int类型:

///所有的byte类型,short类型,char值,int类型在相互运算的时候都会变成int类型

public class Demo{
	public static void main(String[] args){
		byte b = 1;
		byte b1 = 3;
		byte b3 = b + b1; //哪怕是两个byte之间进行运算也会转化成int,所以会报错
									//解决办法就是:把b3的类型改成int
	}
} 

result:
Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别_第1张图片

例三:

public class Demo{
	public static void main(String[] args){
		char c = 'a';
		int i = c + 1;
		System.out.println(i);//c的ASCII码是97,再加1,所以结果是98
	}
} 

result:
在这里插入图片描述

例四,int,float,double自身来进行计算的时候没有类型的提升,如果超出范围就会出现精度的损失:

public class Demo{
	public static void main(String[] args){
		int x = 2147483647;//int的最大值
		int y= 66;
		System.out.println(x+y);//结果超出int的范围,会显示一个错误数据
	}
} 

result:
在这里插入图片描述

给个题目来做一做:

public class Demo{            
	public static void main(String[] args){
		int x = 4;
		System.out.println("x is " + ((x > 4) ? 99.9 : 9)); //输出会是什么呢?
	}
} 

在这里插入图片描述
为什么输出是 9.0 而不是 9 ;这就涉及到上面所讲的基本数据类型的自动转化了,99.9 : 9这里的运算中,9 的类型提升了,从int变成了float

基本数据类型的强制转换


  • 小容量数据类型向大容量数据类型去转换(比如type向int转换),在运算中是自动转换的。

那么?怎么实现大容量数据类型向小容量数据类型去转换(比如int 向 type转换)而不报错呢?

基本数据类型强制转换的语法:(目标类型)值

举例:

public class Demo{
	public static void main(String[] args){
		byte b = 1;
		byte b1 = 2;
		//两个byte类型的数据进行四则运算时会自动转化为int
		byte b3 = b + b1;
	}
} 

会报错:
在这里插入图片描述
(目标类型)值

public class Demo{
	public static void main(String[] args){
		byte b = 1;
		byte b1 = 2;
		byte b3 =(byte)( b + b1); //就这么使用强制转换的语法就行了
	}
} 

注意:强制转换的存在意义是有前提的,大容量数据转换为小容量数据时,不会失去精度,才有转换的意义!

比如:

public class Demo{
	public static void main(String[] args){
		byte b = 1; //byte类型的最大值是127
		int b1 = 127;
		byte b3 =(byte)( b + b1); //很显然b+b1后的数超出了byte的可表示范围,再强制转换,得不到有意义的数
		System.out.println(b3);
	}
} 

在这里插入图片描述

包装类(封装类)


(补充一点:包装类现在没有那么常用了,因为jdk1.5版本之后,它产生了一个新的特性:自动拆装包【可以自动的把包拆成基本类型,也可以自动的把基本类型包装成包装类】)

java是一个完全的面向对象的编程语言,

而java中的8个基本数据类型却没有类的概念,

在我们眼中,包装类是基本类型和引用类型之间交换的桥梁

  • 基本数据类型 - 对应的包装类
  • byte - Byte
  • short - Short
  • int - Integer (最常用)
  • long - Long
  • float - Float (也很常用)
  • double - Double
  • char - Character
  • boolean - Boolean

  1. 八个包装类都在同一个包下java.lang包,所以它们不需要导包,可以直接用
  2. 八个包装类中有六个(Byte,Short,Integer,Long,Float,Double)是与数字相关,都默认继承父类Number
  3. 八个包装类都实现了这两个接口Serializable和Comparable
  4. 八个包装类都有带自己对应类型的构造方法
  5. 八个包装类中有七个(除了Character),还有构造方法重载,传String类型
  6. 创建对象,对象调用属性/方法

下面就以Integer来说明一下包装类吧:

Integer类中的方法

一:Number中的xxxValue()方法

八个包装类中有六个(Byte,Short,Integer,Long,Float,Double)是与数字相关,都默认继承父类Number

Number中有一种方法叫xxxValue(),例如:
Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别_第2张图片
这些(一个种类的)方法:将一个包装类型转化为对应的基本类型(拆包),这个知道一下就好,基本上没有什么用处

jdk1.5版本之前,包装类与基本数据类型的转化:

Integer i = new Integer(10); 包装
int value = i.intValue();    拆包

jdk1.5版本之后:

Integer i = 10;         自动包装
int value = new Integer(10);   自动拆包

二:Integer.parseInt(“String”)方法

将String转换成int有两种方法:

int value = Integer.parseInt("666");  将字符串直接转换成int

int value = new Integer("666");  先把String构成一个Integer对象,再自动拆成int

Integer中equals和==的区别

1.==equals()区别
2.==可以比较基本数据类型(变量中的值),也可以比较引用数据类型(变量中存储的地址引用)
3.equals()Object类中继承过来的方法,每一个引用类型都可以调用
4.默认继承的equals()比较与==一致,如果想要改变比较规则,我们可以重写equals()
5.但是Integer重写了equals(),所以Integer比较的是数值

public class Demo {

    public static void main(String[] args){
        Integer i1 = 10;
        Integer i2 = 10;
        Integer i3 = new Integer(10);
        Integer i4 = new Integer(10);

        System.out.println(i1 == i2);
        System.out.println(i1 == i3);
        System.out.println(i3 == i4);
        System.out.println(i1.equals(i2));
        System.out.println(i1.equals(i3));
        System.out.println(i3.equals(i4));
    }

}

result:
Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别_第3张图片
解析:

首先:==比较的是什么?equals()比的是什么?还要了解i1,i2,i3,i4它们四个在内存中的存储方式

 Integer i1 = 10;
 Integer i2 = 10;

---
 10自动包装成Integer对象
 这个对象存放在Integer对应的静态元素区里
 i1,i2都指向这个对象
Integer i3 = new Integer(10);

---
new就是堆内存产生新的空间,这个对象里面存了一个10      
i3指向这个新产生的空间 
 Integer i4 = new Integer(10);

---
new,又产生了一个新的对象,这个对象里面也存了一个10 
i4指向这个新的空间(不同于i3指向的空间)
==
比较的是变量空间里面存放的内容(都是地址)

System.out.println(i1 == i2); //true
System.out.println(i1 == i3);//false
System.out.println(i3 == i4);//false

equals()代码:

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

---    
equals()在包装类中被重写了,比较的不再是地址,而是值   

所以:

System.out.println(i1.equals(i2));//true
System.out.println(i1.equals(i3));//true
System.out.println(i3.equals(i4));//true

Interger加载时的源码分析

上面的题目代码全部不变,只把全部10改为1000,再输出,结果会有变化

public class Demo {

    public static void main(String[] args){
        Integer i1 = 1000;
        Integer i2 = 1000;
        Integer i3 = new Integer(1000);
        Integer i4 = new Integer(1000);

        System.out.println(i1 == i2);   很显然,这个输出变成了false,其余的没变
        System.out.println(i1 == i3);
        System.out.println(i3 == i4);
        System.out.println(i1.equals(i2));
        System.out.println(i1.equals(i3));
        System.out.println(i3.equals(i4));
    }

}

result:
Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别_第4张图片
为毛?

Integer i1 = 1000;
Integer i2 = 1000;
System.out.println(i1 == i2);   为什么这个输出变成了false呢?

还要研究Integer类加载的过程

Integer类有一个内部类的代码:

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

从这个代码可以看出:
Integer类加载的时候,自己有一个静态空间,空间内立即加载Integer类型的数组,数组内存储256个Integer对象,范围从 -127 ~ 128 ,如果我们用的对象范围在这之内(比如10),直接去静态区中找对应的对像;如果超出范围(比如1000),它会帮我们new出一个新对象

你可能感兴趣的:(#,Java小知识点)