【Java】基本数据类型与包装类

数据类型

  • Java的数据类型分为:基本类型、引用类型。
  • String是引用类型,是lang包下的类。
    在这里插入图片描述

1、基本数据类型

  • Java 中有 8 种基本数据类型。

4 种整数型:byte、short、int、long
2 种浮点型:float、double
1 种字符类型:char
1 种布尔型:boolean

  • Java数据类型所占存储空间大小与机器硬件结构无关,可移植性更高。
基本数据类型字节数包装类
布尔型boolean1Boolean
字符型char2Character
整型byte1Byte
整型short2Short
整型int4Integer
整型long8Long
浮点型float4Float
浮点型double8Double

2、包装类

  • 包装类将基本数据类型包装转化为类的形式,具有面向对象的特征。
  • Java集合中只能放入包装类型,而不支持基本类型。
  • Java类型间的转换可以通过包装类的方法实现,基本数据类型没有类的属性方法。
  • 所有整型包装类对象之间的比较,全部使用 equals 方法比较。

对于 Integer var 在-128 至 127 之间的赋值,Integer 对象是在 IntegerCache.cache 产生, 会复用已有对象,这个区间内的Integer 值可以直接使用==进行判断.
但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,使用 equals 方法进行判断。

3、基本类型和包装类型的区别

  • 默认值:包装类型不赋值就是 null ,基本类型有默认值且不是 null。
  • 包装类型可用于泛型,而基本类型不可以。
  • 包装类型属于对象类型,几乎所有对象实例都存在于堆中。
  • 基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中。
  • 基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。

4、包装类型的缓存机制

  • 包装类型的大部分都用到了缓存机制来提升性能:节省创建对象的时间开销。对象可以自由共享。
  • Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据。
  • Character 创建了数值在 [0,127] 范围的缓存数据。
  • Boolean 直接返回 True or False。
  • Float,Double 并没有实现缓存机制。
  • 如果超出对应范围会创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。
  • 包装器类提供了对象的缓存,String类提供了常量池,都有final修饰,对象一经创建后不可修改。

5、equals() 和 ==

==

  • 对于基本数据类型来说,== 比较的是值。
  • 对于引用数据类型来说,== 比较的是对象的内存地址。
  • == 运行速度比equals()快,因为==只是比较引用。

equals()

  • equals() 不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。
  • equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,因此所有的类都有equals()方法。
  • 如果类没有重写 equals()方法:等价于通过“==”比较这两个对象,使用的默认是 Object类equals()方法。是否为同一内存地址。
  • 如果类重写了 equals()方法 :一般会重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。
  • String 中的 equals 方法是被重写过的,比较的是对象的值。
    当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
System.out.println(aa == bb);// true
System.out.println(a == b);// false
System.out.println(a.equals(b));// true
System.out.println(42 == 42.0);// true

6、自动装箱拆箱

  • 装箱:将基本类型用它们对应的引用类型包装起来;调用了包装类的valueOf()方法。
  • 拆箱:将包装类型转换为基本数据类型;调用了 intValue()方法。
  • 如果频繁拆装箱的话,也会严重影响系统的性能。应该尽量避免不必要的拆装箱操作。
public static void WrapTest1() {
    // 自动装箱,等效于 Integer num = Integer.valueOf(100);
    Integer num = 100; 
    // 自动拆箱,等效于 int num2 = num.intValue();
    int num2 = num; 

    // valueOf() 方法返回对应包装类实例
    System.out.println("-----valueOf()-----");
    Integer a =Integer.valueOf(9);     // 将int转为Integer包装类对象
    Double b = Double.valueOf(5);
    Float c = Float.valueOf("80");     // 将字符串转为Float包装类对象
    Integer d = Integer.valueOf("444",16);   // 使用 16 进制 
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    System.out.println(d);
}
结果:
-----valueOf()-----
9
5.0
80.0
1092

7、浮点数精度丢失

  • 浮点数运算的时候会有精度丢失的风险。计算机使用有限的宽度表示一个数字,无限循环的小数存储在计算机时,只能被截断。
  • BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。
  • BigInteger 内部使用 int[] 数组来存储任意大小的整形数据。

8、代码

// 大小与范围
public static void WrapTest0() {
    // byte
    System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);
    System.out.println("包装类:java.lang.Byte");
    System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);
    System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);
    System.out.println();
    // char 单一的 16 位 Unicode 字符;
    System.out.println("基本类型:char 二进制位数:" + Character.SIZE);
    System.out.println("包装类:java.lang.Character");
    // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台 \u0000(十进制等效值为 0);
    System.out.println("最小值:Character.MIN_VALUE=" + (int) Character.MIN_VALUE);
    // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台 \uffff(即为 65535);
    System.out.println("最大值:Character.MAX_VALUE=" + (int) Character.MAX_VALUE);
}
结果:
基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127

