Java会话对象已重新分配[英] Java session object is reassigned

问题描述

我正在尝试通过在会话中设置它们来向JSP发送项目列表.我在这里使用春天控制器.

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 

会话对象包含所有三个项目.

...
...

// Somewhere down the code, l.remove(2); //removing item3.

return "some_page";

问题:

期望: fisrt_item_list会话对象应包含3项.

实际:仅在会话中可用2项作为删除第三项更新了会话对象.但我从未将更新的L对象添加到会话中.为什么Java在返回页面之前重新分配会话对象?所以,我是否需要将L复制到另一个列表并使用该列表?

推荐答案

您必须首先了解值类型和引用类型之间的差异,请检查以下链接 Stackoverflow

让我给你一个简单的值类型

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++;
   }
}

输出

Value of a 10
Value of a 20
incrementing a and b
Value of a 10
Value of a 20

结论

int a和int b在C1 class中的值未递增,因为在Java中是primitive type(其恰好是值类型) 一个真实世界的value类型的例子可以如下:
如果我给你标记表的照片副本,如果你涂上涂鸦,原始标记表没有什么会发生,因为它是我的标记表的副本,同样在传递变量int a和int b时,将发送这些变量的副本因此,INC功能因此不会增加C1类的int a和int b的原始值

让我们查看引用类型

的示例

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++;
   }
}

输出

Value of a 10
Value of a 20
incrementing a and b
Value of a 11
Value of a 21

结论

此处的int a和int b的原始值递增,因为传递了对该对象的引用 当我们说C1 obj1 = new C1();键字新的新写入堆内存中的对象并将该对象的引用存储在type C1的type C1中,obj1不是它是句柄的对象Object of C1在堆中创建的Object of C1,因此当我们将obj1转到inc(C1 obj1)在class C2中,我们通过对象的句柄而不是对象,对象位于堆中
所以这不是对象的副本,但原始对象是由于手柄obj1而通过(具有早期给出的Ref tavier)

回答主题

List<Item> l = new ArrayList<Item>();
l.add("item1");
l.add("item2");
l.add("item3");
session.setAttribute("fisrt_item_list", l);

在此处设置ArrayList object中的ArrayList object,但对象不是字面上存储在会话对象中,阵列对象的对象存储在会话对象中,因此当从ArrayList中删除值时它反映在会话对象中,因为您的会话对象将句柄保存到仍然指向删除值的堆上的相同对象的阵列对象

注意:一个对象包含对另一个对象的引用称为对象组成,检查此链接 stackoverflow

其他推荐答案

Java使用参考分配.在你的情况,当你指定一个列表对象会话属性,会话不存储列表对象的副本,而不是它只是存储列表对象的引用.

因此,在该列表中的对象的任何修改将反映到会话为好.如果你不想更新会话,创建一个新的列表出来像下面的现有列表:

<强>列表LIST =新的ArrayList(升);

本文地址:https://www.itbaoku.cn/post/978333.html