我在会话中存储了一个对象。在我的控制器中,当用户发送请求时,它会同时执行以下代码:
MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
while(!obj.isNewResultAvailable()){
//will loop until new result is available.
}
正如我所提到的,它同时执行,因此当控件仍然在循环内时,用户可以做一些其他事情,例如,当用户按下另一个按钮时,请求将被发送到执行该操作的控制器。以下:
MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
obj = null;
我的期望是,循环直到新结果可用的代码将抛出NullPointerException
。只是发现它不是。
那么,为什么从另一个控制器的会话中拉出的对象不是null
,尽管将该对象设置为另一个控制器为null
?
修改:
在我目前的代码中,我实际上尝试过做
req.getSession().setAttribute("myObject", null);
和
req.getSession().removeAttribute("myObject");
但是,这并没有解决我的问题,while循环中的对象仍然没有被取消。
实现
对于那些会遇到这种困惑的人来说,问题的根源是我对如何在Java中传递对象感到困惑。我的问题非常简单,obj = null
只是将obj
的引用设置为null,将 NOT 设置为对象本身。
正如morgano所指出的,会话中的对象已由执行while循环的线程在本地引用,因此,req.getSession().setAttribute("myObject", null);
和req.getSession().removeAttribute("myObject");
不会导致对象变为空。这些基本上是从会话中删除对象的引用(因此理想情况下使它成为gc的候选者,这在我的情况下不会发生,因为对象是由长时间运行的http请求引用的localy [while循环事物])
答案 0 :(得分:3)
不要那样做,这样做:
req.getSession().setAttribute("myObject", null);
或更好:
req.getSession().removeAttribute("myObject");
您正在执行的操作设置为null对对象的引用,您根本不修改会话属性。
问题版本之后更新:
一旦“迭代”线程引用了你的对象,“删除”线程将其从会话中删除是徒劳的,你的对象已被第一个线程中的局部变量引用。
答案 1 :(得分:1)
考虑这个例子:
MyObject a = new MyObject();
MyObject b = a;
b = null;
您似乎期待的是:
MyObject a = new MyObject(); // a is the new object
MyObject b = a; // b is the same object
b = null; // set the object referenced by both a and b to null
真正发生的事情:
MyObject a = new MyObject(); // a is the new object
MyObject b = a; // b points to the same object as a
b = null; // b doesn't point to anything
简而言之:不是将引用值设置为null(即示例中的会话),而是将引用本身设置为null(即在你的例子中obj
。
答案 2 :(得分:0)
做这样的事情。会话是一个关键的价值图。您必须针对特定键值明确设置null。
req.getSession().setAttribute("myObject", null);
或删除密钥。
req.getSession().removeAttribute("myObject");