Java中值类型和引用类型详解

 更新时间:2022年01月04日 09:26:20   作者:我是你bby  
大家好,本篇文章主要讲的是Java中值类型和引用类型详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览

我们都知道java是一种面向对象的编程语言,但是在实际意义上java并不是纯面向对象,因为面向对象的意义就是万物皆对象,那么如果说int类型的变量也是一个对象的话,那么我们应该能用"."这个东西访问到它的属性或者是方法,例如:

import java.util.ArrayList;
import java.util.List;
 
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.get(0);
    }
}

就好比是这样,我们把这个list这个对象看做一个变量,如果他是对象的话那么我们应该能够访问到它的属性和方法,但是在java中的基本数据类型是没属性和方法的,那么我们就可以说,只要点"."不出来东西的变量都是基本数据类型(于是就出现了包装类这种东西)。

关于java中的值类型和引用类型的方法传递问题

咱们先看看Java中的这些数据是怎么存储的

不知道兄弟们能不能理解,我在用语言描述一遍

在一个函数中两个基本类型的变量在声明了之后,将这两个变量作为参数传递给另一个方法,这个方法会复制两个副本,也就是说在swap(int, int)方法中交换的是两个副本的值,其真实的值并没有交换,那么就会有人想了,那用包装类啊,用引用类型的数据不就能交换了吗,咱么看一下: 

public class Test {
    public static void main(String[] args) {
        Integer n1 = 1, n2 = 2;
        System.out.println("交换前: num1: " + n1 + "\tnum2: " + n2);
        swap(n1, n2);
        System.out.println("交换后: num1: " + n1 + "\tnum2: " + n2);
    }
    public static void swap(Integer num1, Integer num2) {
       Integer temp = num1;
       num1 = num2;
       num2 = temp;
    }
}

这个结果是没有交换的,那么就会有人想了,这是怎么回事呢?

其实虽说是引用类型,但是在传参数的过程中,还是按照副本的方式传递的,只不过是将栈区中存储的地址作为副本进行交换,但是数据在堆中,并没有交换。

Oracle官方也说过,java是没有引用传递的,只有值类型的按值传递和引用类型的按值传递,说白了只有按值传递,是无他将引用进行传递的。但是C++中是有引用类型的,我们来看一段代码:

#include <iostream>
using namespace std;
 
int main(int agv, char** args)
{
	int num1 = 1, num2 = 2;
	cout << "交换前 " << "num1: " << num1 << "\tnum2: " << num2 << endl;
	swap(num1, num2);
	cout << "交换后 " << "num1: " << num1 << "\tnum2: " << num2 << endl;
}
 
void swap(int& num1, int& num2)
{
	int temp = num1;
	num2 = num1;
	num2 = temp;
}

结果显示为:

这个是C++中的引用类型传递,传递的参数确确实实是数据的引用

在C++中或者利用指针进行地址中的值交换操作也可以,只不过相对来说麻烦一些(其实这是在C中的操作)输出结果和上面的是一样的

#include <iostream>
using namespace std;
 
int main(int agv, char** args)
{
	int num1 = 1, num2 = 2;
	cout << "交换前 " << "num1: " << num1 << "\tnum2: " << num2 << endl;
	swap(num1, num2);
	cout << "交换后 " << "num1: " << num1 << "\tnum2: " << num2 << endl;
}
 
