Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)

简介: Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)

🛫 方法的参数传递机制是什么?

 方法的参数分为基本数据类型和引用数据类型,基本数据类型就是前面说过的四类八种,具体都有什么可以参考下面这篇博客的🛫 强制and自动类型转换都是啥?这个问题部分,在Java中除了这四类八种的基本数据类型之外都是引用数据类型


在答题之前先介绍一下相关概念


 参数传递机制的两个专业术语:按值调用 表示方法接收到的是调用者提供的值;按引用调用 表示方法接收到的是调用者提供的变量地址

 方法参数的两种形式:实参 就是方法调用的时候方法名后面的括号里的数据;形参 方法声明的时候方法名后面的括号里的数据,这就相当于一种局部变量,只在它定义的这个方法内部有效


🪂 基本数据类型作参数

 基本数据类型的参数采用按值调用的传递机制,也就是说方法调用的时候传过去的是一个值,但是实参并没有作为这个值传递过去,而是将实参的副本传递过去,方法中对形参的所有操作都是对实参副本的操作,并不会更改实参的实际值

image.png


🪂 引用数据类型作参数

 引用数据类型的参数也是采用按值调用的传递机制,也就是说方法调用的时候传过去的也是一个值,一个实参的副本

image.png 但是看上面代码的运行结果,许多小伙伴是不是就懵了,不是说传过去的是一个实参的副本嘛,为什么实参的结果值也互换了呢?别急,仔细想一想,数组是一个引用数据类型也就是说是一个对象,那么实参的arr是个什么?当然是这个数组对象的引用地址了,那么传递的副本也就是这个引用地址的副本,形参按照这个引用地址的副本对数组进行操作,当然也就按照地址操作了实参所对应的对象的值了。这么一来是不就是可以解释的通了


 综上所述,Java中方法的参数传递机制只有按值调用,并没有按引用调用


🛫 关于包装类你都知道什么?

🪂 包装类基本知识

数据类型 包装类 储存空间(byte) 大小

byte Byte 1字节 8位

short Short 2字节 16位

int Integer 4字节 32位

long Long 8字节 64位

float Float 4字节 32位

double Double 8字节 64位

char Character 2字节 16位

boolean Boolean 1字节 8位

🚩每一个基本数据类型都有一个对应的包装类,前六个类派生于公共的超类Number

🚩包装类是不可变的,也即是说一旦构造了包装器,就不允许更改它的值,与此同时包装类还是final修饰的,因此不能派生他们的子类

🚩泛型也必须声明成包装类型,而不能使用基本数据类型

🚩包装类的值比较需要使用equals方法,而不是==判断


🪂 什么是装箱和拆箱?

 Java主张一切皆对象的思想,但是基本数据类型并不是对象,于是就有了包装类的概念。其中装箱就是将一个基本数据类型包装成其对应的包装类,拆箱就是反过来将包装类拆成对应的基本数据类型数据。根据转换时是否使用方法,装箱又称为自动拆装箱和手动拆装箱


 手动装箱有两种方式:使用包装类构造器、包装类的valueOf方法;手动拆箱有一种:包装类的xxxValue方法。但是Java提供了自动拆装箱,如果二者相互复赋值的话就会自动转换而无需使用方法进行转换,且使用泛型定义的集合添加基本数据类型的时候也会自动装箱为对应的包装类型


🚩装箱和拆箱是编译器的工作

image.png

🪂 包装类cache缓存机制

 从Java5开始,包装类新增了自动拆、装箱的功能,除此之外还新增了cache缓存机制,该机制会将取值在一定范围内的值创建成相应的对象缓存起来,这些缓存起来的对象在以后使用到的时候就可以直接用,这样就可以避免在这个范围内的值重复创建造成的内存损耗从而降低性能。为了更好的了解这个机制,让我们看一下接下来的这段代码写下自己的答案,然后结合cache机制的解释再推测一下答案,最终结果在后面给出  

image.png这里通过源码(下面给出),以Integer为例来了解一下包装类的cache缓存机制,Integer类中有一个IntegerCache类,这个类的主要作用即就是创建[-128,127]之间的所有对象并添加到cache数组中,等到调用valueOf方法的时候就使用if判断是不是在范围内,如果在的话就直接在cache数组中直接返回,反之就使用构造器创建一个对应的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 =
            sun.misc.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() {}
}
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
相关文章
|
5天前
|
Java
Java如何标记异步方法
【8月更文挑战第13天】Java如何标记异步方法
14 1
|
5天前
|
Java
【Java】Math、System、RunTime、BigDecimal类常用方法
【Java】Math、System、RunTime、BigDecimal类常用方法
|
23小时前
|
存储 Java
|
2天前
|
存储 SQL 关系型数据库
深入MySQL锁机制:原理、死锁解决及Java防范技巧
深入MySQL锁机制:原理、死锁解决及Java防范技巧
|
5天前
|
前端开发 Java
【前端学java】java中的包装类(12)
【8月更文挑战第10天】java中的包装类
7 1
|
1天前
|
存储 Java
|
4天前
|
Java API
Java8 Lambda 设计和实现问题之在Java 8的Stream API中,parallel=false时collect方法是如何实现的
Java8 Lambda 设计和实现问题之在Java 8的Stream API中,parallel=false时collect方法是如何实现的
|
4天前
|
Java 数据库连接 API
Java 的 SPI 机制
Java 的 SPI 机制
9 0
|
4天前
|
Java Spring 容器
Java SpringBoot 中,动态执行 bean 对象中的方法
Java SpringBoot 中,动态执行 bean 对象中的方法
13 0
|
5天前
|
Java API
【Java】Object、Objects、包装类、StringBuilder、StringJoiner
【Java】Object、Objects、包装类、StringBuilder、StringJoiner