基本类型:char 二进制位数:16
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535    
public static void WrapTest2() {
    System.out.println("-----缓存池范围-----");
    Integer a = 100, b = 100;
    System.out.println(a == b);         //true  // 比较引用地址相同,缓存池中为同一对象
    System.out.println(a.equals(b));    //true  // 比较对象内容相等

    Long c = 145L, d = 145L;
    System.out.println(c == d);         //false // 比较引用地址不同,超出缓存池范围重新new了不同对象
    System.out.println(c.equals(d));    //true  // 比较对象内容相等
    System.out.println(c.intValue() == d.intValue()); // true

    System.out.println("-----不同包装类对象-----");
    Integer i = 130;
    Long j = 130L;
    System.out.println(i.equals(j));    //false  // equals()会先判断包装类型,若j是不同类型,直接false
                                                 // 不同包装类对象不能用==比较
    System.out.println("-----不同基本数据类型-----");
    int m = 100;
    long n = 100L;
    System.out.println(m == n);         //true  // 基本数据类型没有缓存池的概念,用 == 比较
    int M = 150;
    long N = 150L;
    double O = 150.0;
    System.out.println(M == N);         //true  // 基本数据类型 ==比较,都指向相同堆地址
    System.out.println(M == O);         //true  

    System.out.println("-----包装类和基本数据类型-----");
    Long x = 145L;
    long y = 145l;
    System.out.println(x == y);         //true //  == 会自动拆箱
    System.out.println(x.equals(y));    //true // 自动装箱
    
    int z = 145;
    System.out.println(x == z);         //true //  == 会自动拆箱x 为long
    System.out.println(x.equals(z));    //false // equals()自动装箱z 为Integer, 不同包装类对象用equals()比较直接false
    
	Integer i1 = 40; // 缓存中的对象
	Integer i2 = new Integer(40);  // 创建新的对象
	System.out.println(i1==i2);  // false
}
// 基本数据类型与字符串的转换
public static void WrapTest3() {
    // 基本数据类型转换为String
    String str1 = String.valueOf(111);
    String str2 = 222 + "";
    String str3 = Integer.toString(333);
    // 字符串转换成基本数据类型
    int a = Integer.parseInt("111");

    // 字符串转换成包装类
    Integer b = Integer.valueOf("222");
    // 包装类型转换为字符串类型
    String str4 = String.valueOf(Integer.valueOf(444));
}
public static void intTest() {
    System.out.println(5/2);

    double x = 1.0 / 10;
    double y = 1 - 9.0 / 10;
    System.out.println(x);
    System.out.println(y);

    // 四舍五入
    double d = 2.6;
    int n = (int) (d + 0.5);
    System.out.println(n);

    double e = 2.4;
    int m = (int) (e + 0.5);
    System.out.println(m);

    char c3 = '\u0041';
    System.out.println(c3);

    double d = 12900000;
    System.out.println(d);

    double e = 3.1415926;
    System.out.printf("%.2f\n", e);
    System.out.printf("%.4f\n", e);

    int n = 12345000;
    System.out.printf("n=%d, hex=%08x \n", n, n);
    System.out.printf("%%%d", n);
}


参考
https://tobebetterjavaer.com/basic-grammar/basic-data-type.html#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%88%86%E7%B1%BB
https://javaguide.cn/java/basis/java-basic-questions-01.html#%E8%87%AA%E5%8A%A8%E8%A3%85%E7%AE%B1%E4%B8%8E%E6%8B%86%E7%AE%B1%E4%BA%86%E8%A7%A3%E5%90%97-%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java基本数据类型包装类是Java中用来表示数据的两种不同方式。 1. 基本数据类型(Primitive Data Types): - Java基本数据类型有8种:byte、short、int、long、float、double、char和boolean。 - 这些基本数据类型直接存储着数据的值,它们是直接操作内存的,因此效率较高。 - 基本数据类型不具有任何方法,不能调用任何方法。 2. 包装类(Wrapper Classes): - 包装类是用来将基本数据类型包装起来,以便能够以对象的形式使用。 - Java提供了对应于每种基本数据类型包装类:Byte、Short、Integer、Long、Float、Double、Character和Boolean。 - 包装类提供了许多有用的方法,可以进行类型转换、比较、运算等操作。 - 包装类是不可变的(immutable),即一旦创建就无法修改其值。 区别: - 基本数据类型是直接存储数据的值,而包装类是将基本数据类型包装成对象。 - 基本数据类型效率较高,而包装类的效率较低,因为需要进行对象的创建和销毁操作。 - 基本数据类型不能调用任何方法,而包装类提供了许多有用的方法。 - 包装类可以用于泛型、集合类等需要对象作为参数的场景,而基本数据类型则不能直接使用。 - 基本数据类型在内存中占据的空间大小是固定的,而包装类的内存消耗较大,因为需要额外存储一些信息。 总的来说,基本数据类型适合用于简单的数据操作,而包装类适合用于需要更多功能和灵活性的场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值