java通过方法来交换实参的值实现方式

 更新时间:2025年12月26日 09:21:26   作者:月下清融析愿  
文章介绍了Java方法参数传递方式以及如何通过数组、自定义包装类或返回结果来实现变量交换,同时,讨论了内部类中static关键字的作用和使用场景

一、代码实例引出

代码输出结果:

我们可以看到,尽管我们写了一个交换方法来交换a与b的值,但是从结果来看好像没有发生交换,这是为什么?如何修改才能使其发生交换?有几种方法能够做到?这就是今天要做的事情

二、为什么无法发生交换?

答:在java中,方法参数的传递方式是值传递(pass by value),这意味着当你将变量传递给方法的时候,实际上传递的是变量的副本,而不是变量本身

在上述代码中,swap方法接受两个int类型的参数x和y.当你在main方式中调用swap(a,b)时,java会将a和b分别复制一份传递给x和y

在swap的方法内部,x和y的值确实被交换了.但这只是交换了x和y的副本值,而不是main方法中a和b的值.当swap方法执行完毕后,x和y的生命周期结束,他们的值不会影响到main方法中的a和b

因此main方法中的a和b的值没有呢发生交换,输出的结果仍然是交换前的值

三、如何修改能使其发生交换?

方法 1:用数组封装(利用引用传递特性)

基本类型本身无法直接通过方法修改外部变量,但可以用数组(引用类型)封装,通过修改数组元素实现交换:

方法 2:用Integer不行?注意!

虽然 Integer 是引用类型,但由于 Integer 内部值是 final 修饰的(不可变) ,直接传递 Integer 对象也无法真正交换。

若想模拟,需自定义一个 “可变” 的包装类(或用 Java 提供的 AtomicInteger 等,不过更推荐简单场景用数组)。

比如自定义一个简单的可变包装类:

方法 3:返回交换后的结果(无需修改外部变量,直接返回新值)

如果不想用数组或自定义类,也可以让 swap 返回交换后的结果数组 / 对象,重新接收赋值:

总结:最简洁的方式是用数组封装基本类型(方法 1),利用引用传递修改内部元素;若追求更面向对象,可自定义可变包装类(方法 2);简单场景也可直接返回交换结果(方法 3)。

当然也可以这样改

当然如果要赋值这样还不够,需要增加一个构造方法来初始化value的值

至于这一块为什么要加static,这就涉及到了之前的模块,内部类.

我们来回顾一下:

四、回顾:内部类

在 Java 中,static class MyValue 这里的 static 是用来修饰内部类的,它的作用和报错原因与 Java 的类加载、内部类访问规则有关,具体可以这么理解:

1. 内部类的“归属”问题

  • 我们写的 MyValue 是定义在另一个类(假设是 Main 类,因为有 main 方法)里面的内部类
  • 内部类默认是 “依赖外部类对象” 存在的(非静态内部类),它需要先有外部类的实例,才能创建自己的实例。(也就是说,如果把不加static,将这段代码放到外面,这串代码也是正确的)

  • 但你的 main 方法是 static 的(静态方法),静态方法里不能直接创建 “非静态内部类” 的对象 ,因为静态方法不依赖外部类实例,而非静态内部类却依赖,两者矛盾。

2. static修饰内部类的作用

给内部类加上 static 后,它就变成了静态内部类

  • 静态内部类不再依赖外部类的实例,”相当于和外部类 “平级,可以直接在静态方法(比如 main)里创建对象。
  • 简单说:static 让内部类脱离了 “必须依附外部类对象” 的限制,能在静态环境(如 main)里直接用。

3.  不加static会报错的场景

如果去掉 staticMyValue 就是非静态内部类,此时在 main(静态方法)里写 new MyValue() 就会报错,因为:

  • 静态方法 main 执行时,可能还没有外部类的实例。
  • 非静态内部类需要外部类实例才能创建,Java 不允许这种 “无依赖创建”,所以会提示类似 “无法从静态上下文引用非静态内部类” 的错误。

