Java会话对象被重新分配

Java会话对象被重新分配,java,spring,session,arraylist,Java,Spring,Session,Arraylist,我试图通过在会话中设置项目来将项目列表发送到JSP。我在这里使用Spring控制器 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 问题: class Main{ public static voi

我试图通过在会话中设置项目来将项目列表发送到JSP。我在这里使用Spring控制器

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 
问题:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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);
  }
}
应为:
第一个项目列表
会话对象应包含3个项目


实际:由于删除第三项更新了会话对象,会话中只有2项可用。但我从未将更新的l对象添加到会话中。为什么java在返回页面之前重新分配会话对象?那么,我是否需要将l复制到另一个列表并使用它?

Java使用引用赋值。在将列表对象指定给会话属性时,会话不会存储该列表对象的副本,而只存储列表对象的引用

因此,该列表对象中的任何修改也将反映到会话中。如果不想更新会话,请从现有列表中创建一个新列表,如下所示:


列表列表=新的ArrayList(l)

Java使用引用赋值。在将列表对象指定给会话属性时,会话不会存储该列表对象的副本,而只存储列表对象的引用

因此,该列表对象中的任何修改也将反映到会话中。如果不想更新会话,请从现有列表中创建一个新列表,如下所示:


列表列表=新的ArrayList(l)

您必须首先了解Java中值类型引用类型之间的区别,请查看以下链接

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

MAIN.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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);
  }
}
C1.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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{
   void inc(int a, int b){
      a++;
      b++;
   }
}
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 10
Value of a 20
Value of a 10
Value of a 20
incrementing a and b
Value of a 11
Value of a 21
结论

C1类
中的
int a
int b
的值没有增加,因为in在java中是一个
基本类型
(它恰好是一个值类型)
值类型的实际示例如下:
如果我给你我的标记表的照片副本,如果你在上面涂鸦,原始标记表不会发生任何事情,因为当你传递变量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();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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);
  }
}
C1.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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{
   void inc(int a, int b){
      a++;
      b++;
   }
}
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 10
Value of a 20
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=newc1()
关键字new在堆内存中创建了一个
类C1
的对象,对该对象的引用存储在
类型C1
变量obj1
中,
obj1
不是对象,而是在堆中创建的C1对象的句柄,因此当我们将
obj1
传递给
inc(C1 obj1)时
类C2
中,我们传递的是对象的句柄而不是对象,对象在堆中
因此,这不是对象的副本,而是传递原始对象,因为句柄obj1(参考前面给出的真实世界示例)

对主要问题的答复

listl=newarraylist();
l、 添加(“第1项”);
l、 添加(“第2项”);
l、 添加(“第3项”);
session.setAttribute(“第一个项目列表”,l);
在这里,您可以在会话对象中设置
ArrayList对象
,但对象并不是直接存储在会话对象中,ArrayList对象的句柄存储在会话对象中,因此,当从Arraylist对象中删除某个值时,它会反映在会话对象中,因为会话对象持有Arraylist对象的句柄,该句柄仍然指向从中删除该值的堆上的同一对象

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


您必须首先了解Java中值类型引用类型之间的区别,请查看以下链接

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

MAIN.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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);
  }
}
C1.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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{
   void inc(int a, int b){
      a++;
      b++;
   }
}
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 10
Value of a 20
Value of a 10
Value of a 20
incrementing a and b
Value of a 11
Value of a 21
结论

C1类
中的
int a
int b
的值没有增加,因为in在java中是一个
基本类型
(它恰好是一个值类型)
值类型的实际示例如下:
如果我给你我的标记表的照片副本,如果你在上面涂鸦,原始标记表不会发生任何事情,因为当你传递变量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();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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);
  }
}
C1.java:

class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       obj1.increment();
       obj1.print();
     }
}
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);
  }
}
class Main{
     public static void main(String [] args){
       C1 obj1 = new C1();
       obj1.print();
       C2.inc(obj1);
       obj1.print();
     }
}
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{
   void inc(int a, int b){
      a++;
      b++;
   }
}
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 10
Value of a 20
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=newc1()
关键字new在堆内存中创建了一个
类C1
的对象,对该对象的引用存储在
类型C1
变量obj1
中,
obj1
不是对象,而是在堆中创建的C1对象的句柄,因此当我们将
obj1
传递给
inc(C1 obj1)时
类别C2中
我们传递的是对象的句柄而不是对象,对象在