void swap(int* num1, int* num2)
{
	int temp = *num1;
	*num1 = *num2;
	*num2 = temp;

在C#中也有引用传递,需要用到关键字ref,代码如下

        static void Main(string[] args)
        {
            int num1 = 1, num2 = 2;
            Console.WriteLine("交换前: num1: {0}\tnum2: {1}", num1, num2);
            swap(ref num1, ref num2);
            Console.WriteLine("交换后: num1: {0}\tnum2: {1}", num1, num2);
            Console.ReadKey();
        }
 
        static void swap(ref int num1, ref int num2)
        {
            int temp = num1;
            num1 = num2;
            num2 = temp;
        }

输出结果为:

 确实也进行交换了

说了这么多都快跑题了,这时候可能就有人想  诶 明明标题是Java的标题,怎么说了这么一大堆其他语言的东西,马上了  不用着急

但是Java这两个功能没有怎么办呢?

我们可以用数组的方式,反正就是想法设法把堆中的数据进行交换,或者用返回值的方式,但是返回的话也只能返回一个数据(不像C#中能返回多个数据,有人就会想了,怎么java这么菜,啥啥干不了),但是事实就是如此,我们又能有什么办法。。。

    public static void main(String[] args) {
        int[] n1 = {1}, n2 = {2};
        System.out.println("交换前: num1: " + n1[0] + "\tnum2: " + n2[0]);
        swap(n1, n2);
        System.out.println("交换后: num1: " + n1[0] + "\tnum2: " + n2[0]);
    }
    public static void swap(int[] num1, int[] num2) {
        int temp = num1[0];
        num1[0] = num2[0];
        num2[0] = temp;
    }

所以咯,java只能这么进行交换了

到此这篇关于Java中值类型和引用类型详解的文章就介绍到这了,更多相关Java值类型和引用类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Spring Boot中Controller用法

    详解Spring Boot中Controller用法

    Controller是SpringBoot里最基本的组件,他的作用是把用户提交来的请求通过对URL的匹配,分配个不同的接收器,再进行处理,然后向用户返回结果。下面通过本文给大家介绍Spring Boot中Controller用法,需要的朋友参考下
    2017-05-05
  • SpringCloud 如何使用feign时的复杂参数传递

    SpringCloud 如何使用feign时的复杂参数传递

    这篇文章主要介绍了SpringCloud 如何使用feign时的复杂参数传递方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringBoot配置MongoDB多数据源的方法步骤

    SpringBoot配置MongoDB多数据源的方法步骤

    这篇文章主要介绍了SpringBoot配置MongoDB多数据源的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 使用Guava Cache原理及最佳实践

    使用Guava Cache原理及最佳实践

    文章介绍了GuavaCache,这是一种支持高并发的本地缓存,它支持多种回收策略,如基于容量、时间和引用的回收,并提供了自动加载、定时刷新和显式清除缓存的功能,文章还讨论了GuavaCache的适用场景和使用方法,并通过代码示例和源码分析,帮助读者更好地理解和使用GuavaCache
    2025-02-02
  • 在SpringBoot中配置日志级别和输出格式的教程详解

    在SpringBoot中配置日志级别和输出格式的教程详解

    在开发一个应用程序时,日志记录是非常重要的一环,SpringBoot提供了多种日志输出方式和配置选项,本文将介绍如何在SpringBoot应用程序中配置日志级别和输出格式,需要的朋友可以参考下
    2023-06-06
  • MyBatis-Plus 分页查询的实现示例

    MyBatis-Plus 分页查询的实现示例

    本文主要介绍了MyBatis-Plus 分页查询的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java日期处理工具类DateUtils详解

    Java日期处理工具类DateUtils详解

    这篇文章主要为大家详细介绍了Java日期处理工具类DateUtils的相关代码,包含日期和时间常用操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Flutter实现容器组件、图片组件 的代码

    Flutter实现容器组件、图片组件 的代码

    容器组件(Container)可以理解为在Android中的RelativeLayout或LinearLayout等,在其中你可以放置你想布局的元素控件,从而形成最终你想要的页面布局。这篇文章主要介绍了Flutter实现容器组件、图片组件 的代码,需要的朋友可以参考下
    2019-07-07
  • Java forEach对原数组的操作过程

    Java forEach对原数组的操作过程

    forEach对于基本数据类型,是直接赋值,对于引用数据类型,是引用地址值,forEach遍历时,是创建的临时变量,引用的数据地址,本文给大家介绍Java forEach对原数组的操作过程,感兴趣的朋友一起看看吧
    2024-02-02
  • Java Annotation(Java 注解)的实现代码

    Java Annotation(Java 注解)的实现代码

    本篇文章介绍了,Java Annotation(Java 注解)的实现代码。需要的朋友参考下
    2013-05-05

最新评论