2013-03-29 4 views
1
public void foo() { 
    class Bar { 
    } 
    Bar b = new Bar(); 
} 

메서드 로컬 클래스가 최상의 디자인 선택이 될 수있는 상황은 없습니다. 당신은 그것을 사용한 적이 있습니까? 어떤 경우에?메서드 로컬 클래스 란 무엇입니까?

답변

1

하나의 유스 케이스는 매개 변수로 인터페이스 유형과 방법에 대한 루프 호출이있을 때,이고, 방법은 단지 그 방법에 사용된다. 따라서 분리 된 클래스를 작성하는 대신 메소드 로컬 클래스를 정의 할 수 있습니다. (익명 클래스의 접근 방식은 작동 할 수 있지만 루프에있는 경우, 더 나은 클래스를 만들 수 있습니다.)

interface A{ public int getValue();} 
.... 
public void processValue(A a){} 
.... 
public void showResults(){ 
    class B implements A{ 
     int getValue(){ 
      return value; 
     } 
    } 
    for (int i=0;i<10;i++){ 
     processValue(new B()) 
    } 
} 
2

다른 스윙 구성 요소에 연결된 동일한 이벤트 수신기의 매개 변수가 약간 다른 버전을 필요로했지만 이름이 로컬 클래스보다 익명 클래스를 선호하는 경향이있는 경우를 제외하고 한 번 또는 두 번 사용했습니다.

이것의 간단한 예는 내가 키 - 값 쌍을 필요한 상황에서 사용했습니다 내 키를 기존의 클래스에 매핑되지 않은

public void attachListeners(final JLabel label) { 
    class ButtonListener implements ActionListener { 
    private String value; 
    public ButtonListener(String val) { value = val; } 
    public void actionPerformed(ActionEvent e) { 
     label.setText(value); 
    } 
    } 

    button1.addActionListener(new ButtonListener("value1")); 
    button2.addActionListener(new ButtonListener("value2")); 
} 
+1

코드 스 니펫을 제공 할 수 있습니까? 흥미 롭군! –

+0

감사합니다. 흥미로운 솔루션. –

0

될 것이다. 내 "키 클래스"를 내 방법 밖에 사용할 수 없도록 만들고 싶지 않았습니다.

예를 들어, 키는 EmployeeDate으로 구성 될 수 있으며 값은 그 날짜에 해당 직원의 예약 시간입니다. 이러한 상황에서, 그것은 다음과 같습니다

public void doExcitingCalculation() { 
    class EmployeeDateKey { 
     private Employee employee; 
     private Date date; 
     // Getters and setters ommited for brevity 
    } 

    Map<EmployeeDateKey, Double> bookedHours = new HashMap<>(); 
    Map<Empoyee, Map<Date, Double>> temp = fetchData(); 
    // This isn't a useful datastructure, so we remodel it 
    for (Map.Entry<Employee, Map<Date, Double>> entry : temp.entrySet()) { 
     for (Map.Entry<Date, Double> hours : entry.getValue().entrySet()) { 
      bookedHours.put(new EmployeeDateKey(entry.getKey(), hours.getKey()), hours.getValue()); 
     } 
    } 

    // process data 
} 
+1

그러나 EmployeeDateKey 클래스는 fetchData() 메소드에 표시되지 않습니다. 그렇습니까? 거대한 메소드 인 doExcitingCalculation()으로 이어질 fetchData() 메소드를 인라인하게 만듭니다. –

+0

이렇게 쓸모없는 것 같습니다. 어느 목록도 쓸모가 없거나 방법 설계에 결함이 있습니다. (실제 작업을하지 않습니다.) – Ankit

+0

좋은 캐치 @ Oleksandr.Bezhan, 나는 내가 의미하는 바를 더 잘 설명하기 위해 코드를 약간 썼습니다. – mthmulders

0

함께 관련 부품을 유지하여 코드의 가독성을 높일 수 있습니다 방법 로컬 클래스를 사용. 인위적인 예를 들어, 당신은 백그라운드에서 뭔가를 할 수있는 스레드를 만들 필요가있는 방법이 있다고 가정 :

라는 이름의 새를 만듭니다 방법 로컬 클래스없이

class Test { 
void f() { 
    // lots of stuff 
    new Thread(new Runnable() { 
     public void run() { 
      doSomethingBackgroundish(); 
     } 
    }).start(); 
    // lots more stuff 
    } 
} 

을, 당신도 할 것 백그라운드 테스트를 수행하는 클래스 내부 테스트 또는 별도의 소스 파일에 새 명명 된 클래스를 만들어 백그라운드 처리를 수행합니다. 두 옵션 모두 소스 트리의 어딘가에서 관련 처리를 이동하여 코드의 가독성을 떨어 뜨릴 수 있습니다 (어쩌면 같은 소스 파일에서, 어쩌면 다른 소스 파일에서). 메소드 로컬 클래스를 사용하면 처리 논리가 사용되는 곳에서 올바르게 유지됩니다.

이것은 모든 상황에 적용 할 수있는 것은 아니지만 많은 일반적인 상황에서 매우 유용 할 수 있습니다. 이러한 코드는 일반적으로 액션 메소드 호출을 한 곳에서 다른 곳으로 전달하는 매우 작은 클래스 인 GUI 액션 리스너에 사용됩니다.

관련 문제