java return hashmap更改指针而不是返回值
虽然我已经编程多年了,但我对Java还是新手。我遇到了一个哈希映射问题,我不知道如何解决。我认为我搜索这个网站很好,但我一定没有使用正确的术语,因为我不认为我是第一个遇到这个问题的人。我必须相信有一个简单的解决方案,我只是没有看到(森林换树木)
我有一个程序,它使用HashMaps在类之间来回传递大量变量。之所以这样做,是因为我们正在连接各种系统,其中包含我们试图在程序中处理的非协调数据
我发现,在做了大量的梳理之后(我没有太多的开始),当HashMap由类中的方法“返回”时,值不会返回给调用类的过程。而是返回一个指向“called”类过程中HashMap的指针。在“调用”类的方法中对HashMap的“副本”的后续修改会反映在被调用类的HashMap中,即使被调用类的HashMap被标记为private(并且这些类在不同的包中!)
同样,对“被调用类的HashMap”的任何修改也会反映在调用类的HashMap中
困惑?我也是,所以我把它归结为一小段代码来复制我发现的东西。(它可能会缩短得更多,但我正试图保留我使用的一些级别。)
麦因。java-默认包:
import mainLogic.MainLogic; public class TMain { private static MainLogic ml = new MainLogic(); public static void main(String[] args) { ml.performMainLogic(); } }
主要逻辑。java——“调用类”
package mainLogic; import java.util.HashMap; import subLogic.SubLogic; public class MainLogic { private HashMap<String,String> slValues; public MainLogic() { // do constructor stuff here } public void performMainLogic(){ SubLogic sl = new SubLogic(); sl.performSubLogic(); // returns pointer rather than values? slValues = sl.getSLHashUser(); showSLValues("MainLogic - after calling sl.getSLHashUSer"); sl.showSLHashUser("MainLogic - calling sl.showSLHashUserafter calling sl.getSLHashUser"); // affects both slValues AND slHash in the SubLogic Class!!!!! slValues.put(SubLogic.USER_FLD1,"NEWVALUE"); showSLValues("MainLogic - slValues after put"); sl.showSLHashUser("MainLogic - calling SubLogic showSLHashUser after slValues put"); // modifies slHash in SubLogic Class AND slValues here!!!!! sl.doSubLogic2(); showSLValues("MainLogic - slValues after doSubLogic2"); sl.showSLHashUser("MainLogic - calling SubLogic showSLHashUser after doSubLogic2"); } public void showSLValues(String title) { System.out.println(title); System.out.println(" slValues"); System.out.println(" Field 1 :\t" + slValues.get(SubLogic.USER_FLD1) ); System.out.println(" Field 2 :\t" + slValues.get(SubLogic.USER_FLD2) ); System.out.println(""); } }
子逻辑-被调用的类
package subLogic; import java.util.HashMap; public class SubLogic { private HashMap<String,String> slHashUser = new HashMap<String, String>(); // field names slHashUser static public final String USER_FLD1 = "ONE"; static public final String USER_FLD2 = "TWO"; public SubLogic() { slHashUser.put(USER_FLD1, "SubLogic1"); slHashUser.put(USER_FLD2, "SubLogic2"); showSLHashUser("SubLogic - Constructor"); } public void performSubLogic(){ slHashUser.put(USER_FLD1, "PSubLogic1"); slHashUser.put(USER_FLD2, "PSubLogic2"); showSLHashUser("SubLogic - performSubLogic"); } public void doSubLogic2(){ slHashUser.put(USER_FLD1, "modified"); showSLHashUser("SubLogic - doSubLogic"); } public HashMap<String,String> getSLHashUser() { showSLHashUser("SubLogic - getSubLogic"); return slHashUser; } public void showSLHashUser(String title) { System.out.println(title); System.out.println(" slHash Values"); System.out.println(" Field 1 :\t" + slHashUser.get(USER_FLD1) ); System.out.println(" Field 2 :\t" + slHashUser.get(USER_FLD2) ); System.out.println(""); } }
我的第一个想法是,我需要在生产线的MainLogic中做一些不同的事情:
slValues = sl.getSLHashUser();
但我不确定真正的问题是否出在SubLogic的getSLHashuser方法中,我尝试在该方法中执行返回:
return slHashUser;
因为java应该是关于“按值传递”和“按引用传递”(在老派的“C”意义上)的,所以我没有想到这一点
您的帮助将不胜感激,即使这是一个指向正确文档的指针,我一定忽略了
# 1 楼答案
当方法返回对可变对象的引用时,该方法的调用方可以通过调用该引用的方法来改变该对象,从而改变调用该方法的对象的状态
要防止此类修改,您可以返回
HashMap
的副本:这样,更改返回的HashMap不会影响
slHashUser
成员的内容# 2 楼答案
不,这是Java中可变对象的工作方式
Java方法参数和结果是按值传递的
然而,有一个微妙之处,许多新手错过了。当您传递或返回一个对象时,传递和复制的是对象引用。。。而不是对象本身的状态
但如果你记住了这一点,你所观察到的是可以解释的,也是自然的
如果您的应用程序要求在返回HashMap时进行复制,则需要显式地进行复制。幸运的是,
HashMap
有一个“拷贝构造函数”,它生成一个新的HashMap
,它是现有映射状态的浅拷贝