2011-01-27 5 views
7

내부 클래스가 일반 클래스보다 가볍습니까? 아니면 결국 Java가 일반 클래스처럼 내부 클래스를 컴파일합니까?내부 클래스는 가볍습니까?

자바의 클래스가 모두 매우 가벼운 것은 아니며 permgen 메모리의 일부를 차지하므로 내부 클래스처럼 클로저와 같은 함수를 사용하는 것이 가장 좋은지 또는 표준 클래스가 괜찮아?

+1

JVM에는 기본 데이터 유형 ('int','float' 등) 및 클래스 만 있습니다. 그들 사이에는 아무것도 없습니다. – Gabe

답변

17

내부 클래스와 익명 내부 클래스는 모두 .class 개의 파일로 컴파일됩니다. 예를 들어 :

class Outer { 
    class Inner { 

    } 

    Object function() { 
      return new Object() { 

      }; 
    } 
} 

.class 파일, Outer.class, Outer$Inner.classOuter$1.class를 생성합니다. 그것들은 다른 클래스들보다 "가벼운"것이 아니며, 성능에 대한 관점에서 다른 것을 사용하는 것의 장점이 없습니다. 물론, 내부 클래스와 특히 익명의 내부 클래스는 일반 클래스가 코딩하기가 어려운 컨텍스트에서 유용하지만 별개의 문제입니다.

+7

+1. 내부 클래스가 컴파일러가 포함하는 합성 메소드 및 필드를 포함하기 때문에 내부 클래스가 포함 된 클래스에 대해 특수한 가시성 규칙을 용이하게하기 때문에 내부 클래스가 "무겁"수 있습니다. – Thilo

+0

와우! 정보 주셔서 감사합니다! – Waneck

1

가벼운 무게는 아니지만 한계가 있습니다. AFAIK, 익명 내부 클래스의 인스턴스를 둘 이상 만들 수 없으므로 필요에 따라 익명이 아닌 클래스를 사용해야합니다.

편집 1 : 모든 댓글과 설명을 제공해 주셔서 감사합니다. 제발 이해 좀 도와주세요 ... 당신이 익명의 내부 클래스의 인스턴스를 여러 개 가질 수 있다는 것을 이해합니다. 그러나 예를 들어 단일 익명의 내부 ActionListener 객체를 선언하면 의 인스턴스가 여러 개있을 수 있으며 그 클래스는이고 그 클래스 리플렉션을 사용하지 않고? 사전에 감사드립니다 (또는 내 자신의 질문에 이것을 물어봐야합니까?)!

좋아, 내가 물기가 없어서 ... 코드로 설명해 드리겠습니다. 내가 여기에 익명의 ActionListener를 만들 말 :

JButton button = new JButton("Button"); 

    button.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.out.println("Button says \"Foo!\""); 
    } 

    }); 

    JOptionPane.showMessageDialog(null, button); 

내가 익명의 ActionListener를 작성하고도 일거에이 클래스의 개체를 만듭니다. 내가 항상 배웠던 것은, 내가 여기에서 나의 포스트의 꼭대기에서 말했던 (그리고 땡겨 줬다),이 익명의 클래스의 또 다른 객체를 만드는 것은 불가능하지 않다면 (반사의 마법없이) 어렵다는 것이 었습니다. 하나의 객체 만 만들 수 있으며 하나의 객체 만 필요로하는 상황에서는 괜찮습니다. 그러나 다른 상황에서는 괜찮지 않습니다. 그리고 물론, 당신은 for 루프에서와 같이 유사한 여러 익명의 ActionListener 클래스를 만들 수 있습니다

JPanel panel = new JPanel(new GridLayout(5, 5)); 
    JButton[] buttons = new JButton[25]; 
    for (int i = 0; i < 25; i++) { 
    final int btnNumber = i; 
    buttons[i] = new JButton(String.valueOf(btnNumber)); 
    buttons[i].addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("From button " + btnNumber); 
     } 
    }); 
    panel.add(buttons[i]); 
    } 
    JOptionPane.showMessageDialog(null, panel); 

그러나 그렇다고하더라도, 여기에서 만든 각 익명의 클래스가 다르다. 이러한 유형의 청취자가 여러 JButtens에서 사용되고 상태가 있고 해당 동작이이 상태에 따라 다르면 중요 할 수 있습니다. 동의하다? 동의하지 않는다? 모든 입력에 미리 감사드립니다!

+3

예를 들어 클래스를 'for' 루프에 넣고 여러 번 인스턴스화하여 익명 내부 클래스의 인스턴스를 여러 개 가질 수 있습니다.Java는이 클래스가 모두 동일한 유형을 필요로한다고 생각하지만, 맞는지 아닌지를 기억할 수는 없습니다. – templatetypedef

+1

당신은 그것을 생각하고 있습니다. 익명의 내부 클래스는 여전히 클래스입니다. 당신이 원하는만큼의 인스턴스를 가질 수 있습니다. 원하는만큼 익명 내부 클래스를 가질 수도 있습니다. 컴파일러는이 모든 것을 컴파일 타임에 처리합니다. 첫 번째 익명의 스펙은 Foo $ 1의 멋진 이름을 얻고, 두 번째는 Foo $ 2를 얻습니다. 'new Runnable() {...} '과 같은 코드는'Foo.new 1()'이됩니다. –

+0

의견과 도움이되는 정보를 보내 주셔서 감사합니다! 나에게 분명히 해주세요 ... 익명의 내부 ActionListener가있는 경우, 객체가 생성 될 때 생성되므로이 클래스의 두 개의 별개의 인스턴스를 가질 수 있습니다 (참조하지 않고). 나는 익명의 ActionListeners의 인스턴스를 많이 가질 수 있다는 것을 알고 있지만 선언 된 하나의 별개의 익명 클래스의 인스턴스를 여러 개 가질 수 있는지 궁금합니다. –

7

내부 클래스는 여전히 클래스이며 ClassLoader에 의해로드되어야합니다. 어떤 것이라도 그 반대가 사실입니다. 정적이 아닌 내부 클래스는 부모 클래스가 소유하고있는 클래스에 대한 참조를 가지고 있기 때문에 부모 클래스가 가비지 수집을 유지할 수 있습니다.

+1

+1. 부모 참조뿐만 아니라 관련 클래스의 "private"메서드 호출을 허용하는 합성 메서드도 있습니다. – Thilo

관련 문제