public void foo() {
class Bar {
}
Bar b = new Bar();
}
메서드 로컬 클래스가 최상의 디자인 선택이 될 수있는 상황은 없습니다. 당신은 그것을 사용한 적이 있습니까? 어떤 경우에?메서드 로컬 클래스 란 무엇입니까?
public void foo() {
class Bar {
}
Bar b = new Bar();
}
메서드 로컬 클래스가 최상의 디자인 선택이 될 수있는 상황은 없습니다. 당신은 그것을 사용한 적이 있습니까? 어떤 경우에?메서드 로컬 클래스 란 무엇입니까?
하나의 유스 케이스는 매개 변수로 인터페이스 유형과 방법에 대한 루프 호출이있을 때,이고, 방법은 단지 그 방법에 사용된다. 따라서 분리 된 클래스를 작성하는 대신 메소드 로컬 클래스를 정의 할 수 있습니다. (익명 클래스의 접근 방식은 작동 할 수 있지만 루프에있는 경우, 더 나은 클래스를 만들 수 있습니다.)
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())
}
}
다른 스윙 구성 요소에 연결된 동일한 이벤트 수신기의 매개 변수가 약간 다른 버전을 필요로했지만 이름이 로컬 클래스보다 익명 클래스를 선호하는 경향이있는 경우를 제외하고 한 번 또는 두 번 사용했습니다.
이것의 간단한 예는 내가 키 - 값 쌍을 필요한 상황에서 사용했습니다 내 키를 기존의 클래스에 매핑되지 않은
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"));
}
될 것이다. 내 "키 클래스"를 내 방법 밖에 사용할 수 없도록 만들고 싶지 않았습니다.
예를 들어, 키는 Employee
및 Date
으로 구성 될 수 있으며 값은 그 날짜에 해당 직원의 예약 시간입니다. 이러한 상황에서, 그것은 다음과 같습니다
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
}
그러나 EmployeeDateKey 클래스는 fetchData() 메소드에 표시되지 않습니다. 그렇습니까? 거대한 메소드 인 doExcitingCalculation()으로 이어질 fetchData() 메소드를 인라인하게 만듭니다. –
이렇게 쓸모없는 것 같습니다. 어느 목록도 쓸모가 없거나 방법 설계에 결함이 있습니다. (실제 작업을하지 않습니다.) – Ankit
좋은 캐치 @ Oleksandr.Bezhan, 나는 내가 의미하는 바를 더 잘 설명하기 위해 코드를 약간 썼습니다. – mthmulders
함께 관련 부품을 유지하여 코드의 가독성을 높일 수 있습니다 방법 로컬 클래스를 사용. 인위적인 예를 들어, 당신은 백그라운드에서 뭔가를 할 수있는 스레드를 만들 필요가있는 방법이 있다고 가정 :
라는 이름의 새를 만듭니다 방법 로컬 클래스없이
class Test {
void f() {
// lots of stuff
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
// lots more stuff
}
}
을, 당신도 할 것 백그라운드 테스트를 수행하는 클래스 내부 테스트 또는 별도의 소스 파일에 새 명명 된 클래스를 만들어 백그라운드 처리를 수행합니다. 두 옵션 모두 소스 트리의 어딘가에서 관련 처리를 이동하여 코드의 가독성을 떨어 뜨릴 수 있습니다 (어쩌면 같은 소스 파일에서, 어쩌면 다른 소스 파일에서). 메소드 로컬 클래스를 사용하면 처리 논리가 사용되는 곳에서 올바르게 유지됩니다.
이것은 모든 상황에 적용 할 수있는 것은 아니지만 많은 일반적인 상황에서 매우 유용 할 수 있습니다. 이러한 코드는 일반적으로 액션 메소드 호출을 한 곳에서 다른 곳으로 전달하는 매우 작은 클래스 인 GUI 액션 리스너에 사용됩니다.
코드 스 니펫을 제공 할 수 있습니까? 흥미 롭군! –
감사합니다. 흥미로운 솔루션. –