Java 会话对象被重新分配 [英] Java session object is reassigned
问题描述
我试图通过在会话中设置项目列表来将项目列表发送到 JSP.我在这里使用 Spring 控制器.
List- l = new ArrayList
- ();l.add("item1");l.add("item2");l.add("item3");session.setAttribute("fisrt_item_list", l);//所以 fisrt_item_list
会话对象包含所有三个项目.
<代码>......//代码下方的某处,l.remove(2);//删除item3.返回some_page";
问题:
预期: fisrt_item_list
会话对象应包含 3 个项目.
实际:会话中只有 2 个项目可用,因为删除了第三个项目更新了会话对象.但我从未将更新的 l 对象添加到会话中.为什么java在返回页面之前重新分配会话对象?那么,我是否需要将 l 复制到另一个列表并使用它?
你必须先了解Java中Value Type和Reference Type的区别,查看以下链接StackOverflow
让我给你一个简单的值类型示例
MAIN.java :
class Main{公共静态无效主(字符串 [] args){C1 obj1 = 新 C1();obj1.print();obj1.increment();obj1.print();}}
C1.java:
class C1{int a = 10;整数 b = 20;公共 C1(){}无效增量(){System.out.println("增加a和b");新的 C2().inc(a,b);}无效打印(){System.out.println("a"+a的值);System.out.println("b 的值"+ b);}}
C2.java
class C2{void inc(int a, int b){一个++;b++;}}
输出
一个 10 的值20 的价值递增 a 和 b10 的值20 的价值
结论
C1 class
中int a
和int b
的值没有增加,因为in是一个原始类型
在 java 中(恰好是一个值类型)
值类型的真实示例如下:
如果我给你我的标记表的照片副本并且如果你在上面涂鸦,原始标记表不会发生任何事情,因为它是我的标记表的副本,当你传递变量 int a 和 int b 时,这些变量的副本被发送到 inc 函数,因此它不会增加 C1 类的 int a
和 int b
中的原始值
让我们看一个引用类型的例子
MAIN.java :
class Main{公共静态无效主(字符串 [] args){C1 obj1 = 新 C1();obj1.print();C2.inc(obj1);obj1.print();}}
C1.java:
class C1{int a = 10;整数 b = 20;公共 C1(){}无效打印(){System.out.println("a"+a的值);System.out.println("b 的值"+ b);}}
C2.java
class C2{公共静态无效公司(C1 obj1){obj1.a++;obj1.b++;}}
输出
一个 10 的值20 的价值递增 a 和 b11 的值21 的值
结论
这里 int a 和 int b 的原始值递增,因为传递了对该对象的引用
当我们说C1 obj1 = new C1();
时,关键字new在堆内存上创建了一个class C1
的对象,并且对该对象的引用存储在type C1
的 >variable obj1 ,obj1
不是对象,它是堆中创建的 C1 对象
的句柄,因此,当我们将 obj1
传递给 class C2
中的 inc(C1 obj1)
时,我们传递的是对象的句柄而不是对象,对象在堆
所以这不是对象的副本,而是原始对象因为句柄 obj1 被传递(引用真实世界,例如之前给出的)
回答主要问题
List- l = new ArrayList
- ();l.add("item1");l.add("item2");l.add("item3");session.setAttribute("fisrt_item_list", l);
这里在session对象
中设置了ArrayList对象
,但是object并不是按字面存储在session对象中,Arraylist对象的句柄存储在session 对象,所以当一个值从 Arraylist 对象中删除时,它会反映在 session 对象中,因为你的 session 对象持有 Arraylist 对象的句柄,该对象仍然指向删除该值的堆上的同一个对象><块引用>
注意:持有对另一个对象的引用的一个对象称为对象组合,请检查此链接 堆栈溢出
I am trying to send List of Items to JSP by setting them in a session. I am using Spring controller here.
List<Item> l = new ArrayList<Item>();
l.add("item1");
l.add("item2");
l.add("item3");
session.setAttribute("fisrt_item_list", l); // So the fisrt_item_list
The session object contains all three items.
...
...
// Somewhere down the code, l.remove(2); //removing item3.
return "some_page";
The Problem:
Expected: fisrt_item_list
session object should contain 3 items.
Actual : Only 2 items available in session as the removal of third item updated the session object. But I have never added the updated l object into session. Why does java reassign the session object before returning a page? So, do I need to copy over the l to another list and use that?
You must first understand the difference between Value Type and Reference Type in Java , check the following link StackOverflow
let me give you a simple example of Value Type
MAIN.java :
class Main{
public static void main(String [] args){
C1 obj1 = new C1();
obj1.print();
obj1.increment();
obj1.print();
}
}
C1.java:
class C1{
int a = 10;
int b = 20;
public C1(){
}
void increment(){
System.out.println("incrementing a and b");
new C2().inc(a,b);
}
void print(){
System.out.println("Value of a "+ a);
System.out.println("Value of b "+ b);
}
}
C2.java
class C2{
void inc(int a, int b){
a++;
b++;
}
}
Output
Value of a 10
Value of a 20
incrementing a and b
Value of a 10
Value of a 20
Conclusion
The value of int a
and int b
in C1 class
was not incremented because in is a primitive type
in java(which happens to be a value type)
A real world example to value type can be as follows :
If I give you photo copy of my mark sheet and if you scribble on it nothing will happen to original mark sheet because it is a copy of my mark sheet similarly when you pass the variable int a and int b , copy of those variables is sent to the inc function hence it doesnot increment the original value in int a
and int b
of class C1
let us see an example for reference type
MAIN.java :
class Main{
public static void main(String [] args){
C1 obj1 = new C1();
obj1.print();
C2.inc(obj1);
obj1.print();
}
}
C1.java:
class C1{
int a = 10;
int b = 20;
public C1(){
}
void print(){
System.out.println("Value of a "+ a);
System.out.println("Value of b "+ b);
}
}
C2.java
class C2{
public static void inc(C1 obj1){
obj1.a++;
obj1.b++;
}
}
Output
Value of a 10
Value of a 20
incrementing a and b
Value of a 11
Value of a 21
Conclusion
here the original value of int a and int b is incremented , because the reference to that object is passed
When we say C1 obj1 = new C1();
the key word new makes an object of class C1
on the heap memory and the reference to that object is stored in variable obj1
of type C1
, obj1
is not the object it is a handle to the Object of C1
created in heap, so when we pass obj1
to inc(C1 obj1)
in class C2
we pass the handle of the object not the object , the object is in the heap
So this is not the copy of the object but the original object is passed because of the handle obj1(with ref to real world eg given earlier)
Answer to the main question
List<Item> l = new ArrayList<Item>();
l.add("item1");
l.add("item2");
l.add("item3");
session.setAttribute("fisrt_item_list", l);
here you set the ArrayList object
in the session object
,but object is not literally stored in the session object , the handle to the object of Arraylist is stored in the session object , so when a value is deleted from the Arraylist object it is reflected in the session object because your session object holds the handle to the Arraylist object which is still pointing to the same object on the heap from which the value is deleted
Note : One object holding the reference to another object is Called Object Composition , do check this link StackOverflow
这篇关于Java 会话对象被重新分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!