Java中值类型和引用类型详解
作者:我是你bby 发布时间:2023-11-29 00:44:51
我们都知道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只能这么进行交换了
来源:https://blog.csdn.net/m0_58015306/article/details/122287532


猜你喜欢
- 手势操作可以说是智能手机的一种魅力所在,前两节给大家讲解了两种有趣的手势操作,
- 今天在做数据分页显示的时候遇到了一个问题,经过测试,证实是Tomcat 6的一个bug,我所用的版本为:apache-tomcat-6.0.
- 泛型中 T 类型变量 和 ? 通配符 区别定义不同 :T 是类型变量,? 是通配符使用范围不同:? 通配符用作 参数类型、字段类型、局部变量
- 前言对于 InterruptedException,一种常见的处理方式是 “生吞(swallow)” 它 —— 捕捉它,然后什么也不做(或者
- 一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net、NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵
- 支持趋势线的图表类型包括二维面积图、条形图、柱形图、柱形图、股价图、xy (散点图) 和气泡图中;不能向三维、堆积、雷达图、饼图、曲面图或圆
- 代码一:class Program { static int
- Java NIO(New IO)是Java 1.4版本中引入的一套全新的IO处理机制,与之前的传统IO相比,NIO具有更高的可扩展性和灵活性
- 一、简介地图控件自v2.3.5版本起,支持多实例,即开发者可以在一个页面中建立多个地图对象,并且针对这些对象分别操作且不会产生相互干扰。文件
- java中的线程状态🥇在操作系统层面,一个线程就两个状态:就绪和阻塞状态.但是java中为了在线程阻塞时能够更快速的知晓一个线程阻塞的原因,
- Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日
- Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean(本文),还可以是带有泛型的
- 相信不少喜欢开发的朋友都已经知道微信小程序是个什么物种了,楼主也是从小程序内测期间就开始关注,并且也写过几个已经上线的微信小程序。但是基本上
- 本文实例为大家分享了Android实现简单垂直进度条的具体代码,供大家参考,具体内容如下代码注释特别清晰,就不多解释了支持属性:progre
- 从Handler.post()说起Handler.post()是用来发送消息的,我们看下Handler源码的处理:public final
- 引言在平时的工作中多多少少都会接触到注册中心,当你的应用从单机到拆分成多个服务,每个服务又有多个实例的情况时,那么对服务IP地址管理的要求就
- 概述Android开发过程中,经常遇到 Textview 展示不完全的情况。遇到此情况,通常的处理是:方案一 Textview 添加 and
- maven打包指定jdk的版本问题今天遇到个问题,项目中新写了一个接口,其中用到了lambda表达式,本地跑是没问题的,但提交到gitLab
- 看过阿里巴巴开发手册的同学应该都会对Integer临界值127有点印象。原文中写的是:【强制】所有整型包装类对象之间值的比较,全部使用 eq
- 安装容易出现的问题以及解决方法:1、更新sdk时可能无法连接服务器,可在C:\WINDOWS\system32\drivers\etc下的h