尽管明确将会话属性设置为null,但仍未引用该属性

时间:2013-07-23 03:12:50

标签: java httpsession

我在会话中存储了一个对象。在我的控制器中,当用户发送请求时,它会同时执行以下代码:

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循环事物])

3 个答案:

答案 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");