总结一下:

  • 加 static 是为了把内部类变成静态内部类,让它可以在静态方法(比如 main)里直接使用 。如果不加 static,非静态内部类依赖外部类实例,而静态方法里没法保证有外部类实例,就会报错~
  • 那么这时候就有聪明的小猪要问了,"同学同学,那我把static全都删掉不就好了"
  • 很遗憾的说,这样是不行的

4. 为什么不能把static全部去掉

如果把全部的 static 都去掉,代码会无法编译运行,因为 Java 程序的入口点 main 方法必须是 static 的。当你去掉所有 static 后,会遇到以下问题:

main方法必须是static

Java 虚拟机(JVM)启动时,会直接调用 public static void main(String[] args) 方法,而不需要创建类的实例。如果去掉 static,JVM 无法直接调用 main 方法,会抛出错误:

静态方法中不能引用非静态成员

如果 main 保持 static,但其他方法 / 类去掉 static,会导致:

  • 静态方法 main 无法直接调用非静态方法(如 swap)或创建非静态内部类(如 MyValue)的实例   例如:

必须先创建 Main 的实例,再通过实例调用:

解决方案:保留必要的static

如果你想去掉 static需要重构整个程序结构,例如:

  • 将 main 改为非静态(但 JVM 无法直接启动,需通过其他类调用)。
  • 创建类的实例来调用方法(违背 Java 程序的常规写法)。

这种重构会让代码变得复杂,通常不推荐更合理的做法是:

  • 保留 main 和工具方法(如 swap)的 static,确保程序可运行。
  • 仅在需要对象状态时使用非静态成员(如实例变量、方法)。

总结

不能去掉所有 static,因为 main 必须是 static 的。但可以根据需求调整:

  • 工具类方法(如 swap)通常设为 static,方便直接调用。
  • 内部类若需在静态环境使用,需声明为 static
  • 对象相关的成员(如实例变量、方法)保持非静态。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • spring 整合 mybatis 中数据源的几种配置方式(总结篇)

    spring 整合 mybatis 中数据源的几种配置方式(总结篇)

    因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • Spring中Bean的命名方式代码详解

    Spring中Bean的命名方式代码详解

    这篇文章主要介绍了Spring中Bean的命名方式代码详解,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • SpringBoot实现发送邮件功能过程图解

    SpringBoot实现发送邮件功能过程图解

    这篇文章主要介绍了SpringBoot实现发送邮件功能过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Log4j日志分类和过滤敏感字段的实例

    Log4j日志分类和过滤敏感字段的实例

    这篇文章主要介绍了Log4j日志分类和过滤敏感字段的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Spring Bean初始化及销毁多种实现方式

    Spring Bean初始化及销毁多种实现方式

    这篇文章主要介绍了Spring Bean初始化及销毁多种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java获取视频时长和封面截图

    Java获取视频时长和封面截图

    这篇文章主要为大家详细介绍了如何使用Java获取视频时长和封面截图功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-03-03
  • Java快速掌握Vector类方法

    Java快速掌握Vector类方法

    Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:Vector 是同步访问的;Vector 包含了许多传统的方法,这些方法不属于集合框架
    2022-03-03
  • SpringBoot优化接口响应时间的九个技巧

    SpringBoot优化接口响应时间的九个技巧

    在实际开发中,提升接口响应速度是一件挺重要的事,特别是在面临大量用户请求的时候,本文为大家整理了9个SpringBoot优化接口响应时间的技巧,希望对大家有所帮助
    2024-01-01
  • Spring基于注解的缓存声明深入探究

    Spring基于注解的缓存声明深入探究

    spring boot对缓存支持非常灵活,我们可以使用默认的EhCache,也可以整合第三方的框架,只需配置即可,下面这篇文章主要给大家介绍了关于SpringBoot学习之基于注解缓存的相关资料,需要的朋友可以参考下
    2022-08-08
  • Maven仓库加载顺序的实例解析

    Maven仓库加载顺序的实例解析

    Maven仓库一般分为本地仓库和远程仓库。那么在实际开发中,在配置了多个仓库的情况下,他们之间的加载访问顺序是怎么样的呢,本文就详细的来介绍一下
    2021-12-12

最新评论