복붙노트

[SPRING] Java 세션 객체가 재 할당 됨

SPRING

Java 세션 객체가 재 할당 됨

세션에 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 객체를 세션에 추가 한 적이 없습니다. 왜 자바 페이지를 반환하기 전에 세션 개체를 다시 할당합니까? 그래서 l을 다른 목록으로 복사하고 사용해야합니까?

해결법

  1. ==============================

    1.먼저 Java에서 값 유형과 참조 유형의 차이점을 이해하고 다음 링크를 확인하십시오. StackOverflow

    먼저 Java에서 값 유형과 참조 유형의 차이점을 이해하고 다음 링크를 확인하십시오. 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
    

    결론

    in은 int 타입과 C1 타입의 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();
           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 (); 핵심 단어 new는 힙 메모리에 C1 클래스의 객체를 만들고 해당 객체에 대한 참조는 C1 유형의 변수 obj1에 저장되며 obj1은 힙에 만들어진 C1 객체에 대한 핸들 인 객체가 아니므로 클래스 C2의 inc (C1 obj1)에 obj1을 전달하여 객체가 아닌 객체의 핸들을 전달합니다. 객체는 힙에 있습니다. 그래서 이것은 객체의 복사본이 아니지만 obj1 핸들 때문에 원래의 객체가 전달됩니다 (예를 들어 현실 세계에 대한 참조와 함께)

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

    여기 세션 객체에서 ArrayList 객체를 설정하지만 객체가 세션 객체에 실제로 저장되지 않으면 Arraylist 객체의 핸들이 세션 객체에 저장되므로 Arraylist 객체에서 값을 삭제하면이 객체에 반영됩니다. 세션 객체는 값이 삭제 된 힙의 같은 객체를 여전히 가리키는 Arraylist 객체에 대한 핸들을 보유하기 때문에 세션 객체

  2. ==============================

    2.Java는 참조 지정을 사용합니다. 세션 개체에 목록 개체를 할당하면 세션에서 해당 목록 개체의 복사본을 저장하지 않고 대신 목록 개체의 참조 만 저장합니다.

    Java는 참조 지정을 사용합니다. 세션 개체에 목록 개체를 할당하면 세션에서 해당 목록 개체의 복사본을 저장하지 않고 대신 목록 개체의 참조 만 저장합니다.

    따라서 해당 목록 개체의 모든 수정 사항은 세션에도 반영됩니다. 세션을 업데이트하지 않으려면 다음과 같이 기존 목록에서 새 목록을 만드십시오.

    리스트리스트 = 새로운 ArrayList (l);

  3. from https://stackoverflow.com/questions/42606099/java-session-object-is-reassigned by cc-by-sa and MIT license