为了账号安全,请及时绑定邮箱和手机立即绑定

通过私有方法返回更新的变量

通过私有方法返回更新的变量

森栏 2022-06-04 16:38:18
我今天注意到一个场景。当我们在私有方法上传递参数时,实体将返回修改后的值,而不是原始值。这是我的示例代码,/** * @author gowthami * */public class Test {    /**     * @param args     */    public static void main(String[] args) {        String s = "gowth";        System.out.println("before " + s);        concateMe(s, "ami");        System.out.println("after " + s);        BeanTest bt = new BeanTest();        bt.setId("1");        System.out.println("before");        System.out.println(bt.getId());        System.out.println(bt.getName());        setBeanTestName(bt, "gowthami");        System.out.println("after");        System.out.println(bt.getId());        System.out.println(bt.getName());        String st = new String("gowth");        System.out.println("before " + st);        concateMe(st, "ami");        System.out.println("after " + st);    }    private static void setBeanTestName(BeanTest bt, String string) {        bt.setName(string);    }    private static void concateMe(String s, String string) {        s = s+string;        System.out.println("inside method " + s);    }}BeanTest.javapublic class BeanTest {    private String id;    private String name;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}因此,即使我们没有从私有方法返回它,但字符串不是,bean 也会得到更新。有人可以解释一下 JVM 级别发生了什么吗?
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

这是因为 Java 遵循按值调用,而不是按引用调用。


当您传递s时,您实际上传递的是 s 的值,而不是实际的 s。因此,尽管您在 concateMe() 中更改了s,但它不会在您的 main 方法中更改。


当您传递bt时,更改会在您更改该引用的字段变量时产生影响。但是,如果您更改参考,则不会有任何效果。您可以在 main 方法中添加它:


 System.out.println("before......");

 System.out.println(bt.getId());

 System.out.println(bt.getName());

 changeBeanTest(bt);

 System.out.println("after");

 System.out.println(bt.getId());

 System.out.println(bt.getName());

假设你的changeBeanTest是这样的:


private static void changeBeanTest(BeanTest tempBeanTest) { 

    BeanTest bt = new BeanTest();

    bt.setId("2");

    bt.setName("Trump");

    tempBeanTest = bt;

}

运行这个。从 main() 发送的bt不会有任何变化。


查看完整回答
反对 回复 2022-06-04
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

字符串 s = "gowth"; 在这一行中 s 指向字符串池中的“gowth”。当您在这里调用 private static void concateMe(String s, String string) 时,String s 与调用方方法 String s 不同。这里 String s 范围是方法 ContactMe 的本地,但是contactMe本地字符串s指向调用者类字符串s所指向的相同“gowth”。在s = s +字符串之后;由于字符串是不可变的,方法本地引用字符串s指向不同的字符串“gowthami”,但调用者方法字符串s是仍然指向“gowth”。所以你得到了这个输出。但是在 Bean 两个对象都指向同一个 String 引用的情况下,一旦我们对引用进行了任何更改,它将同时反映在两个对象中。



查看完整回答
反对 回复 2022-06-04
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

Bean 是 java 中通过引用传递给私有方法的完整对象,因此它在主方法和私有方法中是相同的实例。

您正在修改该实例的值,以便更改显示在两个位置。

该字符串或多或少是一个原语,并作为值的副本而不是来自 main 的确切实例传递。它是私有方法中的一个新实例,因此您正在修改一个新变量。更改不会显示在 main 方法中,因为它是不同的实体。


查看完整回答
反对 回复 2022-06-04
  • 3 回答
  • 0 关注
  • 81 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信