구구구구우
1k
2017-07-29 22:57:04
4
926

"자바에서 아래 두 방식의 차이점이 뭘까요?" 에 답변 다셨던 분들과 다른 개발자분들에게 질문이 있습니다.


Okky사이트가 댓글에 대한 댓글 기능이 및 알림기능이 신통치 못해서(표현이 이래서 사이트 운영자 분께는 죄송합니다. ) 새로 글 쓰네요


https://okky.kr/article/406874?note=1277358


일단 람다와 익명클래스 , 외부 참조 및 GC에 대한 질문인데 특히 람다가 기존의 익명클래스에서 어떤식으로 구현이 된건지가 궁금하네요. 해당 글에도 질문에 내용이 있는데 여기에도 간략하게 적어볼께요

외부 클래스의 참조를 갖는 익명클래스와 달리 static 익명 클래스 와 람다 표현식은 외부 클래스의 참조를 같지 않는다는 사실을 이제 알게 되었습니다. (이제 2년차가 된 개발자인데 그동안 자신만만했던 자신이 부끄럽네요. 정확히는 람다의 특성은 알고 있었는데 익명클래스의 특성이 람다의 특성과 같은줄 알았습니다.)

그런데 static 익명 클래스와 달리 람다 표현식의 경우는 외부 클래스의 멤버의 접근이 가능하죠

static 익명 클래스 경우 외부클래스에 멤버에 접근하려면 static 익명 클래스의 인스턴스를 생성할때 해당 멤버를 전달하는 방법 말고는 없구요.

제가 궁금한건 람다식의 접근 범위 (기존의 익명클래스와 비교해서) 및 내부적으로 구현된 상세 내용들에 대해서 자세하게 설명을 듣고 싶네요,

그리고 해당 글에 단설 님께서 답글을 중에 " 바이트코드 뜯어보면 내부적으로는 static 메소드가 됩니다"  라고 하셨는데 그부분에 대해서 설명을 들었으면 좋겠어요 

단설 님께서 설명해주면 더 좋고, 아시는 분꼐서 설명해주셔도 좋구요




0
  • 답변 4

  • kenu
    52k
    2017-07-30 00:59:26

    specification 일독을 권합니다.

    https://translate.google.com/translate?sl=en&tl=ko&js=y&prev=_t&hl=ko&ie=UTF-8&u=http%3A%2F%2Fwww.oracle.com%2Ftechnetwork%2Farticles%2Fjava%2Farchitect-lambdas-part1-2080972.html&edit-text=

  • 구구구구우
    1k
    2017-07-30 01:38:16

    방금 읽어보았는데 제가 원하는 내용은 없는거 같은데....

    저는 람다와 익명클래스가 외부 변수에 대해 접근하는 방식의 차이가 궁금한데 그부분에 대해서는 특별히 다루고 있지는 않는거 같네요

    제공해주신 정보는 감사합니다. 

  • kenu
    52k
    2017-07-30 09:52:09

    https://stackoverflow.com/questions/25055392/lambdas-local-variables-need-final-instance-variables-dont

  • 구구구구우
    1k
    2017-07-30 11:45:06 작성 2017-07-30 11:45:53 수정됨

    익명클래스의 외부 변수에 대한 접근이 어떠한건진 기존보다 더 확실하게 알게되었습니다. 감사합니다. 

    근데 질문하고 싶은 내용의 일부를 제가 제대로 하지 못해서 그부분만 다시 질문을 드리겠습니다.


    익명클래스와 람다식의 경우 외부 클래스 인스턴스에 참조를 같는 상황이 조금 다른거 같은데 

    익명클래스와 람다식 모두 외부클래스 인스턴스의 멤버 변수에 접근 및 변경에 자유롭지만

    제가 작성한 예제처럼 익명클래스와 람다식은 GC에서 차이를 보였습니다. 외부클래스 인스턴스 참조를 갖는 익명클래스의 경우 익명클래스 인스턴스가 살아있는 동안 외부클래스의 인스턴스는 GC가 되지 않았고 

    람다식의 경우는 GC가 되었습니다.(예제처럼 외부클래스 인스턴스에 대해 어떠한 작업도 하지 않는 경우)

    그래서 단설 님의 답변을 보고 람다식은 static 익명 클래스 (static inner class)가 아닐까 라는 생각에 예제를 작성해서 태스트 했는데 static 익명클래스의 경우 람다식과 마찬가지로 익명클래스의 인스턴스가 살아 있다 하더라도 외부 클래스의 인스턴스는 GC 대상이 되더라구요

    그래서 람다식은 static 익명클래스와 같은 표현이다라고 적었는데 다시 생각해보니 이들은 차이가 있었습니다. 앞서 말한것처럼 람다식의 외부클래스 인스턴스의 멤버 변수에 접근 및 변경이 가능하다는 차이이죠

    static 익명클래스 (static inner class)가 람다식과 같은 방식으로 동작하려면 외부클래스 인스턴스를 익명 클래스의 인스턴스가 생설될때 전달받아야 가능하겠다라는 생각을 했습니다.

    여기까지가 생각을 하고 무언가 부족함을 느껴서 어제 질문을 드렸던 거구요 (그냥 막연하게 제 생각이 흐름이 맞는건지 람다식과 익명클래스의 차이 또는 람다식과 익명클래스의 차이를 좁히기 위한 방법 등 뭐든 간에 제 머릿속에 정립이 안되는 무언가에 대한 설명이 필요했습니다.)

    그래서 아침에 예제를 다시 작성했는데

    // static inner class
    	private static final class CRunnable implements Runnable {
    //		public WeakReference<OuterClass> ref;
    //		private OuterClass out;
    		
    		public CRunnable(OuterClass out) {
    //			this.out = out;
    //			ref = new WeakReference<OuterClass>(out);
    		}
    		
    		@Override
    		public void run() {
    			for (int i = 0; i < 1000; i++) {
    				try {
    					System.out.println("inner class live");
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}

    static 익명클래스 (static inner class) 인스턴스를 생성하면서  외부클래스 인스턴스를 전달을 해보았습니다. 그 결과 외부클래스 인스턴스의 참조를 갖는 익명클래스의 인스턴스가 살아있는 동안 외부클래스 인스턴스는 GC가 되지 않았습니다. 그래서 WeakReference 사용해봤는데 이번엔 GC가 되던구요

    그래서 제가 내린 결론이 람다는 static 익명클래스(static inner class) 에 외부 클래스 인스턴스를 WeakReference로 가진 표현과 똑같다 입니다. 

    그래서 제 질문은 이게 맞는건지 입니다. 다른말로하면 람다가 컴파일 과정에서 이와 똑같이 작성이 되는건지 아니면 아예 다른 표현인건지 실제로는 어떤건지가 궁금한겁니다.

    질문이 엄청 길었네요.






  • 로그인을 하시면 답변을 등록할 수 있습니다.