五分钟学会java中的基础类型封装类

简介: 在刚刚学习java的时候,老师不止一次的说过java是一种面向对象的语言,万物皆对象。对于java中的基础数据类型,由于为了符合java中面向对象的特点,同样也有其封装类。这篇文章对其有一个认识。

一、基本认识


其实在jdk1.5之前,在基础数据类型与其封装器之间的转化必须手动进行,但是从jdk1.5之后,由于提供了自动装箱的机制,因此我们不再手动进行了。

装箱:基础类型转封装类型。Integer a = 3底层实现:Integer a = Integer.valueOf(3);拆箱:封装类型转基础类型。int b = a;底层实现:int b = a.intValue();

既然封装类能够封装基础类型,那么能封装的范围是多少呢?


基本类型封装器字节数最大值最小值byteByte1byte2^7 - 1-2^7shortShort2byte2^15 - 1-2^15charCharacter2byte2^16 - 10intInteger4byte2^31 - 1-2^31longLong8byte2^63 - 1-2^63floatFloat4byte3.4e+381.4e-45doubleDouble8byte1.8e+3084.9e-324booleanBoolean1byte/4byte/不明确--


我们对其进行了一个总结。不过我们应该注意到boolean类型没有给出精确的定义,可能是一个字节也有可能是四个字节,这是为什么呢?java虚拟机规范中规定的是4个字节,但是不同的厂家虚拟机可能不同,所以可能不会按照规范来。


以上这张图想必我们都不陌生,每一种基础类型都有一个唯一的封装类。而且也给出了字节数、最大值最小值等。下面我们就看一下其基本使用:

public class Test{
    public static void main(String[] args) {
        Integer int_a= new Integer(3);
        int int_b=  int_a;//自动完成了拆箱
        char char_a = new Character('a');
        char char_b = char_a;//自动完成了拆箱
        //其他类似
    }
}


二、基础类型与封装类的区别


1、传递方式不同


基本类型是按值传递,而封装类型是按引用传递的。int是基本类型,直接存放数值;Integer类会产生一个对象引用指向这个对象。


2、存储位置不同


基本类型存储在栈中,封装类的引用存储在栈中,而值是存在堆中。这样看上去好像基础封装类多此一举,而且基本类型的速度也确实会比封装类更快。为什么快呢?这是因为封装类涉及到了对象内存的分配和垃圾回收。但是基本类型直接拿起来就计算了。


三、源码分析


在讲解源码之前我们先给出一个神奇的例子,请看下面的代码:

public class Test{
    public static void main(String[] args) {
        //这种情况会返回true
        Integer a1 = 10;
        Integer a2 = 10;
        System.out.println(a1 == a2); 
        //这种情况会返回false?????
        Integer b1 = 1000;
        Integer b2 = 1000;
        System.out.println(b1 == b2); 
    }
}

第一种情况感觉和第二种情况一模一样呀,为什么第二种是false呢?想要知道原因,我们就必须要深入到源码中找寻答案。

public static Integer valueOf(int i) {
    // i是否在表示范围[-128, 127]中
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
        // 如果在直接取出
        return IntegerCache.cache[i + (-IntegerCache.low)];
    // 如果不在,则创建一个新的
    return new Integer(i);
}

也就是说,在合理表示范围之内就直接拿出来一个旧的数据,如果不在表示范围之内那就创建一个新的。但是对于源码的了解不能仅限于此。我们还是按部就班的分析,下面我们以Integer封装类为例。


1、参数


//最小值::-2147483648
//其实也就是2的10次方,然后取负
@Native public static final int   MIN_VALUE = 0x80000000;
//最大值
//其实也就是2的10次方
@Native public static final int   MAX_VALUE = 0x7fffffff;


2、方法


//方法1:将字符串参数解析为有符号的整数
//第二个参数指定基数
public static int parseInt(String s, int radix) ;
//方法2:类型转换,并给出其中一个例子
public byte byteValue(){
    return (byte) value;
}
public short shortValue()
public int intValue()
public long longValue()
public float floatValue()
public double doubleValue()
//方法3:求a和b的和
public static int sum(int a, int b)
//方法4:求最大最小值
public static int max(int a, int b){
    return Math.max(a, b);
}
public static int min(int a, int b){
    return Math.min(a, b);
}


3、缓存


上面支持给出了一些基本的使用方法,不过最核心的还是缓存范围的实现。下面我们看一下:

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
            assert IntegerCache.high >= 127;
        }
        private IntegerCache() {}
    }

上面这些代码能看懂最好,看不懂我来描述一下大概意思:这是一个静态内部类,类中定义一个静态cache数组,这个静态数组预先放了自己指定范围内的数据,拆箱的时候首先判断范围然后从缓存数组中去抓取数据。就是这么一个简单的过程。


四、使用场景


上面分析了这么多,最主要的还是如何使用,在什么地方使用。下面我们就总结几个场景:


1、类型之间的转换:


String b = "123"; 
int c = Integer.parseInt(b); 
//如果b中含有非法字符,则会报错
NumberFormatException


2、泛型中使用

List<>为原始类型,不指定元素类型时,会出现不安全的警告:

List is a raw type. References to generic type List should be parameterized

大概意思就是:List的<>中应该指定清楚是那种类型,如Integer、String等。


3、强制类型转换


4、集合中使用


public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>(2);
    list.add(1);
    list.add(null);
    for (int value:list){
        System.out.println("value:"+value);
    }
}

这种情况下会出现空指针异常。

OK。今天的文章先到这里,如有问题还请批评指正。

目录
打赏
0
0
0
0
26
分享
相关文章
java变量与数据类型:整型、浮点型与字符类型
### Java数据类型全景表简介 本文详细介绍了Java的基本数据类型和引用数据类型,涵盖每种类型的存储空间、默认值、取值范围及使用场景。特别强调了`byte`、`int`、`long`、`float`、`double`等基本类型在不同应用场景中的选择与优化,如文件流处理、金融计算等。引用数据类型部分则解析了`String`、数组、类对象、接口和枚举的内存分配机制。
32 14
|
3天前
|
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
课时11:综合实战:简单Java类
本次分享的主题是综合实战:简单 Java 类。主要分为两个部分: 1.简单 Java 类的含义 2.简单 Java 类的开发
|
4天前
|
课时11:Java数据类型划分(浮点类型)
课时11介绍了Java中的浮点数据类型。主要内容包括:1. 定义小数,默认使用Double类型;2. 定义Float变量,需在数值后加&quot;F&quot;或&quot;f&quot;进行强制转换;3. 观察不同类型计算结果,如Int型除法会丢失精度,需至少包含一个Double或Float类型以确保准确性。总结指出,在复杂计算中推荐使用Double类型以避免精度损失。
|
4天前
|
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
21 5
|
4天前
|
课时10:Java数据类型划分(整型类型)
本文主要围绕Java中整型数据展开,详细讲解整型变量、常量的概念,整型数据运算规则,包括数据溢出问题及解决方法,数据类型转换(自动转换与强制转换)的原理和注意事项,同时介绍了整型数据默认值的相关知识,以及byte数据类型与int数据类型的关系和使用场景,帮助读者全面掌握Java整型数据的相关内容。
课时37:综合实战:数据表与简单Java类映射转换
今天我分享的是数据表与简单 Java 类映射转换,主要分为以下四部分。 1. 映射关系基础 2. 映射步骤方法 3. 项目对象配置 4. 数据获取与调试
JAVA泛型类的使用(二)
接上一篇继续介绍Java泛型的高级特性。3. **编译时类型检查**:尽管运行时发生类型擦除,编译器会在编译阶段进行严格类型检查,并允许通过`extends`关键字对类型参数进行约束,确保类型安全。4. **桥方法**:为保证多态性,编译器会生成桥方法以处理类型擦除带来的问题。5. **运行时获取泛型信息**:虽然泛型信息在运行时被擦除,但可通过反射机制部分恢复这些信息,例如使用`ParameterizedType`来获取泛型参数的实际类型。
JAVA泛型类的使用(一)
Java 泛型类是 JDK 5.0 引入的重要特性,提供编译时类型安全检测,增强代码可读性和可维护性。通过定义泛型类如 `Box&lt;T&gt;`,允许使用类型参数。其核心原理是类型擦除,即编译时将泛型类型替换为边界类型(通常是 Object),确保与旧版本兼容并优化性能。例如,`Box&lt;T&gt;` 编译后变为 `Box&lt;Object&gt;`,从而实现无缝交互和减少内存开销。
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
180 4

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等